Source Map不同模式对比

JavaScript代码经过编译转换有三个好处

  1. 压缩,减少体积
  2. 多个文件合并,减少HTTP请求
  3. 其他语言编译成JavaScript

这样使得实际代码不同于开发代码,debugger过程无法进行,source map储存位置信息(转换后代码所对应的转换前代码位置),source map映射转换后的代码与源代码之间的关系,参考JavaScript Source Map 详解,解决引入构建编译的概念之后,导致源代码与运行代码不一致所产生的调试问题

// source map生成文件目录
{
    version:Source map的版本,目前为3。
    names:转换前的所有变量名和属性名,压缩时替换为简短的字符。
    sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。
    mappings:source-map核心属性 base64 VLQ编码格式 记录转换过后位置信息的字符串
    file:转换后的文件名。
    sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
}
配置webpack SourceMap

通过构建或编译之后,开发阶段编写的源代码转换为在生产环境运行的代码,这种进步同时也意味着实际运行的代码和真正编写的代码之间的差异例子

// ./webpack.config.js
module.exports = {
  devtool: 'source-map' // source map 设置
}
eval('console.log(123) //# sourceURL=./foo/bar.js')

在打包后的文件中生成.map文件,在对应的js文件中通过//# sourceMappingURL=bundle.js.map引入

webpack devtool模式对比
  • eval模式:不会生成source map文件,每个模块都封装在eval中,并在后面添加//# sourceURL = xx.js

    [图片上传失败...(image-b4118b-1611217404145)]

    (function(module, exports, __webpack_require__) {
    
    eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(5);\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"body {\\n  margin: 0 auto;\\n  padding: 0 20px;\\n  max-width: 800px;\\n  background: #f4f8fb;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n\n\n//# sourceURL=webpack:///./src/main.css?./node_modules/css-loader/dist/cjs.js");
    
    /***/ }),
    /* 8 */
    /***/ (function(module, exports, __webpack_require__) {
    
    eval("module.exports = __webpack_require__.p + \"aaa0e8af948e470ee7dd81a36b503e18.png\";\n\n//# sourceURL=webpack:///./src/icon.png?");
    
    /***/ })
    
  • source-map:生成source map文件,并在打包末尾添加//# sourceMappingURL=bundle.js.map指定JS引擎文件,生成的source map文件目录上面已经有介绍

    // ......
    module.exports = __webpack_require__.p + "aaa0e8af948e470ee7dd81a36b503e18.png";
    /***/ })
    /******/ ]);
    //# sourceMappingURL=bundle.js.map
    
  • hidden-source-map:和 source-map 一样,但不会在 bundle 末尾追加注释,寻找文件靠后缀,如xxx/bundle.js尝试去找xxx/bundle.js.map

    // ......
    module.exports = __webpack_require__.p + "aaa0e8af948e470ee7dd81a36b503e18.png";
    /***/ })
    /******/ ]);
    
  • inline-source-map:不会生成source map文件,而是为每个文件添加source map的DataURL,这个DataURL是包含一个文件完成source map信息的Base64编码,会导致文件很大

    //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib...
    
  • eval-source-map:把eval的sourceURL换为完整sourcemap信息的DataURL

    (function(module, exports, __webpack_require__) {
    
    eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(5);\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"body {\\n  margin: 0 auto;\\n  padding: 0 20px;\\n  max-width: 800px;\\n  background: #f4f8fb;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvbWFpbi5jc3M/MDk5YyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBLGtDQUFrQyxtQkFBTyxDQUFDLENBQWdEO0FBQzFGO0FBQ0E7QUFDQSxjQUFjLFFBQVMsU0FBUyxtQkFBbUIsb0JBQW9CLHFCQUFxQix3QkFBd0IsR0FBRztBQUN2SDtBQUNBIiwiZmlsZSI6IjcuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG52YXIgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fID0gcmVxdWlyZShcIi4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIik7XG5leHBvcnRzID0gX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fKGZhbHNlKTtcbi8vIE1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiYm9keSB7XFxuICBtYXJnaW46IDAgYXV0bztcXG4gIHBhZGRpbmc6IDAgMjBweDtcXG4gIG1heC13aWR0aDogODAwcHg7XFxuICBiYWNrZ3JvdW5kOiAjZjRmOGZiO1xcbn1cXG5cIiwgXCJcIl0pO1xuLy8gRXhwb3J0c1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzO1xuIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7\n");
    
    /***/ }),
    /* 8 */
    /***/ (function(module, exports, __webpack_require__) {
    
    eval("module.exports = __webpack_require__.p + \"aaa0e8af948e470ee7dd81a36b503e18.png\";//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvaWNvbi5wbmc/Zjk0NCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxpQkFBaUIscUJBQXVCIiwiZmlsZSI6IjguanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IF9fd2VicGFja19wdWJsaWNfcGF0aF9fICsgXCJhYWEwZThhZjk0OGU0NzBlZTdkZDgxYTM2YjUwM2UxOC5wbmdcIjsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///8\n");
    
    /***/ })
    
  • cheap-source-map:不包含列信息,不包含 loader 的 sourcemap,(譬如 babel 的 sourcemap)

  • cheap-module-source-map:不包含列信息,同时 loader 的 sourcemap 也被简化为只包含对应行的。最终的 sourcemap 只有一份,它是 webpack 对 loader 生成的 sourcemap 进行简化,然后再次生成的。

webpack模式不仅支持7中,可以任意组合以上关键字,如cheap-module-inline-source-map

选择一个source map

  • 开发环境:cheap-module-eval-source-map,选择cheap因为代码每行不会很长,所以不需要关心列信息,选择module是因为像vue、react这种代码调试时需要源代码,而不是转换后的代码,使用eval可大幅提高持续构建效率
  • 生产环境:none,不生成source map,source map暴露源代码


    image-20210121094515843.png

你可能感兴趣的:(Source Map不同模式对比)