弄懂 SourceMap
转载:https://mp.weixin.qq.com/s/l_ZDlie3X8zHGw8d5e6zJw
一、什么是 Source Map
通俗的来说, Source Map
就是一个信息文件,里面存储了代码打包转换后的位置信息,实质是一个 json
描述文件,维护了打包前后的代码映射关系。关于 Source Map
的解释可以看下 Introduction to JavaScript Source Maps。
二、Source Map 的作用
我们为什么需要 Source Map
?
大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。
常见的源码转换,主要是以下三种情况:
- 压缩,减小体积
- 多个文件合并,减少 HTTP 请求数
- 其他语言编译成 JavaScript
这三种情况,都使得实际运行的代码不同于开发代码,debug 变得困难重重,所以才需要 Source Map
。结合上面的例子,即使打包过后的代码,也可以找到具体的报错位置,这使得我们 debug 代码变得轻松简单,这就是 Source Map
想要解决的问题。
三、如何生成 Source Map
各种主流前端任务管理工具,打包工具都支持生成 Source Map 。
Grunt
配置 grunt-contrib-uglify 插件以生成 Source Map :
grunt.initConfig({
uglify: {
options: {
sourceMap: true
}
}
});
Gulp
使用gulp-sourcemaps生成 Source Map :
var gulp = require('gulp');
var plugin1 = require('gulp-plugin1');
var plugin2 = require('gulp-plugin2');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(plugin1())
.pipe(plugin2())
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('dist'));
});
Webpack
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
devtool: "source-map"
};
四、如何使用 Source Map
生成 Source Map 之后,一般在浏览器中调试使用,前提是需要开启该功能,以 Chrome 为例:
打开开发者工具,找到 Settins :
勾选以下两个选项:
五、Source Map 的工作原理
生成 dist 文件夹,打开 dist/bundld.js :
可以看到尾部有这句注释:
//# sourceMappingURL=bundle.js.map
正是因为这句注释,标记了该文件的 Source Map 地址,浏览器才可以正确的找到源代码的位置。sourceMappingURL 指向 Source Map 文件的 URL 。
除了这种方式之外,MDN中指出,可以通过 response header 的 SourceMap:
> SourceMap: /path/to/file.js.map
dist 文件夹中,除了 bundle.js 还有 bundle.js.map ,这个文件才是 Source Map 文件,也是 sourceMappingURL 指向的 URL
题外话:reverse-sourcemap 可还原文件
npm install --global reverse-sourcemap
reverse-sourcemap -o XXX(导出路径) app.XXX.js.map(打包文件中的.js.map文件)