目录
一、source map简介
现在先让我们清理原先的src文件夹,只留下index.js和template.html:
并且修改index.js:
index.js:
consele.log('hello world!');
很明显这是一个错误语句,因为console写成了consele。
再修改webpack.config.js让项目只有一个入口文件:
webpack.config.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 导入HtmlWebpackPlugin
const CleanWebpackPlugin = require('clean-webpack-plugin'); // 导入CleanWebpackPlugin
module.exports = {
mode: 'development',
devtool: 'none',
entry: {
main: './src/index.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(png|svg|jpg|gif$)/, // 文件后缀名匹配通配符
use: [{
loader: 'url-loader', // 使用的loader
options: {
limit: 10240 // 当图片小于10kb时,使用base64的方式进行打包
}
}]
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf)$/,
use: [
'file-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'dist.html', // 将自动生成的html文件的文件名改为dist.html
template: './src/template.html' // 模板
}),
new CleanWebpackPlugin()
]
};
注意上面的devtool: 'none',这是将source map功能关闭,因为development模式下会默认开启source map功能。
现在进行打包操作:
打包成功,然后用浏览器打开dist.html,并打开控制台:
我们可以发现控制台的错误信息中,只含有错误在出口文件中的位置信息,却没有错误在源代码中(index.js)的位置信息。
当webpack打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,在本例中,将index.js打包到一个main.js中,而index.js中包含一个错误,那么堆栈跟踪就会简单地指向到main.js。这通常并没有太多帮助,因为我们可能需要准确地知道错误来自于哪个源文件。
为了更容易地追踪错误和警告,webpack提供了source map功能,将编译后的代码映射会原始源代码。如果错误来自于index.js,source map就会明确的告诉你。
二、使用source map
在上面我们在webpack.config.js中设置devtool: 'none'来关闭source map功能,那怎么开启source map功能呢?
其实devtool属性可以接受以下值:
不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
其中一些值适用于开发环境,一些适用于生产环境。对于开发环境,通常希望更快速的source map,需要添加到bundle中以增加体积为代价,但是对于生产环境,则希望更精准的source map,需要从bundle中分离并独立存在。
下面让我们来一一探索这些值的不同效果:
①souece-map
将webpack.config.js中的devtool修改为devtool: 'source-map',然后进行打包:
生成了一个main.js.map文件,其实这个文件里面就包含了错误信息的映射关系。
我这里用谷歌浏览器打开显示不出准确错误信息,还没找到原因,这一部分先放着吧。
②inline-source-map
将webpack.config.js中的devtool修改为devtool:'inline-source-map',然后进行打包:
这次没有生成main.js.map文件,那么使用浏览器打开dist.html:
可以发现控制台仍然打印了错误位置的详细信息,也就是定位了错误信息在index.js文件,而不是在main.js。
那么原先是通过main.js.map这个文件实现了映射关系,那么现在没有生成main.js.map文件,那么映射功能是如何实现的呢?
打开main.js文件,可以发现这么一部分内容:
原来,wepback将映射关系以Base64的形式放在main.js中!
③cheap-inline-source-map
将webpack.config.js中的devtool修改为devtool: 'cheap-inline-source-map',然后进行打包:
使用浏览器打开dist.html:
貌似跟之前的配置的效果没什么区别。
在代码量很大的项目中,如果devtool中没有加入cheap关键字(这些cheap、inline等关键字都可以自由组合),则错误信息会精确到哪一行哪一列发生错误,但是这样打包耗费的时间肯定比较长。而加入了cheap关键字(例如这里的cheap-inline-source-map),则错误信息只会定位到哪一行,打包时间就会相对短一些。
另外,cheap-inline-source-map的配置使得webpack只负责映射业务代码的错误信息,而不管第三方模块,所以会定位不到第三方模块的错误位置。
④cheap-module-souce-map
将webpack.config.js中的devtool修改为devtool:'cheap-module-souce-map',则webpack不仅负责映射业务代码的错误信息,也映射第三方模块的错误信息。
⑤eval
将webpack.config.js中的devtool修改为devtool:'eval',然后进行打包操作,然后打开main.js,可以发现这一部分代码:
这种配置情况下,webpack会借助eval()方法构建映射关系,而且构建速度是所有devtool选项种最快的。
但是因为构建速度快,提示的的内容可能并不全面。
⑥cheap-module-eval-souce-map(开发模式下的最佳选择)
前面提到多mode:'devlopment'情况下,会默认开启souce map功能,这是一个不错的选择。
但是综合构建速度、错误信息的质量等因素,最佳的选择应该是devtool: 'cheap-module-eval-souce-map'
⑦cheap-module-souce-map(生产环境下的最佳选择)
这个选项与前面的开发模式的最佳选择的差异是没有eval关键字,所以错误信息构建速度将会更慢,但是错误信息将会更完备,更容易定位到错误代码位置。