Webpack4后包拆成webpack和webpack-cli两个包:
// 安装webpacknpm install --save-dev webpack webpack-cli
主要有以下这些一级配置:
module.exports = {mode: 'development', // 模式配置,webpack4.0新增entry: '', // 入口文件output: {}, // 出口文件module: {rules: [/*loader setting*/]}, // 配置modules,包括loaderplugins: [], // 对应的插件devServer: {}, // 开发服务器配置optimization: {}, // 最佳实践devtool: '',resolve: { alias: {}},}
1. mode
Webpack 4 引入了 mode 这个选项。这个选项的值可以是 development 或者 production。 设置了 mode 之后会把 process.env.NODE_ENV 也设置为 development 或者 production。然后在 production 模式下,会默认开启 UglifyJsPlugin 等一堆插件。
webpack4支持ES6的方式导入JSON文件,并且支持Tree-shaking
2. entry/output
3. mudule - rules - loader配置
webpack4中移除loaders配置,必须使用rules。rules 配置模块的读取和解析规则, 通常用来配置loader, 其类型是一个数组, 数组里每一项都描述了如何去处理部分文件。
配置一项rules大致通过以下方式:
- 条件匹配: 通过test、include、exclude三个配置来命中Loader要应用的规则文件。(三个配置都可以是正则,也支持数组)
- 应用规则: 对选中后的文件通过use配置项来应用loader,可以应用一个loader或者按照从后往前的顺序应用一组loader。同时还可以分别给loader传入参数。
- 重置顺序: 一组loader的执行顺序默认是从右到左执行,通过exforce选项可以让其中一个loader的执行顺序放到最前或者是最后。
```json
module: {
rules: [
] }{test: /\.m?js$/,exclude: /node_modules/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env']}}},{test: /\.scss$/,use: ['style-loader', 'css-loader', 'sass-loader'],exclude: path.resolve(__dirname, 'node_modules')}
常用loader:(待补充)- css- style-loader- css-loader- postcss-loader- sass-loader<a name="Uik4z"></a>## 4. optimization在Webpack4中引入,根据mode(production/development)的不同,配置项默认值不同,具体有以下:1. optimization.minimize: 是否自动压缩打包后的代码。mode = production时,为true。压缩默认使用uglifyjs-webpack-plugin插件,如果想要使用别的压缩插件,可以使用optimization.minimizer设置。1. optimization.splitChunks: 根据不同的策略来分割打包出来的bundle。配置基于[SplitChunksPlugin(opens new window)](https://webpack.js.org/plugins/split-chunks-plugin/),剔除了老的CommonsChunkPlugin(webpack4移除)。- optimization.splitChunks.chunks: async/all/initial3. 零配置- optimization.nodeEnv: 告诉webpack process.env.NODE_ENV的值,值来自于mode的取值。代替[webpack.DefinePlugin(opens new window)](https://webpack.js.org/plugins/define-plugin/)(webpack4移除)- optimization.namedModules: 代替webpack.NamedModulesPlugin(webpack4移除)- optimization.noEmitOnErrors: 代替webpack.NoEmitOnErrorsPlugin(webpack4移除)- optimization.concatenateModules: 代替webpack.optimize.ModuleConcatenationPlugin(webpack4移除)<a name="FBmPY"></a>## plugins- 常用插件1. HtmlWebpackPlugin 自动在html中加载打包后的js文件1. DLLPlugin/DllReferencePlugin 提高打包速度- DLLPlugin:创建一个只有dll的bundle- DllReferencePlugin: 打包生成的dll文件引用到需要的预编译依赖上来3. happyPack 多进程打包,加快打包速度。3. webpack.DefinePlugin webpack4设置mode会自动使用3. uglifyjs-webpack-plugin webpack4 mode = production默认使用- 废弃插件1. CommonsChunkPlugin 拆分依赖包,生成单独文件,使得文件大小减小。在webpack4被废弃,替代optimization.splitChunks1. ExtractTextWebpackPlugin 拆分css样式的插件(webapck4已废弃)。由于webpack4以后对css模块支持的逐步完善和commonchunk插件的移除,在处理css文件提取的计算方式上也做了些调整,之前我们首选使用的extract-text-webpack-plugin也完成了其历史使命,将让位于[mini-css-extract-plugin(opens new window)](https://github.com/webpack-contrib/mini-css-extract-plugin)。<a name="WcKoi"></a>## <br />devServer详见[Webpack4 devServer配置详解](https://lq782655835.github.io/blogs/project/webapck4-2.devServer.html)<br />举个完整例子:```jsonconst path = require('path');const webpack = require('webpack');// 插件都是一个类,所以我们命名的时候尽量用大写开头const HtmlWebpackPlugin = require('html-webpack-plugin'); //打包htmlconst MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 提取出来cssconst UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // 压缩打包后的jsconst HappyPack = require('happypack'); // 多线程构建const happyThreadPool = HappyPack.ThreadPool({ size: 5 }); // 构造出共享进程池,进程池中包含5个子进程const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')// 最大化压缩cssconsole.log('process.env.NODE_ENV------->', process.env.NODE_ENV)// 解决css 分离后图片引入路径不正确问题if (process.env.type == 'build') { // 判断package.json里面是build还是dev命令// 开发var website ={publicPath:"/"}} else {// 生产var website ={publicPath:"/"}}module.exports = {// devtool:'eval-source-map',mode: 'development', // 模式配置entry: {main: './src/index.js',},output: {filename: 'bundle.[chunkhash:6].js',path: path.resolve(__dirname, 'dist'),publicPath: website.publicPath, // 解决css 分离后图片引入路径不正确问题},module: {rules: [{test: /\.css/,exclude: /node_modules/,use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader'],},{test: /\.less$/,exclude: /node_modules/,use: ['style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'],},{test: /\.(png|jpe?g|gif|svg)$/,use: [{loader: 'url-loader',options: {limit: 10000,name: '[name]_[hash:7].[ext]',outputPath:'static/images/'}}]},{test: /\.(htm|html)$/,use: 'html-withimg-loader'},// babel 解析es7 es6 jsx{test:/\.(jsx|js)$/,include: [path.resolve(__dirname, 'src'),],use:['babel-loader'],/*如果开启多线程进行构建use:['happypack/loader?id=js'],loader这样写 匹配下面注释的插件*/exclude:/node_modules/},]},plugins: [// 打包htmlnew HtmlWebpackPlugin({template: './src/index.html',hash: true,minify: {minifyCSS: true,minifyJS: true,removeAttributeQuotes: true},}),new MiniCssExtractPlugin({filename: "static/css/[name].[chunkhash:8].css",chunkFilename: "[id].css"}),new UglifyJsPlugin({parallel: true,}),new webpack.DefinePlugin({NODE_ENV: JSON.stringify('DEV')}),// 多线程构建 匹配上面的loader// new HappyPack({// id: 'js',// //threads: 4,// loaders: ['babel-loader'],// threadPool: happyThreadPool, // 使用共享进程池中的子进程去处理任务// }),],// 提取公共代码optimization: {minimizer: [// 自定义js优化配置,将会覆盖默认配置 最大化压缩成jsnew UglifyJsPlugin({exclude: /\.min\.js$/, // 过滤掉以".min.js"结尾的文件,我们认为这个后缀本身就是已经压缩好的代码,没必要进行二次压缩cache: true,parallel: true, // 开启并行压缩,充分利用cpusourceMap: false,extractComments: false, // 移除注释uglifyOptions: {compress: {unused: true,warnings: false,drop_debugger: true},output: {comments: false}}}),// 用于优化css文件 最大化压缩成css 并且去掉注释掉的cssnew OptimizeCssAssetsPlugin({assetNameRegExp: /\.css$/g,cssProcessorOptions: {safe: true,autoprefixer: { disable: true },mergeLonghand: false,discardComments: {removeAll: true // 移除注释}},canPrint: true})],splitChunks: {cacheGroups: {vendor: { // 抽离第三方插件test: /node_modules/, // 指定是node_modules下的第三方包chunks: 'initial',name: 'vendor', // 打包后的文件名,任意命名// 设置优先级,防止和自定义的公共代码提取时被覆盖,不进行打包priority: 10},// utils: { // 抽离自己写的公共代码,utils这个名字可以随意起 (css/js公用的都会单独抽离出来生成一个单独的文件)// chunks: 'initial',// name: 'utils', // 任意命名// minSize: 0 // 只要超出0字节就生成一个新包// }}}},devServer: {historyApiFallback: true,inline: true},// externals: {// jquery: "jQuery",// },resolve: {// alias 别名配置,它能够将导入语句里的关键字替换成你需要的路径alias: {// 比如我们就可以直接写 import Nav from '@/Nav''@': './app/component'},// 省略后缀extensions: ['.js', '.jsx', '.less', '.json', '.css'],},performance: {hints: false // 选项可以控制 webpack 如何通知「资源(asset)和入口起点超过指定文件限制」}}
