乐趣区

关于webpack:Webpack-Sourcemap-回顾

本文同步公布在我的 Github 集体博客

前言

前几天在优化我的项目时,发现 next.config.js 的配置里,development 模式下的 sourcemap 为cheap-module-sourcemap,认真想了想,记忆中如同有个更举荐罕用的开发模式 sourcemap 配置:cheap-module-eval-source-map

看了一下是三年前增加的代码,于是又回顾钻研了下 webpack 的 sourcemap 配置,开个 PR。

什么是 Sourcemap

咱们的我的项目在打包后,将开发环境中源代码通过压缩,去空格,babel 编译等工程化转换,最终的我的项目代码和源代码之间差异性很大,会造成无奈 debug 的问题,在线上环境定位到的代码是压缩解决后的代码。

而 Sourcemap 就是是为了解决开发代码与理论运行代码不统一时帮忙咱们 debug 到原始开发代码的技术,解决上述 代码定位 的问题,是 源代码和指标代码出错地位的映射

Sourcemap 关键词

Sourcemap 的关键词组合目迷五色,咱们不可能一个一个去记每种 sourcemap 用处,咱们只需晓得几个关键词的意思,便可揣测它们组合的 sourcemap 类型。

eval

每一个模块都执行 eval() 过程,执行后不会生成 .map 文件,而是在每一个模块后追加 //@ sourceURL 来关联代码解决前后的对应关系 。应用 eval 包裹模块代码,能够进步 rebuild 的速度。故个别 sourcemap 带有eval 的选项,rebuild 速度都快一些。

webpackJsonp([1],[function(module,exports,__webpack_require__){
eval(
      ...
//# sourceURL=webpack:///./src/js/index.js?'
    )
  },
function(module,exports,__webpack_require__){
eval(
      ...
//# sourceURL=webpack:///./src/static/css/app.less?./~/.npminstall/css-loader/0.23.1/css-loader!./~/.npminstall/postcss-loader/1.1.1/postcss-loader!./~/.npminstall/less-loader/2.2.3/less-loader'
    )
  },
function(module,exports,__webpack_require__){
 eval(
      ...
 //# sourceURL=webpack:///./src/tmpl/appTemplate.tpl?"
    )
  },
...])

为什么 eval 模式 rebuild 的速度会快?

因为带 eval 的构建模式可能 cache Sourcemap,猜想可能是带 eval 的模式能把每个模块的生成代码独自打在一行里,并且都以 DataURL 的模式增加 sourcemap,这样它在 rebuild 时会对每一个模块进行查看,如果没有产生改变,就间接应用之前的 sourcemap,故只须要为改变的模块从新生成 sourcemap;而非 eval 的构建模式下生成代码不论有任何模块作出批改,都会影响到最初 bundle 文件整体的行列格局,所以它每次都要从新生成整体的 sourcemap,rebuild 的速度会很慢。

source-map

会为每一个打包后的模块生成独立的 .map 文件,会在 bundle 文件开端追加 sourceURI= 指定.map 文件门路 ,会在浏览器开发者工具中看到webpack:// 的文件夹

webpackJsonp([1],[function(e,t,i){...},
function(e,t,i){...},
function(e,t,i){...},
function(e,t,i){...},
  ...
])//# sourceMappingURL=index.js.map

打包后的模块在模块前面会对应援用一个 .map 文件,同时在打包好的目录下会针对每一个模块生成相应的.map 文件,在上例中会生成一个 index.js.map 文件,这个文件是一个典型的 sourcemap 文件,模式如下:

{
"version":3,
"sources":[
    "webpack:///js/index.js","webpack:///./src/js/index.js",
    "webpack:///./~/.npminstall/css-loader/0.23.1/css-loader/lib/css-base.js",
    ...
],
"names":["webpackJsonp","module","exports"...],
"mappings":"AAAAA,cAAc,IAER,SAASC...",
"file":"js/index.js",
"sourcesContent":[...],
"sourceRoot":""
}

cheap

不蕴含列信息也不蕴含 loader 的 sourcemap,会为每一个模块生成 .map 文件,与 source-map 的区别在于 cheap 生成的 .map 文件会疏忽原始代码中的列信息。

