场景: 项目打包优化阶段,为了解决打包成功后,单文件体积过大的问题 ,可以通过 webpack 的 externals 节点,来配置并加载外部的 CDN 资源
原因:报错的原因就是重新定义了$router,因为在项目中安装了vue-router的依赖并且用Vue.use()使用了vue-router,还在index.html页面引入了vue-router.js文件
此处介绍两种解决办法
报错如下
第一种办法(比较简洁的):
在public/index.html文件中加入if判断
<% if(htmlWebpackPlugin.options.isProd){ %> <link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.8/lib/theme-chalk/index.css"> <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.core.css"> <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.snow.css"> <link rel="stylesheet" href="https://unpkg.com/quill@1.3.7/dist/quill.bubble.css"> <script src="https://unpkg.com/echarts@5.3.2/dist/echarts.min.js"></script> <script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script> <script src="https://unpkg.com/vue-router@3.2.0/dist/vue-router.js"></script> <script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script> <script src="https://unpkg.com/axios@1.1.3/dist/axios.min.js"></script> <script src="https://unpkg.com/dayjs@1.11.7/dayjs.min.js"></script> <script src="https://unpkg.com/element-ui@2.15.10/lib/index.js"></script> <script src="https://unpkg.com/quill@1.3.7/dist/quill.js"></script> <script src="https://unpkg.com/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script> <script src="https://unpkg.com/vuex-persistedstate@3.2.1/dist/vuex-persistedstate.umd.js"></script> <% } %>
这样就可以正常运行了
第二种、在vue.config.js中定义只有在生产环境中引入响应的CDN地址 :
1、首先需要定义一个CDN对象,用来配置CDN链接
let CDN = { css: [], js: [] }
2、在判断为生产环境中,给CDN赋值
// 判断是否为生产环境 const isProduction = process.env.NODE_ENV === 'production' // 如果是生产环境,需要执行以下逻辑 if (isProduction) { externals = { /** * externals 对象属性解析: * '包名':'在项目中引入的名字' * 以element-ui 举例:我在main.js里是以 import ELEMENT from 'element-ui' * Vue.use(ELEMENT) * 这样引入的,所以我的 externals 的属性值应该是 ELEMENT,一定要去main.js设置 */ echarts: 'echarts', vue: 'vue', 'vue-router': 'VueRouter', vuex: 'vuex', axios: 'axios', days: 'days', 'element-ui': 'ELEMENT', // 因为在cdn源码里,ELEMENT是大写,所以在这里需要大写,并且把项目中(elementUi/index.js)引入这个插件的地方也改成大写 'vue-quill-editor': 'VueQuillEditor', 'vuex-persistedstate': 'createPersistedState' } CDN = { css: [// element-ui css样式表 'https://unpkg.com/element-ui@2.15.8/lib/theme-chalk/index.css', 'https://unpkg.com/quill@1.3.7/dist/quill.core.css', 'https://unpkg.com/quill@1.3.7/dist/quill.snow.css', 'https://unpkg.com/quill@1.3.7/dist/quill.bubble.css' ], js: [ 'https://unpkg.com/echarts@5.3.2/dist/echarts.min.js', 'https://unpkg.com/vue@2.6.11/dist/vue.js', 'https://unpkg.com/vue-router@3.2.0/dist/vue-router.js', 'https://unpkg.com/vuex@3.6.2/dist/vuex.js', 'https://unpkg.com/axios@1.1.3/dist/axios.min.js', 'https://unpkg.com/dayjs@1.11.7/dayjs.min.js', 'https://unpkg.com/element-ui@2.15.10/lib/index.js', 'https://unpkg.com/quill@1.3.7/dist/quill.js', 'https://unpkg.com/vue-quill-editor@3.0.6/dist/vue-quill-editor.js', 'https://unpkg.com/vuex-persistedstate@3.2.1/dist/vuex-persistedstate.umd.js' ] } }
3、将配置的css/js地址注入到html页面中
module.exports = defineConfig({ chainWebpack (config) { // 注入cdn变量(打包时会执行) config.plugin('html').tap(args => { // 参数对象添加属性叫cdn,值就是上面的CDN对象 args[0].cdn = CDN// 配置CDN给插件 return args }) })
4、在public/index.html页面中设置对应的导入信息
导入样式
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %> <link rel="stylesheet" href="<%=css%>" as="style"> <% } %>
导入JS
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %> <script src="<%=js%>"></script> <% } %>
到这就结束了,打包后的体积会很小,达到了只有在生产环境中,才会在public/index.html页面中导入CDN地址,开发环境还是从node_modules中引入