上一篇 webpack处理模块化源码 的文章中提到了 "source map",这一篇来详细说说。

有什么作用

source map 用于映射编译后的代码与源码,这样如果编译后的代码出错了,可以很快速的定位到源文件的位置。

我们在 format.js 文件中打印一个不存在的 hello 变量, 当没有 source map 的时候,没有办法看到报错内容在源码的哪个位置。

生产环境提示报错是在编译后的 bundle.js 文件,点击该文件后,只能看到压缩和丑化之后的代码。

开发环境中会告知报错文件路径在 src/utils/format.js 中,点击 bundle.js 文件看到的代码也是经过编译的,和源码仍有些出入。

当设置了 source map 之后,源代码的目录结构、报错内容在哪个源文件、哪一行、列都能够清晰的看到。

这样可以快速的定位问题并进行代码修复。

如何使用

在配置文件 webpack.config.js 中,mode 字段用于定义模式,默认生产模式 "production",这里设置为开发模式便于调试,"dev-tool" 用于设置 source map,为了能看到 source map 定位到行与列的区别,增加 babel-loader。

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
module.exports = {
  entry: "./src/index.js",
  mode: "development",
  devtool: "inline-source-map",
  output: {
    filename: "./bundle.js",
    path: path.resolve(__dirname, "./dist"),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env"],
            },
          },
        ],
      },
    ],
  },
};

source map 有26种值可以设置,performance 表示构建速度,production 表示是否建议在"生产环境"使用,建议 source map 仅在开发及测试中使用,因为在生产中暴露源码是非常不安全的。

但这26种 source map 是有规律可循的,弄懂几种类型就可以全部理解。

source map 文件

当 devtool 设置为 source-map 时,webpack 会生成一个 source map 文件,并在打包后的 bundle.js 文件最后添加一行注释,指向 source map 文件。

source map文件中有这些字段用于记录编译后代码与源码的映射关系

  • version:版本,第一个版本的 source map 文件大小是源文件的 10 倍左右,第二版减少了 50%,第三版又减少了 50%,现在是第三版。
  • file:编译后的文件名,用于浏览器加载的
  • mappings:用来保存和源文件的映射信息(比如行、列位置信息、变量等)
  • sources:转换前的源文件、打包所用webpack代码
  • sourceContent:转换前的具体代码信息(与sources是对应的关系)
  • names:转换前的变量和属性名称
  • sourceRoot:所有sources相对的根目录

以上是生成 source map 文件时的标准版本,除了某些不生成 source map 文件的配置,其它都是以类似这种方式来设置映射关系的。

不生成 source map 文件

也有可能存在不需要 source map 文件的情况,有两种方式来配置 devtool,使之不不生成 source map 文件。

  • false:不使用 source map
  • none:mode 为 production 的默认值(没有定义 devtool 时)

这两种方式不会生成 bundle.js.map 文件,也不会在 bundle.js 引入 bundle.js.map 。

内联 source-map

除了直接生成 source map 文件,还可以将 source map 内容直接内联到编译后的 bundle.js 中,有三种方式来配置 devtool。

  • eval:development 模式下的默认值(没有定义 devtool 时),通过 eval 函数来执行文件内容,并在最后增加指向该内容所在的源文件地址
  • eval-source-map:生成的 source map 以 base64 编码的形式添加到 eval 函数中
  • inline-source-map:生成的 source map 以 base64 编码放置在打包后文件的最后面

eval

当 devtool 设置为 eval 时,在编译的 bundle.js 文件中,使用 eval 执行文件内容,并通过 //# sourceURL= 指向源文件地址。

此时可以获取到报错的文件、行、列,但看到的代码与源码会有一点不同,增加了 webpack 处理的部分。

eval-source-map

当 devtool 设置为 eval-source-map 时,文件内容通过 eval 函数执行,source map 通过base64编码后添加到了eval函数中。

此时通过控制台可以看到具体源代码,报错提醒具体到行与列。

inline-source-map

当 devtool 设置为 inline-source-map 时,source map 通过base64编码后添加到了文件最末尾处。

此时通过控制台可以看到具体源代码,报错提醒也具体到行与列。

因为 source map 会占据较大空间,将 source map 内联到 bundle.js 文件中,会使打包后文件体积变大。

