概述
工程化的项目中,一般都是模块化的形式引入对应的依赖包,并不会将其注入到全局变量中,在微前端中,基座项目(主应用)和子应用直接肯定存在依赖的重叠,因此公共的三方包需要提取共用,而这些公共模块,放到主应用中,然后子应用打包排除对应的公共包即可,这样可以节省大量的资源。
实现方式
1、cdn
把对应公共资源单独部署到cdn上,然后主应用中引入加载,主应用和子应用都通过构建工具进行排包,示例如下: 以vue项目为例,公共资源位:vue axios vue-router vuex等
修改主应用和子应用 vue.config.js
js
module.exports = {
configureWebpack: {
externals: {
// 键是包名,值是全局变量名
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_'
}
}
}
主应用的index.html中cdn引入
将公共的资源单独部署,然后cdn方式引入 index.html示例如下:
js
<head>
<!-- Vue 相关 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue-router.min.js"></script>
<!-- 其他库 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
</head>
2、expose-loader
这种方式更为内聚,不用单独cdn引入,直接将主应用的公共模块包注入到全局中,然后子应用排包使用即可。
expose-loader是什么?
expose-loader
允许暴露一个模块(整体或者部分)给全局对象(self
、window
和 global
)。
实现
注意:expose-loader版本的不同,用法也会有差异,这里有坑,可以使用的时候查阅文档
js
// eslint-disable-next-line @typescript-eslint/no-var-requires
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
/* eslint-disable @typescript-eslint/no-var-requires */
const prod = process.env.NODE_ENV === 'production';
module.exports = {
configureWebpack: (config) => {
//s----重点
config.module.rules.push({
test: require.resolve('vue'),
use: [{
loader: 'expose-loader',
options: {
exposes: 'MyVue'//暴露到window的属性名
}
}]
})
config.module.rules.push({
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: {
exposes: 'JQuery'
}
}]
})
config.module.rules.push({
test: require.resolve('@qbee/fe-vue-contacts'),
use: [{
loader: 'expose-loader',
options: {
exposes: 'FeVueContacts'
}
}]
})
}
},
parallel: require('os').cpus().length > 1,
devServer: {
hot: true,
open: process.platform === 'darwin',
host: '0.0.0.0',
port: 2459,
https: false,
hotOnly: false,
proxy: prod
? null
: {
'/': {
target: process.env.APP_PROXY_URL, // 服务器地址
changeOrigin: true, // 是否跨域,
ws: false
}
}
}
};
总结
对应大平台,集群项目来说,公共资源抽离出去可以减少很大一部分资源请求的消耗时间,提升用户体验。