最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • [webpack学习]梳理一下sourcemap的知识点

    正文概述 掘金(村上小树)   2021-02-02   592

    sourcemap的作用

    在生产环境和开发环境下,经过webpack打包的代码在运行发生错误时,控制台报出的错误信息让人很难定位。如下:

    [webpack学习]梳理一下sourcemap的知识点

    如果我们引入sourcemap,在webpack的配置文件中导出配置添加devtool如下所示:

    webpack.config.js

    module.exports = {
          mode:'production',
          devtool:'source-map', // 添加devtool配置
        //..以下配置省略
    }
    

    则同样的代码以及同样的抛出错误,控制台报出的信息会更详细。如下:

    [webpack学习]梳理一下sourcemap的知识点

    为什么运行的是已经打包压缩后的代码,然而在输出报错时可以精准定位到开发代码。其中是借助sourcemap实现的,sourcemap作用在于映射转换过后的代码与源代码之间的关系。

    sourcemap的原理

    这里简单说一下sourcemap的原理,当经过启用了sourcemap的webpack打包时,会对每个打包压缩后的文件生成对应的map代码。我们拿jquery1.10.2map代码作例子,其结构如下:

    {
          "version": 3, // SourceMap的版本,目前为3
          "file": "jquery.min.js", // 转换后的文件名称
          "sources": ["jquery.js"], // 转换前的文件名称的集合,因为转换后的文件可能是多个文件打包合并的,所以此属性的值是数组类型
          "names":[ // 源代码使用的成员名称,压缩代码时会通过把变量名替换成简短的形式以减少体积。故此值用于记录原始对应的名称
          	"global",
            "factory",
            ...
          ],
          "mappings":";;;CAaA,SAAWA,EAAQC,GAOnB,..." // BASE64-VLQ编码的字符串,记录转换后的代码和源代码之间的映射关系
          // "sourcesContent": "", 转换后的代码,jquery的map不存在此项
          // "sourceRoot" : "" 转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空,jquery的map不存在此项
    }
    

    拓展: 至于里面的mappings是怎么映射的,可以看:阮一峰 JavaScript Source Map 详解

    不同的sourcemap会对该map代码的放置方式不同。

    • inline-*eval-*命名的sourcemap会把map代码内联到对应的打包后的原文件中,
    • 而其他的会把map代码放置到与对应的打包压缩后的原文件同名的以.map为后缀的新的文件中。

    devtool的分类

    为什么不直接说sourcemap的不同模式?因为devtool中除了可以设置"sourcemap"模式还可以设置"eval"模式。这里先介绍"eval""sourcemap",后再介绍"sourcemap"的不同模式。

    以下的构建重构分别指webpack初次构建和在监视模式下文件变化时的重新构建。

    eval

    效果: 该模式下,每个模块都使用 eval() 执行,并且都有 //@ sourceURL。但其错误定位在经过webpack打包生成的独立模块的代码上。如下:

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 此模式下,webpack无论是初次构建还是重新构建的速度都快。主要缺点是,由于会映射到转换后的独立模块代码,而不是映射到源代码(没有从 loader 中获取 sourcemap),所以不能正确的显示行数。主要在简单的项目中的开发模式下可以使用。

    source-map

    效果: 每个打包后的生成的文件都会生成一个对应的map文件作为转换代码和源代码之间的映射。对比于上述的eval模式,source-map模式的定位精准度高很多,可以定位到列位置。

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 虽然精准度高,然而构建速度和重构速度非常的慢,因此用于对错误代码定位要求高的生产环境中。

    在如今前端框架普遍使用的时代,用eval模式定位错误非常鸡肋,然而用source-map模式时webpack的构建速度和重构又非常慢。针对此,source-map模式下又分了好几种模式,以对其构建过程进行一些调整从而达到加快webpack的构建和重构速度。

    我们可以引用webpackdevtool的校验规则去了解sourcemap的分类

    inline-*

    效果: 该模式下会把生成的map文件转换为DataUrl后以//# sourceMappingURL=DataUrl添加到转换后的文件中中。如下所示:

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 这种模式下生成的map文件体积较大,所以一般在开发模式和生产模式都不会被使用。他们是一些特定场景下需要的,例如,针对一些第三方工具。

    hidden-*

    效果: 该模式下会生成map文件,但不会为打包后的代码添加引用注释。因此报错时控制台的输出错误效果会和没设置生成sourcemap的一样。

    使用场景: 该模式适用于生产环境,尤其是用于开发第三方包,开发者想生成map文件而达到映射那些源自错误报告的错误堆栈跟踪信息,但不想在打包代码中引用。

    当使用第三方包的开发者想引用map文件时,可以手动通过注入//# sourceMappingURL=(map文件名称)把这个包引用回来。目前jquery就是用这种模式。

    eval-*

    效果: 该模式下打包生成的每个模块使用eval()执行,并且map文件会转换为DataUrl后添加到eval()中。如下所示:

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 第一次构建map文件时比较慢,但在重新构建时速度较快。eval-cheap-source-map,eval-cheap-module-source-map以及eval-source-map都适用于开发环境

    nosources-*

    效果: 该模式下,当抛出错误时,输出的错误栈会详细列出错误来源,但当点击错误栈查看源码时,源码为空或无法加载。

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 可以在生产环境下使用,在错误抛出时找到错误来源的同时,可以保护源代码不会被暴露。

    cheap-*

    效果: 使用该模式下,map文件没有生成列映射(column mapping),只是映射行数。下面可以对一下cheap-source-mapsource-map

    使用cheap-source-map:

    [webpack学习]梳理一下sourcemap的知识点

    使用source-map:

    [webpack学习]梳理一下sourcemap的知识点

    使用场景: 可以看出使用cheap-*会让错误信息只定位到行,较source-map的定位到列会显得稍微不太精准。但其好处就是低开销,构建与重构速度快。无论哪种环境都可以用该模式以准确性为代价提高构建速度。

    cheap-module-*

    效果: 使用该模式下,错误栈定位的代码是loader加工转换前的,否则,定位的代码是loader加工转换后的。下面详细说明以下:

    假设下面是开发时的源代码:

    /src/index.js

    const fn=()=>{
      console.log1('hello')
    }
    
    fn()
    

    webpack.config.js中的module.rules这么设置:

    module:{
      rules:[
        {
          test:/\.js$/,
          use:{
            loader:'babel-loader',
            options:{
              presets:['@babel/preset-env']
            }
          }
        }
      ]
    },
    

    此时 /src/index.js中的箭头函数在打包过程中经过babel-loader的转换会被替换成普通函数。

    现在再对比一下cheap-source-mapcheap-module-source-map

    cheap-source-map:

    [webpack学习]梳理一下sourcemap的知识点

    cheap-module-source-map:

    [webpack学习]梳理一下sourcemap的知识点

    对比得知,cheap-module-source-map定位的是loader转换前的代码,cheap-source-map定位的是loader转换后的代码。其错误定位是到源代码行的,因为cheap-module-* 模式是在cheap-* 模式下进一步调整的。

    使用场景: 不分环境,能提高定位的精准度,但会降低初次构建map文件的速度。

    如何选择适合的sourcemap

    同上面不同的sourcemap模式的特性可知,有些适合在开发环境使用,有些适合生产环境使用,有些适合特殊环境下使用。

    下面来总结一下不同环境下适用的sourcemap

    开发模式

    以下选项非常适合开发环境:

    devtool构建速度重构速度定位精准度
    eval-source-mapslowestok源代码eval-cheap-source-mapokfastloader转换后的代码eval-cheap-module-source-mapslowfast源代码行

    生产环境

    这些选项通常用于生产环境中:

    devtool构建速度重构速度定位精准度
    (none)fastestfastest生成且打包后的代码source-mapslowestslowest源代码hidden-source-mapslowestslowest源代码nosources-source-mapslowestslowest源代码

    个人认为:一般不允许普通用户访问sourcemap文件,因此,不能把sourcemap文件部署到线上(RC)环境。

    特殊环境

    以下选项对于开发环境和生产环境并不理想。他们是一些特定场景下需要的,例如,针对一些第三方工具。

    devtool构建速度重构速度定位精准度
    inline-source-mapslowestslowest源代码cheap-source-mapokslowloader转换后的代码inline-cheap-source-mapokslowloader转换后的代码cheap-module-source-mapslowslow源代码行inline-cheap-module-source-mapslowslow源代码行

    其余更详细的sourcemap请查看webpack devtool:


    起源地下载网 » [webpack学习]梳理一下sourcemap的知识点

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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