乐趣区

关于前端:26种sourcemap看花了眼别急理解这几个全弄懂

上一篇 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-[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 的内容能够参考我其它的博文,继续更新中~

退出移动版