webpack4比较热门的两大特性,零配置和速度快(号称提速上限98%)javascript
通常状况下,webpack4相比于低版本,production场景下第三方依赖打包速度 和 development场景下本地服务首次启动速度 都获得显著提高css
零配置
经过mode指定当前场景为开发模式仍是生产模式,自动设置好当前场景的默认配置,用户便可立刻使用,不须要多余的配置html
打包速度快
打包速度之因此能获得显著提高,多亏了Optimization这个新增的选项,下文会说到java
1.入口(entry)node
是应用程序,或者说一个页面的起点入口,若是传递一个数组,那么数组的每一项都会执行
每一个html页面都有一个入口起点
单页面应用(SPA):一个入口
多页面应用(MPA :多个入口webpack
entry: { home: "./home.js", about: "./about.js", contact: "./contact.js" }
若是entry的值是一个字符串,那么打包以后的chunk名即为默认的main
若是entry的值是一个对象,则每一个key都会是chunk的名字,每一个key对应的值都是入口起点git
2.输出(output)github
output的值必须为一个对象,至少包含下面两个属性web
filename: webpack打包以后输出文件的路径
path: 决定了每一个输出的bundle的名称(即打包后的文件名字),这些bundle将写入到output.path指定的目录下npm
例如:
单入口
output: { path: '/dist', filename: 'bundle.js' }
这个配置将会在根目录的dist文件夹下输出打包后的bundle.js,这是单页面应用的配置
多入口
output: { path: '/dist', filename: 'js/[name].js' }
即在dist目录下的js文件夹中输出一系列的bundle
一个比较难理解的配置:ouput.publicPath
配置html中引用的静态资源的目录,在多数状况下,此选项的值为'/'
publicPath并不会对webpack打包文件后存放的目录有所影响,是对生成的html中应用的静态资源,好比图片,css和js文件的引用路径作对应的补足
对于按需加载或者加载外部资源来讲,这个选项的值尤其重要,若是设置错误,加载资源的时候会返回404
3.模块加载器(loader)
loaders能够说是各类模块的转换器,能够用来预处理文件,解析和打包除javascript以外的任何静态资源
loader要下载才能配置使用,好比:
npm install --save-dev css-loader
npm install --save-dev ts-loader
而后在webpack的配置文件中,声明,css后缀的文件使用css-loader解析,ts后缀的文件使用ts-loader解析
module.exports = { module: { rules: [ { test: /\.css$/, use: 'css-loader' }, { test: /\.ts$/, use: 'ts-loader' } ] } };
更多loader的配置:webpack loaders
4.插件(plugins)
plugins用于自定义webpack的构建过程, 好比自定义打包以后的html模板,自定义js和样式文件是否打包等等
plugins的值,是一个个new出来的插件实例
webpack4取消了四个经常使用的用于性能优化的pluginUglifyjsWebpackPlugin,CommonsChunkPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin
转而提供了一个名为optimization的配置项,用于替代以上四个插件(并非说以上插件不能使用了,只是webpack4自己有替代的方案,能够不用插件)
html-webpack-plugin
经过new 该插件的实例,可让webpack帮咱们编译出一个html文件
须要注意的是,多页面的配置下,有多少个页面,就要new多少个实例,传入到plugins中,后面有代码示例。
html-webpack-inline-source-plugin
这个插件用于生产模式下,让webpack在打包的时候,将js和css直接插入到html中,从而减小请求的消耗
要注意的是,并非全部状况下都适合用,文件较大时,仍是推荐经过标签去引入资源(运行时文件通常比较小,下面会经过另外一个插件将runtime的代码直接插入html中)
更多插件及其配置:webpack plugins
5.模式(mode)
mode是webpack4新增的参数选项,它有三个值,development、production、none,
因为开发模式和生产模式所须要的webpack的配置稍微有单不一样(可是大部分是相同的)
因此能够创建两个webpack的配置文件,分别用于开发模式和生产模式,除此以外,指明当前处于哪一个模式下,有利于webpack内部作优化
好比,有一些插件是在生产模式下才启用的。
经过指定mode的值为development和production中的一个,来表示webpack处于何种模式下,默认值是production
mode为 development 时,注重提高代码的构建速度和开发体验
module.exports = { mode: 'development', cache: true, devtools: "eval", plugins: [ new webpack.NamedModulesPlugin(), new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }) ] };
mode为 production 时,提供代码优化,如压缩、做用域提高等
module.exports = { mode: 'production', plugins: [ new UglifyJsPlugin(/* ... */), new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), new webpack.optimize.ModuleConcatenationPlugin(), new webpack.NoEmitOnErrorsPlugin() ] }
也能够经过命令行运行下面的命令来指定模式
webpack --mode=production
6.优化(optimization)
这个选项也是wepack4新增的,主要用来自定义一些优化打包的策略
minimizer
在production模式下,该配置会默认为咱们压缩混淆代码,但配置项过于少致使没法知足咱们对于优化代码的诉求,下面是一套比较灵活的优化配置
var UglifyJsPlugin = require('uglifyjs-webpack-plugin') var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') module.exports = { optimization: { minimizer: [ // 自定义js优化配置,将会覆盖默认配置 new UglifyJsPlugin({ exclude: /\.min\.js$/, // 过滤掉以".min.js"结尾的文件,咱们认为这个后缀自己就是已经压缩好的代码,不必进行二次压缩 cache: true, parallel: true, // 开启并行压缩,充分利用cpu sourceMap: false, extractComments: false, // 移除注释 uglifyOptions: { compress: { unused: true, warnings: false, drop_debugger: true }, output: { comments: false } } }), // 用于优化css文件 new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css$/g, cssProcessorOptions: { safe: true, autoprefixer: { disable: true }, //这里注意下!!!!! mergeLonghand: false, discardComments: { removeAll: true // 移除注释 } }, canPrint: true }) ] } }
UglifyJsPlugin是你们常用的插件,这里比较亮的地方是能够过滤自己已经压缩的js,能够提高打包速度,而且避免二次混淆压缩形成的未知bug
OptimizeCssAssetsPlugin用来优化css文件的输出,优化策略包括:摈弃重复的样式定义、砍掉样式规则中多余的参数、移除不须要的浏览器前缀等
这里注意插件的参数autoprefixer: { disable: true },必定要指定为true。不然的话该插件会把咱们用autoprefix加好的前缀都移除掉(由于该插件以为多余)
runtimeChunk
分离出webpack编译出来的运行时代码,也就是咱们以前成为manifest的代码块,方便咱们作文件的之就好缓存
这个参数项(runtimeChunk)有多种类型的值,其中,single即将全部的chunk的运行时代码打包到一个文件中,multiple即针对每一个chunk的运行时代码分别打包出一个runtime文件
咱们能够配合上面说到的 InlineManifestWebpackPlugin插件,将运行时代码直接插入html文件中,由于这段代码很是少,这样作能够避免一次请求的开销
InlineManifestWebpackPlugin插件的顺序必定要在HtmlWebpackPlugin以后,不然会致使编译失败
var HtmlWebpackPlugin = require('html-webpack-plugin') var InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin') module.exports = { optimization: { runtimeChunk: 'single' // 等价于 // runtimeChunk: { // name: 'runtime' // } }, plugins: [ new HtmlWebpackPlugin({ template: '../src/index.html', filename: 'article.html', chunks: ['article', 'vendors', 'runtime'] }), new InlineManifestWebpackPlugin(), //放在htmlWebpackPlugin的后面才能生效 ] }
splitChunks
这是比较难理解的一个配置项
webpack4移除了CommonsChunkPlugin插件,取而代之的是splitChunks
比较优雅的分离打包配置以下
splitChunks: { cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors', minSize: 30000, minChunks: 1, chunks: 'initial', priority: 1 // 该配置项是设置处理的优先级,数值越大越优先处理 }, commons: { test: /[\\/]src[\\/]common[\\/]/, name: 'commons', minSize: 30000, minChunks: 3, chunks: 'initial', priority: -1, reuseExistingChunk: true // 这个配置容许咱们使用已经存在的代码块 } } }
这段配置,首先是将node_modules中的模块统一打包成vendors.js
它限制了分离文件的最小体积为30k(压缩以前的),由于webpack认为,小于30k的代码分离出来,还要额外小号一次请求去加载它,成本过高,这个值是经过大量的时间总结出来的
其次,还分离除了共享模块,好比src目录下有几个全局公用的js文件如utils等,能够单独抽出来打包成一个commons.js
因为这部分文件不常常改变,有利于持久缓存
完:demo地址