webpack 4迁移指南
webpack 4 出来也已经一年了,公司的老项目用的还是webpack3,也是时候该升级一波了。说实话webpack4还是有几点挺吸引我的,估计也是感受到了parcel的压力,4这个版本内置了很多默认配置。
迁移的坑
- CommonsChunkPlugin 废除, webpack 4内置了optimization.splitChunks 和 runtimeChunk 进行代码拆分
- ExtractTextPlugin 不支持webpack4,官方推荐了一个MiniCssExtractPlugin来拆分chunk中的css代码
- vue-loader 的升级,vue-loader 版本由14 升级到了15, 之前的配置也改变了具体参考从 v14 迁移
基础配置
const package = require('../package.json'); const path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const utils = require('./utils'); function resolve (dir) { return path.join(__dirname, dir); } module.exports = { entry: { main: '@/main', 'vender-exten': '@/vendors/vendors.exten.js' }, output: { path: path.resolve(__dirname, '../dist/' + package.version) // 输出文件的绝对路径 }, module: { rules: [ { test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', exclude: /node_modules/, options: { emitError: true, emitWarning: false, failOnError: true } }, { test: /\.vue$/, exclude: /node_modules/, loader: 'vue-loader' }, { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.js[x]?$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, use: { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, use: { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } } ] }, plugins: [ new VueLoaderPlugin(), ], resolve: { extensions: ['.js', '.vue'], alias: { '@': resolve('../src') } }, externals: { AMap: 'AMap', vue: 'Vue', iview: 'iview', 'vue-router': 'VueRouter', vuex: 'Vuex' } };
如上,实现了对vue,jsx, js, 和资源文件对处理和转译
开发环境配置
const HtmlWebpackPlugin = require("html-webpack-plugin"); const merge = require("webpack-merge"); const webpackBaseConfig = require("./webpack.base.config.js"); const config = require("./config"); const webpack = require("webpack"); module.exports = merge(webpackBaseConfig, { mode: 'development', devtool: '#source-map', output: { publicPath: '/dist/', filename: '[name].js', chunkFilename: '[name].chunk.js' }, plugins: [ new HtmlWebpackPlugin({ title: 'admin management', filename: '../index.html', inject: false }), ], module: { rules: [ { test: /\.css$/, use: ['vue-style-loader', 'css-loader', 'postcss-loader'] }, { test: /\.less$/, use: [ 'vue-style-loader', 'css-loader', 'postcss-loader', 'less-loader' ] } ] }, //设置跨域代理 devServer: { public: 'local.xxxx.net:9000', port: 9000, proxy: { '/login': { target: config.devApi.passport, pathRewrite: { '^/login': '/login' }, changeOrigin: true }, '/v3': { target: config.devApi.sass, pathRewrite: { '^/v3': '/v3' }, changeOrigin: true } } } });
如上,配置了开发环境的配置,注意webpack4多了一个mode,mode有三个选项可以选择:development, production, 和none,
可以看官方的这个图,webpack会根据mode自动开启内置插件
生产环境配置
const HtmlWebpackPlugin = require('html-webpack-plugin') const TerserJSPlugin = require('terser-webpack-plugin'); const webpack = require('webpack') const CopyWebpackPlugin = require('copy-webpack-plugin') const cleanWebpackPlugin = require('clean-webpack-plugin') const merge = require('webpack-merge') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const webpackBaseConfig = require('./webpack.base.config.js') const path = require('path') const package = require('../package.json') module.exports = merge(webpackBaseConfig, { mode: 'production', output: { publicPath: '/' + package.version + '/', // 所有引入的文件资源都加上publicPath路径 filename: '[name].[contenthash].js', // 输出 bundle 的名称, 入口(non-entry) chunkFilename: '[name].[contenthash].chunk.js' // 非入口(non-entry) chunk 文件的名称 }, optimization: { splitChunks: { cacheGroups: { // 缓存组 commons: { test: /[\\/]node_modules[\\/]/, // 只抽取引入的node_modules文件 name: 'vender-exten', // 要缓存的 分隔出来的 chunk 名称 chunks: 'all' // 对所有的chunk都进行缓存 } } }, runtimeChunk: { name: 'runtime' }, minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})] }, module: { rules: [ { test: /\.css?$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ] }, { test: /\.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader' ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', chunkFilename: '[name].[contenthash].css' }), new cleanWebpackPlugin(['dist/*'], { root: path.resolve(__dirname, '../') }), new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: '../static', ignore: ['.*'] } ]), new HtmlWebpackPlugin({ title: 'admin', favicon: './static/favicon.ico', filename: '../index.html', template: '!!ejs-loader!./src/template/index.ejs', inject: false }) ] });
生产环境
1.使用MiniCssExtractPlugin,来拆分css,我可以可以options里面有两个值filename和chunkFilename, filename指的是entry中key生成的css名称, chunkFilename是webpack中每个chunk拆分生成css的名称。
2.使用OptimizeCSSAssetsPlugin 对打包之后的css文件进行压缩,
3.使用splitChunks对公共代码进行抽取缓存,我们先来看一下这个插件的默认配置
module.exports = { optimization: { splitChunks: { chunks: 'async', "initial" | "all"(推荐) | "async" (默认就是async) minSize: 30000, 最小尺寸,30000 maxSize: 0, 最小尺寸 minChunks: 1, 最小 chunk ,默认1 maxAsyncRequests: 5, // 最大异步请求数, 默认5 maxInitialRequests: 3, // 最大初始化请求书,默认3 automaticNameDelimiter: '~', // 打包分隔符 name: true, cacheGroups: { // 重点,缓存配置 vendors: { test: /[\\/]node_modules[\\/]/, // 只缓存node_modules里面的模块 priority: -10 // // 缓存组优先级,可能有多个 }, } } } };
看下我的配置
splitChunks: { cacheGroups: { // 缓存组 commons: { test: /[\\/]node_modules[\\/]/, // 只抽取引入的node_modules文件 name: 'vender-exten', // 要缓存的 分隔出来的 chunk 名称 chunks: 'all' // 对所有的chunk都进行缓存 } } }
通过webpack-bundle-analyzer生成的可视化图标分析查看项目中的多个chunk共同引入的lib包
抽离5个依赖的lib包,进行缓存<br/><br/>
4.使用optimization.runtimeChunk,去缓存生成chunk过程中生成的webpack公用代码<br/><br/>
5.使用TerserJSPlugin对js进行压缩
相关推荐
不知道该写啥QAQ 2020-11-12
webfullStack 2020-11-09
Yvettre 2020-09-15
想做大牛的蜗牛 2020-10-30
gloria0 2020-10-26
gaojie0 2020-09-11
SelinaChan 2020-08-14
不知道该写啥QAQ 2020-08-09
gloria0 2020-08-09
不知道该写啥QAQ 2020-08-02
hline 2020-07-29
SelinaChan 2020-07-28
wangdianyong 2020-07-23
webpackvuees 2020-07-23
yqoxygen 2020-07-20
不知道该写啥QAQ 2020-07-18
waterv 2020-07-18
81463166 2020-07-17