报错精确到行

以上的报错信息都是精确到"列"的,提示具体哪个字段报错,而精确到"行"的话,只会告知这一行中有错误。

只精确到行,编译速度会稍快一点,有两种方式设置 devtool,这两种文件都会生成 source map 文件,也就是 bunlde.js.map。

  • cheap-source-map:只精确到行,对于有loader的情况,会不够准确。
  • cheap-module-source-map:只精确到行,可以很好的处理有loader的情况。

为了方便演示,将普通函数改成箭头函数。

可以看到,两者都是精确到"列"的,"cheap-source-map" 定位到的代码和实际的源码有些出入,并且行列顺序也有点不同,但"cheap-module-source-map" 就与源码完全一致。

不显示源码

有没有方法既生成 sourcemap,又不会显示源代码呢?webpack 也提供了两种 devtool 的配置。

  • hidden-source-map:与 devtool 定义成 source-map 一样都会生成 source map 文件,只是在打包后文件 bundle.js 中,没有对 source-map 的引用,如果手动加入,也是会生效的。
  • nosources-source-map:会生成source map,但是生成的source map只有错误信息的提示,不会生成源代码文件, 会在控制台告诉错误的内容及文件,但是点击文件名的时候看不到源码

hidden-source-map

没有引入 source map,在报错信息处也就不会指向源码

nosources-source-map

此时会生成 source map 文件,打包后的 bundle.js 也会引入map文件,也可以看到报错内容所在文件,但无法获取源码。

组合规则

通过表格总结一下上面所提到的 source map

理解这些 source map 之后,剩余的组合也可以推导出,比如

  • eval-cheap-module-source-map:不会生成 source map 文件,而是将 source map 以 base64 编码的形式添加到eval函数中,不会精确到列,只精确到列,且

    存在loader时,可准确定位源码
  • inline-nosources-source-map:不生成 source map 文件,将 source map 以base 64 编码的形式添加到编译后文件的底部,不会展示源码。

但以上这些也不能随意的组合,要遵循以下规则

  • inline-|hidden-|eval:三个值时三选一,可不选
  • nosources:可选值
  • cheap可选值,并且可以跟随module的值

总结起来如下

