简介
经历过vue-cli2的时代,优化过项目打包配置,趁最近面试整理一下。分为默认配置介绍和自定义配置方法。
webpack可靠文档地址:https://webpack.docschina.org/configuration/optimization/
vue-cli官方文档:https://cli.vuejs.org/zh/config/
一、默认配置
1、vue-cli4
电脑上当前vue-cli是4.5.7版本,查看项目webpack版本为4.46.0
vue-cli对webpack配置进行了抽象,不能直接查看,但是vue-cli-service暴露了inspect命令用于查看webpack配置
命令:vue inspect > webpconfig.js
生成一个webpconfig.js文件(默认配置共1300+行,这里删除了一些细节,保留了整体结构,具体可通过以上命令自行查看)
这里对选项加了注释:
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| { mode: 'development', context: '/Users/lishichang/Desktop/未命名文件夹/test', node: {}, output: {}, resolve: { alias: { '@': '/Users/lishichang/Desktop/未命名文件夹/test/src', vue$: 'vue/dist/vue.runtime.esm.js' }, extensions: [], modules: [ 'node_modules', '/Users/lishichang/Desktop/未命名文件夹/test/node_modules', '/Users/lishichang/Desktop/未命名文件夹/test/node_modules/@vue/cli-service/node_modules' ], plugins: [ {} ] }, resolveLoader: {}, module: { noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/, rules: [ { test: /\.vue$/, use: [ { loader: '/Users/lishichang/Desktop/未命名文件夹/test/node_modules/cache-loader/dist/cjs.js', options: { cacheDirectory: '/Users/lishichang/Desktop/未命名文件夹/test/node_modules/.cache/vue-loader', cacheIdentifier: '9d856fc8' } }, { loader: '/Users/lishichang/Desktop/未命名文件夹/test/node_modules/vue-loader/lib/index.js', options: { compilerOptions: { whitespace: 'condense' }, cacheDirectory: '/Users/lishichang/Desktop/未命名文件夹/test/node_modules/.cache/vue-loader', cacheIdentifier: '9d856fc8' } } ] } ] }, optimization: { splitChunks: { cacheGroups: { vendors: { name: 'chunk-vendors', test: /[\\/]node_modules[\\/]/, priority: -10, chunks: 'initial' }, common: { name: 'chunk-common', minChunks: 2, priority: -20, chunks: 'initial', reuseExistingChunk: true } } }, minimizer: [ new TerserPlugin( { terserOptions: { compress: {}, mangle: { safari10: true } }, sourceMap: true, cache: true, parallel: true, extractComments: false } ) ] }, plugins: [ new VueLoaderPlugin(), new DefinePlugin( { 'process.env': { NODE_ENV: '"development"', BASE_URL: '"/"' } } ), new CaseSensitivePathsPlugin(), new FriendlyErrorsWebpackPlugin(), new HtmlWebpackPlugin(), new PreloadPlugin(), new PreloadPlugin(), new CopyPlugin() ], entry: { app: [ './src/main.js' ] } }
|
2、vue-cli2
回看了一下2018年优化过的项目,采用vue-cli2搭建,webpack版本为3.12.0。
Vue-cli2搭建项目部分目录结构如下,webpack配置文件在build文件夹中

webpack.base.config.js
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| 'use strict' const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') function resolve(dir) { return path.join(__dirname, '..', dir) } module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, externals: { 'vue': 'Vue', }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'vendor': path.resolve(__dirname, '../src/vendor') } }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.less$/, loader: "style-loader!css-loader!less-loader", }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')], exclude: /node_modules/, } ... ] }, node: {} }
|
webpack.dev.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const devWebpackConfig = merge(baseWebpackConfig, { devServer: { proxyTable: { '/api': { target: 'http://***/admin', changeOrigin: true, pathRewrite: { '^/api': '' } }, }, } } })
|
webpack.prod.config.js
vue-cli2默认配置了CommonsChunkPlugin插件
webpack4.0后提供一个新的分包插件SplitChunksPlugin,开箱即用,移除了CommonsChunkPlugin
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 38 39 40
| 'use strict' const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') }
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks (module) { return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }) new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } })
|
二、自定义配置和优化
针对vue-cli4以上版本,vue.config.js,配置文档:https://cli.vuejs.org/zh/config/
1.cache-loader,缓存,放在其他loader前,尤其开销大的loader适合使用。vue-cli4默认使用。
2.thread-loader,
使用时,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
在 worker 池中运行的 loader 是受到限制的。例如:
- 这些 loader 不能生成新的文件。
- 这些 loader 不能使用自定义的 loader API(也就是说,不能通过插件来自定义)。
- 这些 loader 无法获取 webpack 的配置。
- 请仅在耗时的操作中使用此 loader,如babel-loader
3.devtool,对sourcemap的使用。cheap-module-eval-source-map性能更好,生产环境就把source-map关掉。
4.开发环境不要启用压缩代码这些。生成环境如无必要,不用压缩代码、混淆代码,这些插件影响构建性能。
5.CommonsChunksPlugin,提取出manifest,这样如果没有更改的模块,不会重新生成hash值。vue-cli2默认使用,vue-cli4移除,增加了SplitChunksPlugin,默认使用SplitChunksPlugin
6.loader用在必要的地方,test选项中加include字段来规定使用loader的范围,避免查找和转换不必要的地方
7.常用打包分析插件分析如bundleAnalyzerReport,vendor包太大,用externals去除不必要的第三方包参与打包,改为使用cdn引入。
8.少写extensions,把扩展名写上,减少程序搜索文件次数。
9.更新版本,vue,vue-cli,webpack等,新版本都会有一些性能的优化。
10.优化代码,写合理的逻辑。
// 新的脚手架都默认做了很多优化,一般情况下已经无需大动。