最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Webpack Sourcemap 回顾

    正文概述 掘金(JackySummer)   2021-03-21   528

    本文同步发布在我的 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?"
        )
      },
    ...])
    

    Webpack Sourcemap 回顾

    为什么 eval 模式 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 使用于如下的场景

    • 访问外部资源受限
    • 图片体积小,占用一个 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的,依据你们需求场景选择。总之,最终结果是不能被人通过开发者工具看到源代码的。

    Webpack Sourcemap 回顾

    结语

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

    参考

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


    ps:

    • 个人技术博文 Github 仓库

    起源地下载网 » Webpack Sourcemap 回顾

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元