[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

在开发、测试、生产阶段,也有一些推荐

  • 开发阶段:source-map(vue脚手架默认值)或者 cheap-module-source-map(react脚手架默认值)
  • 测试阶段:source-map 或者 cheap-module-source-map,可快速定位问题
  • 发布阶段:false、none(即不写)

source map 可以帮助我们在开发、测试阶段更好的定位问题,正确的使用能够提升效率。

以上就是关于 source map 的详细介绍,更多有关webpack的内容可以参考我其它的博文,持续更新中~

26种source-map看花了眼?别急,理解这几个全弄懂的更多相关文章

  1. source map 的原理探究

    线上产品代码一般是编译过的,前端的编译处理过程包括不限于 转译器/Transpilers (Babel, Traceur) 编译器/Compilers (Closure Compiler, TypeS ...

  2. 源映射(Source Map)详解

    一.什么是源映射 为了提高性能,很多站点都会先压缩 JavaScript 代码然后上线, 但如果代码运行时出现错误,浏览器只会显示在已压缩的代码中的位置,很难确定真正的源码错误位置. 这时源映射就登场 ...

  3. JavaScript Source Map 详解

    源码地址: http://www.ruanyifeng.com/blog/2013/01/javascript_source_map.html 上周,jQuery 1.9发布. 这是2.0版之前的最后 ...

  4. javascript source map 的使用

    之前发现VS.NET会为压缩的js文添加一个与文件名同名的.map文件,一直没有搞懂他是用来做什么的,直接删除掉运行时浏览器又会报错,后来google了一直才真正搞懂了这个小小的map文件背后的巨大意 ...

  5. 【转】webpack中关于source map的配置

    Webpack中sourcemap的配置 sourcemap是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术.尤其是如今前端开发中大部分的代码都经过编译,打包等工程化转换 ...

  6. Javascript 如何生成Less和Js的Source map

    为什么有Source map CSS和JS脚本正变得越来越复杂,为了解决网络瓶颈,大部分源代码都需要经过编译.合并.压缩才能运用到实际环境中.为了减少网络资源占用,源码一般都会经过以下方式处理: 使用 ...

  7. Fundebug微信小程序BUG监控服务支持Source Map

    摘要: 自动还原真实出错位置,快速修复BUG. Source Map功能 微信小程序的Source Map功能目前只在 iOS 6.7.2 及以上版本支持. 微信小程序在打包时,会将所有 js 代码打 ...

  8. Source Map调试压缩后代码

    在前端开发过程中,无论是样式还是脚本,运行时的文件可能是压缩后的,那这个时候调试起来就很麻烦. 这个时候,可以使用Source Map文件来优化调试,Source Map是一个信息文件,里面储存着原代 ...

  9. java source map

    Chrome 更新后出现了 jquery.min.map 404  (Not Found) 的信息 这个到底是什么东西?查询了一下,得到了以下资料 JQuery 官方解释 摘录一下內容 从 jQuer ...

  10. Source Map入门教程

    部署前端之前,开发者通常会对代码进行打包压缩,这样可以减少代码大小,从而有效提高访问速度.然而,压缩代码的报错信息是很难Debug的,因为它的行号和列号已经失真.这时就需要Source Map来还原真 ...

随机推荐

  1. css3 flex弹性布局详解

    一.flexbox弹性盒子 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便.完整.响应式地实现各种页面布局.目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这 ...

  2. 基于APM模式的异步实现及跨线程操作窗体或控件方法的实现示例

    最近在一家某电力外派公司开发相关于GIS的功能,在实现代码的过程中出现了一些常见的问题比如: 1.跨线程执行窗体或控件操作(直接使用委拖) 2.异步模式执行某长时间耗时方法 经过一系列摸索可算找到解决 ...

  3. Docker compose单机编排工具

    Docker compose单机编排工具 目录 Docker compose单机编排工具 docker-compose介绍 Docker Compose使用的三步: docker-compose安装部 ...

  4. python使用docxtpl生成word模板

    python-docxtpl包简单使用和实战,Python处理word,docx文件. 最近需要处理一些爬虫得到的数据来进行一些自动化报告的操作,因为需要生成的是word的报告,所以估选用docxtp ...

  5. 2022-05-20:给定一个正数数组arr,长度为N,依次代表N个任务的难度,给定一个正数k, 你只能从0任务开始,依次处理到N-1号任务结束,就是一定要从左往右处理任务, 只不过,难度差距绝对值不

    2022-05-20:给定一个正数数组arr,长度为N,依次代表N个任务的难度,给定一个正数k, 你只能从0任务开始,依次处理到N-1号任务结束,就是一定要从左往右处理任务, 只不过,难度差距绝对值不 ...

  6. 2021-04-18:给定一个二维数组matrix,里面的值不是1就是0,上、下、左、右相邻的1认为是一片岛,返回matrix中岛的数量。

    2021-04-18:给定一个二维数组matrix,里面的值不是1就是0,上.下.左.右相邻的1认为是一片岛,返回matrix中岛的数量. 福大大 答案2021-04-18: 并查集. 代码用gola ...

  7. linux ssh远程登录

    目录 一.ssh概念 二.配置文件 三.ssh组成结构 四.远程控制过程 五.远程复制 六.配置密钥 七.wraooers防火墙 一.ssh概念 ssh:一种安全通道协议 功能:1.实现字符界面远程登 ...

  8. Python数据类型 - 元祖

    介绍 元祖和列表都是有序数列,列表是用 [ ],元祖使用() 元祖不同的地方在于创建后不能修改   注意:当元祖中只有一个元素的时候,要加上逗号(一个括号会被当成运算符使用) 比如: (123, ) ...

  9. 提高生产力的最佳免费开源终端:WindTerm

    哈喽,大家好!我是程序视点的小二哥! 前言 自从当上程序员以来使用频率最多的不是vscode,也不是github,而是终端!!! 小师妹使用过很多的终端工具,什么Tabby,Putty,Wrap等等, ...

  10. delving into deep imbalanced regression翻译

    非对照翻译,有所简略.翻译不对,尽情谅解,可留言 作者解释 and paper 笔记 Abstract   Real-world data often exhibit imbalanced distr ...