SourceMap及如何用构建工具生成Source Map

5,207 阅读2分钟

什么是SourceMap

  • 一般来说线上的js代码经过合并压缩成一行,这样会导致生产环境产生js错误的时,浏览器报出的错误行号,列号是没办法直接映射到源码错误的原来位置的。同时压缩代码的变量以及函数名称都会变换,给开发者排查、Debug JS错误增加了难度。
  • sourcemap就是为了解决上述代码定位的问题,简单理解,就是构建了处理前的代码和处理后的代码之间的桥梁。主要是方便开发人员的错误定位。
  • SourceMap 一个存储源代码与编译代码对应位置映射的信息文件,实际上就是一个 JSON 键值对,利用 VLQ编码与特定的规则存储位置信息。这里面的逻辑有兴趣的可以看看阮老师的这篇文章《 JavaScript Source Map 详解 》

如何用构建工具生成Source Map?

  1. Webpack 在其配置文件webpack.config.js中设置devtool即可生成Source Map文件,如
const path = require('path');
module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  devtool: "source-map" // devtool有13种不同取值,分别生成不同类型的Source Map,建议用source-map
};
  1. Gulp
var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('javascript', function() {
  gulp.src('src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(sourcemaps.write('../sourcemaps'))
    .pipe(gulp.dest('dist'));
});
  1. Grunt
  1. 如果你只使用grunt-contrib-uglify压缩打包
grunt.initConfig(
{
    uglify:
    {
        options:
        {
            sourceMap: true
        }
    }
});
  1. 如果你使用grunt-usemin压缩打包,由于grunt-usemin会依次调用grunt-contrib-concatgrunt-contrib-uglify对源码进行打包和压缩
grunt.initConfig(
{
    concat:
    {
        options:
        {
            sourceMap: true
        }
    },
    uglify:
    {
        options:
        {
            sourceMap: true,
            sourceMapIn: function(uglifySource)
            {
                return uglifySource + '.map';
            },
        }
    }
});
  1. 如果你使用grunt-jsmin-sourcemap
```
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-jsmin-sourcemap');
  grunt.initConfig({
    'jsmin-sourcemap': {
      all: {
        src: ['scripts/script.js'],
        dest: 'scripts/script.jsmin-grunt.js',
        destMap: 'scripts/script.jsmin-grunt.js.map'
      }
    }
  });
  grunt.registerTask('default', 'jsmin-sourcemap');
};
```
  1. AngularJS
ng build --prod --source-map --vendor-source-map
  1. UglifyJS2
  • UglifyJS2是命令行工具,执行如: $ uglifyjs app.js -o app.min.js --source-map app.min.js.map
  • 更多source-map选项请看
  1. SystemJSSystemJS Build Tool
builder.bundle('app.js', 'app-outfile.js',
{
    minify: true,
    sourceMaps: true
});

参考资料