vue脚手架打包排除第三方依赖(项目瘦身)- externals
vue脚手架打包排除第三方依赖(项目瘦身)- externals方法首先在 vue.config.js 中加入如下内容module.exports = { // 主体......configureWebpack: config => {config.plugins.forEach((val) => {// 这里加这个判断主要目的是获取到脚手架中的插件 HtmlWebpackPlugin
vue脚手架打包排除第三方依赖(项目瘦身)- externals
方法
首先在 vue.config.js 中加入如下内容
module.exports = { // 主体
......
configureWebpack: config => {
config.plugins.forEach((val) => {
// 这里加这个判断主要目的是获取到脚手架中的插件 HtmlWebpackPlugin
if (JSON.stringify(val).indexOf('"filename":"index.html"') !== -1) {
if (process.env.NODE_ENV === 'production') {
console.log('生产环境');
val.options.cdnConfig = {
js: resources.js,
headerJs: resources.headerJs,
css: resources.css
};
}
val.options.env = process.env.NODE_ENV
}
if (process.env.NODE_ENV === 'production') {
config.externals = resources.externals
}
})
}
}
val.options.env
这个配置十分关键,用于在模板中判断当前环境,如果是开发环境,则不能使用 CDN 引用,否则会报错,在开发环境直接使用平时写法即可,在生产环境才会在模板中写入CDN链接。
下面贴出 vue脚手架所含的插件 HtmlWebpackPlugin 所拥有的值
HtmlWebpackPlugin {
options: {
template: 'E:\\Project\\LIMS-laboratory-management\\bamboo-frame-front-admin\\public\\index.html',
templateParameters: [Function: templateParameters],
filename: 'index.html',
hash: false,
inject: true,
compile: true,
favicon: false,
minify: false,
cache: true,
showErrors: true,
chunks: 'all',
excludeChunks: [],
chunksSortMode: 'auto',
meta: {},
title: 'bamboo-front-admin',
xhtml: false
}
}
我只要使用了这个对象中的 filename: 'index.html',
进行判断当前是不是插件 HtmlWebpackPlugin
,如果是的话,加入自定义配置对象 cdnConfig
主要操作是将需要DNS引入的资源声明成数组然后使模板index.html编译出来引用,同时打包时排除到需要第三方引用的资源
从第一步可以看到有一个变量 resources
,其内容如下:
const enums = require('../application/resources/enums');
module.exports = [
enums.vue
];
const externals = {};
const js = [];
const headerJs = [];
const css = [];
res.forEach(item => {
if (externals[item.key] === undefined) {
externals[item.key] = item.constant
if (item.js) {
js.push(...item.js);
}
if (item.css) {
css.push(...item.css);
}
if (item.headerJs) {
css.push(...item.headerJs);
}
}
});
module.exports = {
externals,
js,
headerJs,
css
};
这里我模拟了一个枚举,用来统一管理第三方资源,内容如下
module.exports = {
vue: {
key: 'vue',
constant: 'Vue',
js: [
'/cdn/vue@2.6.12/vue.js'
],
},
}
修改模板:
<!DOCTYPE html>
<html lang="">
<head>
......
<% if (htmlWebpackPlugin.options.env == 'production') { htmlWebpackPlugin.options.cdnConfig.css.forEach(function(item){ if(item){ %>
<link href="<%= item %>" rel="stylesheet" />
<% }})} %>
</head>
<body>
......
<div id="app"></div>
<% if (htmlWebpackPlugin.options.env == 'production') { htmlWebpackPlugin.options.cdnConfig.js.forEach(function(item){ if(item){ %>
<script type="text/javascript" src="<%= item %>"></script>
<% }}) } %>
<!-- built files will be auto injected -->
</body>
</html>
模板从 插件配置 htmlWebpackPlugin.options.cdnConfig 中读取并渲染,最终构建效果如下
代码到这里就全部贴完了,下面对这些配置进行一些简单说明
externals
的说明直接查看官方文档:https://webpack.docschina.org/configuration/externals/,这里不进行说明
需要注意的是,externals
是一个 Object
,其结构类似于一个 map
,由 key
和 value
构成
其中 key 是第三方资源的包名称:即import
时 from
的名称,以 ElementUI
为例,key 就是下面的 element-ui
import ElementUI from 'element-ui';
其中 value 的值是 当资源以CDN方式引入到页面中后,资源注册到 window
对象上的名称,以 ElementUI
为例,value就是 ELEMENT
这个值必须是可以在window对象上能获取到的对象名称,否则打包后访问即使CND正确也会报错
踩坑
百度有人说 externals 键值对中的值是 import 时写的那个名字,这是不对的,这种说法坑死人,且无法排查问题
一旦写错,报错信息如下:
点进去之后它是这么个东西:
它无法从window对象中获取到 ElementUI 对象,因为 ElementUI 在 window 对象上绑定时并不是使用的这个名字。
更多推荐
所有评论(0)