因为生成的 sourcemap 不会有列信息而只有行信息,编译计算量少,所以速度较快。

module

蕴含 loader 模块之间的 sourcemap(比方 jsx 语法代码经 loader 编译为原生 js 代码), 这样能够看到 loader 解决前的原始代码

inline

失常的 sourcemap 的生成是在 dist 目录下创立一个.map 文件,inline 的含意就是不产生独立的 .map 文件,把 sourcemap 的内容以 DataURI 的形式追加到 bundle 件开端,行将.map 作为 DataURI 嵌入。(个别应用该类型如造成体积过大,该类型比拟少用)

webpackJsonp([1],[function(e,t,i){...},
function(e,t,i){...},
function(e,t,i){...},
function(e,t,i){...},
  ...
])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9...

DataURL 最早是呈现在 HTML 文件 img 标签中的对于图片的援用,如 base64 图片

DataURL 应用于如下的场景

  • 拜访内部资源受限
  • 图片体积小,占用一个 HTTP 会话资源节约

hidden

bundle 里不蕴含 sourcemap 的援用地址,这样浏览器开发者工具里看不到原始代码

Sourcemap 类型

上述的关键词混一起搭配,又减少了好几种 sourcemap 类型

  • eval-source-map:每一个模块在执行 eval()过程之后,并且会为每一个模块生成 .map 文件,生成的 sourcemap 文件通过 DataURL 的形式增加(把 eval 的 sourceURL 换成了残缺 sourcemap 信息的 DataURL)
  • cheap-eval-source-map:跟 eval-source-map 雷同,惟一不同的就是减少了 ”cheap”,”cheap” 是指疏忽了行信息。这个属性同时也不会生成不同 loader 模块之间的 sourcemap。
  • cheap-module-eval-source-map:与 cheap-eval-source-map 雷同,然而蕴含了不同 loader 模块之间的 sourcemap
  • cheap-source-map:不蕴含列信息,不蕴含 loader 的 sourcemap
  • inline-source-map:为每一个文件增加 sourcemap 的 DataURL,留神这里的文件是打包前的每一个文件而不是最初打包进去的,同时这个 DataURL 是蕴含一个文件残缺 sourcemap 信息的 base64 格式化后的字符串

hidden-source-map:不在 bundle 文件结尾处追加 sourceURL 指定其 sourcemap 文件的地位,然而依然会生成 sourcemap 文件。这样,浏览器开发者工具就无奈利用 sourcemap, 目标是防止把 sourcemap 文件公布到生产环境,造成源码泄露。

不仅还有这几种,还能够持续组合,这里就列举这么多了

如何抉择 Sourcemap

  • 首先在源代码的列信息意义不大,因为只有有行信息就能残缺的建设打包前后代码之间的依赖关系,够咱们定位了。
  • 其次,不论在生产环境还是开发环境,咱们都须要定位 debug 到最最原始的资源,比方定位谬误到 jsx 的原始代码处,而不是编译成 js 的代码处,因而,不能疏忽 module 属性。
  • eval-source-map 应用 DataURL 自身蕴含残缺 sourcemap 信息,并不需要像 sourceURL 那样,浏览器须要发送一个残缺申请去获取 sourcemap 文件,这会稍微进步点效率

开发环境中应用:cheap-module-eval-source-map(该配置值能保留 loader 解决前的原始代码信息,而打包速度也较快,是一个较佳的抉择。)

生产环境中应用 sourcemap 会有泄露源代码的危险,但如果要保留定位线上的谬误,应该禁止浏览器开发者工具看到源代码,而是用一些谬误收集零碎,将 sourcemap 文件传到零碎上,通过零碎 source map 剖析出原始代码的谬误堆栈,如应用hidden-source-map

当然,也有应用 nosources-source-map, source-map 的,根据你们需要场景抉择。总之,最终后果是不能被人通过开发者工具看到源代码的。

结语

咱们我的项目目前还是 Webpack4.x,如果你们我的项目曾经用 Webpack5,sourcemap 名称有些不
同,具体请查阅 Webpack5 文档。

参考

Webpack 中的 sourcemap 以及如何在生产和开发环境中正当的设置 sourcemap 的类型

ps:

  • 集体技术博文 Github 仓库
退出移动版