修改方式
Vue CLI 可通过两种方式修改 webpack 配置。分别为:configureWebpack 和 chainWebpack。
需要注意的是:configureWebpack 会直接覆盖同名配置(有可能会覆盖 vue cli 默认配置 或 chainWebpack 配置);而 chainWebpack 则是通过修改默认配置来实现。所以一般推荐优先使用 chainWebpack 来修改配置。
可提供一个 configureWebpack 对象,也可以是一个方法。
- 对象:该对象将被 webpack-merge 合并到最终的 webpack 配置中,可以直接修改或覆盖 Webpack 的配置。
- 方法:可基于环境修改配置。函数会在环境变量被设置之后回调,形参会收到已经解析好的配置。在函数内,你可以直接修改解析好的配置,或者返回一个将会被合并的对象。
1 2 3 4 5 6
| module.exports = { configureWebpack: { }, };
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| module.exports = { configureWebpack: (config) => { if (process.env.NODE_ENV === "production") { } else { } return { }; }, };
|
chainWebpack 推荐
Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的。webpack-chain 是一个可以链式配置 webpack 的库。所以可以使用 webpack-chain API 链式修改配置
创建 vue.config.js
1 2 3 4 5 6 7 8 9 10
| module.exports = { chainWebpack: (config) => { if (process.env.NODE_ENV === "production") { } else { } }, };
|
常用的配置
scss 自动导入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module.exports = { css: { loaderOptions: { sass: { sassOptions: { outputStyle: "expanded" }, additionalData(content, loaderContext) { const { resourcePath, rootContext } = loaderContext; const relativePath = relative(rootContext, resourcePath); if (relativePath.replace(/\\/g, "/") !== "src/assets/styles/variables.scss") return '@import "~@/assets/styles/variables.scss";' + content; return content; }, }, }, }, };
|
别名
1 2 3 4 5 6 7 8 9 10 11
| module.exports = { configureWebpack: { resolve: { alias: { "@": path.resolve(__dirname, "src/"), }, }, }, };
|
打包去掉 console
https://webpack.js.org/configuration/optimization/#optimizationminimizer
https://github.com/terser/terser
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module.exports = { chainWebpack: (config) => { if (process.env.NODE_ENV === "production") { config.optimization.minimizer("terser").tap((args) => { args[0].terserOptions.compress.drop_debugger = true; args[0].terserOptions.compress.drop_console = true; return args; }); } }, };
|
SVG 自动引入
地址:https://www.npmjs.com/package/svg-sprite-loader
1
| npm i -D svg-sprite-loader
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| module.exports = { chainWebpack: (config) => { const svgRule = config.module.rule("svg"); svgRule.uses.clear(); svgRule .test(/\.svg$/) .use("svg-sprite-loader") .loader("svg-sprite-loader"); }, };
|
gzip 压缩
地址:https://www.npmjs.com/package/compression-webpack-plugin
1
| npm i -D compression-webpack-plugin
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const CompressionWebpackPlugin = require("compression-webpack-plugin");
module.exports = { chainWebpack: (config) => { if (process.env.NODE_ENV === "production") { config.plugin("compression").use(CompressionWebpackPlugin, [ { filename: "[path][base].gz[query]", algorithm: "gzip", test: new RegExp("\\.(" + ["html", "js", "css", "svg"].join("|") + ")$"), threshold: 8192, minRatio: 0.8, }, ]); } }, };
|
分块优化
地址: https://webpack.js.org/configuration/optimization/#optimizationsplitchunks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| module.exports = { chainWebpack: (config) => { if (process.env.NODE_ENV === "production") { config.optimization.splitChunks({ automaticNameDelimiter: "-", minSize: 20000, maxSize: 0, minChunks: 1, chunks: "all", cacheGroups: { vue: { name: "vue", test: /[\\/]node_modules[\\/](vue(.*)|core-js)[\\/]/, chunks: "initial", priority: 20, }, elementUI: { name: "element-ui", test: /[\\/]node_modules[\\/]element-ui(.*)[\\/]/, priority: 30, }, echarts: { name: "echarts", test: /[\\/]node_modules[\\/](echarts|zrender|tslib)[\\/]/, priority: 50, }, extra: { name: "roc-extra", test: resolve("src/extra"), priority: 40, }, }, }); } }, };
|
打包排除 js 库使用 CDN 引入
比如排除 echarts 包
1 2 3 4 5 6 7 8
| module.exports = { chainWebpack: (config) => { config.externals({ echarts: "echarts", }); }, };
|
排除后在 index.html
中引入 CDN 。在项目中使用全局的变量 echarts
即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title>Vue App</title> </head>
<body> <noscript> <strong>We're sorry but vue app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <script src="//unpkg.com/echarts@4.9.0/dist/echarts.js"></script> </body> </html>
|
打包模块可视化分析
地址:https://www.npmjs.com/package/webpack-bundle-analyzer
1
| npm i -D webpack-bundle-analyzer
|
1 2 3 4 5 6
| module.exports = { chainWebpack: (config) => { config.plugin("webpack-bundle-analyzer").use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin); }, };
|