在前端工程中引入webpack后,开发人员往往会有下面两个疑问:
- webpack的编译实际上是对代码执行合并、压缩和混淆等动作,最终生成的代码往往已经不具备可读性,不利于开发对问题进行debug;
- 每次代码修改都需要webpack执行一次编译动作,上面提到的合并、压缩和混淆等动作过于消耗性能。
首先看一下可读性问题,以笔者上一篇博客的代码为例,我们在mainCtrl.js里故意构造一个脏检查次数达到循环上限的异常:
嗯,错误还是看的出来,看看有没有办法debug:
看起来想debug是没戏了,压缩以后完全看不出来代码是在做什么,想在线上调试的话看来得想其他办法解决。
再看一下webpack编译的性能问题:
总共6个文件。不超过200行代码,还没做混淆就用了3秒多。按实际项目里的文件数量及执行动作来算的话,几十秒甚至几百秒都是正常的,但是让开发每次调试都要等这么久就不靠谱了。
这其实是在开发阶段使用生产模式带来的问题,所以在开发阶段有必要引入开发模式:不要代码压缩混淆,源码支持调试。
而webpack4允许我们指定编译使用开发模式还是生产模式,这由mode这个配置来控制,value为枚举值:development/production,分别对应开发模式和生产模式(这个配置可以作为命令行的配置参数也可以作为配置文件中的一个配置项,默认值是production,即生产模式)。
下面在webpack.config.js中增加mode配置项:
"use strict";
module.exports = {
entry: "./index.js",
output: {
path: __dirname + "",
filename: "bundle.js"
},
module: {
},
mode: 'development'
};
重新编译一把,性能明显有了提升(只要几百毫秒就搞定了):
不过看下源码,貌似还是不支持调试(都用eval函数包住):
这是由于devtool我们没有配置,这个配置项用于指定编译时的source-map生成方式,默认值是eval。官方文档给出了7种配置项说明:
模式 | 说明 |
---|---|
eval | 每个module会封装到 eval 里包裹起来执行,并且会在末尾追加注释 |
source-map | 生成一个SourceMap文件 |
hidden-source-map | 和source-map一样,但不会在bundle末尾追加注释 |
inline-source-map | 生成一个DataUrl形式的SourceMap文件 |
eval-source-map | 每个module会通过eval()来执行,并且生成一个DataUrl形式的SourceMap |
cheap-source-map | 生成一个没有列信息(column-mappings)的SourceMap文件,不包含loader的 SourceMap(譬如babel的SourceMap) |
cheap-module-source-map | 生成一个没有列信息(column-mappings)的SourceMap文件,同时loader的 SourceMap也被简化为只包含对应行的 |
那就在webpack.config.js中再增加devtool配置项:
"use strict";
module.exports = {
entry: "./index.js",
output: {
path: __dirname + "",
filename: "bundle.js"
},
module: {
},
devtool: 'inline-source-map',
mode: 'development'
};
编译用时差不多,就不贴出来了,主要看下源码(网上有很多介绍devtool的不同配置项编译生成文件区别的文章,有兴趣的同学请自行百度,这里就不多说了):
ok,至此本文开头的两个问题都已经基本解决,但是每次切换模式webpack.config.js还要来回改,而且编译生成的文件一旦发生冲突解决起来也非常麻烦,所以最好的办法就是开发模式和生产模式都给出独立的配置文件,两边互不干扰,本地调试调用开发模式的配置文件编译,最终发布包里的文件由编译环境调用生产模式的配置文件编译生成。比如package.json可以加上两条命令:
{
"name": "angular-webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --progress --colors --config ./webpack.dev.config.js",
"product": "webpack --progress --colors --config ./webpack.product.config.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"angular": "^1.4.6",
"angular-ui-router": "^0.2.18",
"css-loader": "^0.28.11",
"jquery": "^1.9.1",
"oclazyload": "^1.0.1",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.6.0",
"webpack-cli": "^2.1.3"
}
}
dev对应开发模式,我们本地执行npm run dev就可以了;product对应生产模式,由编译环境执行npm run product来执行合并、压缩和混淆等动作生成最终的文件。
本文涉及代码github地址:https://github.com/liqing-taoyanzoukaila/angular-lazyload-webpack