在新添加的 CommonmChunkPlugin 插件中,我们添加了 manifest 值,这是为什么呢?如果你不添加这个值,你在打包时会发现, main.x.js 有更新, vendor.x.js 还是有更新,并未真正实现"分离"。官方文档对此的解释是:
The issue here is that on every build, webpack generates some webpack runtime code, which helps webpack do it's job. When there is a single bundle, the runtime code resides in it. But when multiple bundles are generated, the runtime code is extracted into the common module, here the vendor file.
大致的意思就是说,webpack每次编译时运行的代码会影响到 hash 值的变化,当只有一个打包文件时这部分代码会塞进去,当有多个打包文件时,这部分代码会进入公共的 vendor 。所以解决办法是使用 manifest 字段把这部分代码从 vendor 中作为一个公共模块抽出来,从而不会影响 vendor 。
将以上的配置写入 webpack.config.js ,运行webpack命令,我们发现业务代码和公共库代码成功分离,改写 main.1.js 文件的内容,再次打包,发现 vendor 文件并没有变化,成功!
当我们再进行打包时,发现又会多出了新的 main.x.js 等文件,打包三次就会出现三个 main.x.js 文件,此时该怎么办呢?我们可以使用 clean-webpack-plugin 插件:
npm i clean-webpack-plugin --save-dev
然后在 webpack.config.js 中引入:
var CleanWebpackPlugin = require('clean-webpack-plugin'); new CleanWebpackPlugin( ['public/main.*.js','public/manifest.*.js'],//要删除的文件目录匹配 { root:__dirname, verbose:true, dry:false } ),
这样我们每次在打包新的代码时,旧文件就会删除,不会再出现同一份文件存在多份的情况。
3.压缩
在webpack中,图片,css,js等等其他资源皆可压缩,本文仅以压缩js为例。
安装插件:
npm i uglifyjs-webpack-plugin --save-dev
在 webpack.config.js 中引入:
var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); new UglifyJsPlugin({ beautify:true, exclude:['/node_modules/'], compress:{ warnings:false }, output:{ comments:false } })
我们指定了压缩的方法,排除了不需要压缩的 node_modules 部分,同时我们去除了 comments 部分( comments 为@license等注释,是可观的压缩空间)。再次在终端输入打包命令,可见js打包后的体积有令人满意的减小。
4.热替换
webpack总是绕不开热替换的话题。热替换的功能配置和原理是一大话题,三天三夜也说不完,也并非本文重点,本文只提供简易高效的配置方法。
热替换存在两种使用方式, cli 和 node 。 cli 方式无需添加新的热替换插件,且无需在入口处添加 webpack-dev-server 等入口,故本文采用 cli 使用方式。
在 webpack.config.js 中添加 devServer 字段,加入如下代码:
devServer:{ inline:true, hot:true },
保存后运行 webpack-dev-server --inline --hot --progress ,再修改下 main.less 文件的样式,会发现浏览器并没有刷新,但页面已经发生了变化,我们的热替换功能也成功加入了!
tips:
在实际项目打包时,可以将 filename 字段的值换为 [name].[chunkhash].js ,其中 [chunkhash] 为webpack每次打包后给每个模块的标识值,这个值每次打包后都会更换。为什么在此处我们使用 [id] 呢,因为 chunkhash 与热替换存在冲突,终端会有报错,那么使用 id 可以算作一个解决方案。这就引申出另一话题,我们可以使用两套webpack配置分别用于生产环境和开发环境,通过webpack指定config来进行打包。例如我们在开发环境使用 id ,在生产环境去掉热替换并使用 hash 的方式。而且,一些压缩插件也没必要在开发环境过度使用,两套配置能让webpack发挥最大的威力。
另外, chunkhash 和 hash 有区别, chunkhash 顾名思义是模块的标识,而 hash 是webpack每次编译的标识值,不同的资源如js和css存在 chunkhash 解耦的问题,此处不进行过多讨论。
5.运行
我们知道,每次打包后,都会有新的 main.x.js 文件生成,其hash值每次打包后都会发生变化,难道我们的 index.html 文件需要每次打包后都手动修改 main.x.js 的路径吗?还好社区提供了 html-webpack-plugin 插件,可以在已有html模板的条件下自动为我们生成带有最新代码的html文件:
npm i html-webpack-plugin --save-dev
在 webpack.config.js 中引入:
var HtmlWebpackPlugin = require('html-webpack-plugin'); new HtmlWebpackPlugin({ title:'demo', template:'index.html' }),
在终端运行打包命令,我们看到 public 文件夹下生成了新的 index.html 文件: