这两天在组里协助排查一个 webpack dev 环境下重载时内存溢出的问题,现象是 webpack-dev-server 启动的过程中,在 node 10.xx 的环境下,一旦修改文件工程自动 reload 时会出现内存溢出导致服务直接中断。

排查原因,最终发现原来是脚手架在配置开发环境的 devtool 配置时,为了方便开发者 DEBUG,设置成了 cheap-module-source-map ,在代码修改时触发自动 load,在 loader 编译映射 sourcemap 的时候溢~出~了~,本文不会说明为什么溢出,排查的过程以及解决,其实花的时间也不长,重点说明一下 sourcemap 的作用以及使用过程的几点个人思考。

异常

1
2
3
4
5
6
7
8
9
10
11
12
13
[27849:0x102880000]   133250 ms: Mark-sweep 1377.8 (1409.0) -> 1377.8 (1409.5) MB, 366.7 / 0.0 ms  (average mu = 0.076, current mu = 0.015) allocation failure scavenge might not succeed

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x1673f099e6c1 <JSObject>
0: builtin exit frame: stringify(this=0x1673f09919f9 <Object map = 0x1673955842a9>,0x1673fa7826f1 <undefined>,0x1673fa7826f1 <undefined>,0x1673500ffcc9 <Object map = 0x167345daabb1>,0x1673f09919f9 <Object map = 0x1673955842a9>)

1: arguments adaptor frame: 1->3
2: /* anonymous */(aka /* anonymous */) [0x1673e6f2d6a1] [/Users/xxx/node_modules/webpack/lib/SourceMap...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

好了,上面的报错信息看过就可以忘记了。

SourceMap 在 WEB 开发过程中扮演着很重要的角色,因为被浏览器执行的代码往往与开发过程中原始代码相差很多,源码经过了很多次转译、合并、混淆、压缩等等步骤几乎不具有可读性,那么开发中调试、监控到异常定位快速与本地的源码映射匹配就成了它的唯一“使命”。

  • HTTP Headers 支持 SourceMap: <url> 属性,在请求时就能将映射的资源显示在浏览器的调试面板里。
  • 现代浏览器都支持加载的文件内含有类似 //# sourceMappingURL=path/to/xxx 这类注释,用来明确匹配到对应的指定文件方便跟踪。

那么在使用 SourceMap 应该注意什么呢?

可读性

要发挥它的作用,就要生成的 SourceMap 文件尽量地映射成源码,方便 debug。

比如,Webpack 的 devtool 中支持很多种生成模式,其中常用的 cheap-module-source-map 配置,就可以映射方便定位 .tsx 的内容。

平衡性能

生成 SourceMap 映射文件的过程,是一个转码的过程,记录两边的映射关系,那么转换时性能就成为了一个需要平衡的问题。理想情况,开发时尽可能保证转换速率,而构建时可以降低构建的性能消耗,保证文件的映射还原度。

预防泄漏

要避免源码泄漏,那么生成的 SourceMap 文件的存放位置就不能随意被外网访问到。

比如,异常监控系统中,为了方便开发者快速定位问题代码,在每一次构建时产生的 sourcemap 文件保存在内网指定一个位置,同时与当前上线部署版本做好匹配。

小结

在做 Java 开发时候反编译这个词应该很常见,也有对应的工具用来混淆和反混淆,WEB 端的 JavaScript / CSS 通常来说对任何人都是透明地,所以一些关键逻辑(比如涉及抽奖,特殊逻辑)尽量不要写在 js 脚本中,可以放在服务端或者编译成诸如 WebAssembly 一类字节码来避免一些重要逻辑泄漏。

PS.附赠一篇昨天无意中看到的总结,写的实在挺好的,和业界大佬还是有很大差距,加油吧。

我在阿里云做前端 https://juejin.im/post/6844903808904986637

参考文章: