SourceMap源码映射详细讲解 您所在的位置:网站首页 source-map-js SourceMap源码映射详细讲解

SourceMap源码映射详细讲解

2024-07-04 16:38| 来源: 网络整理| 查看: 265

SourceMap源码映射详细讲解

前端工程打包后代码会跟项目源码不一致,当代码运行出错时控制台上定位出错代码的位置跟项目源码上不对应。这时候我们很难定位错误代码的位置。SourceMap的用途是可以将转换后的代码映射回源码,如果设置了js文件对应的map资源,那么就可以在控制台进行调试时直接定位到源码位置。

SourceMap生成方式

前端的构建工具很多,文章只举例两个常用的:vite和webpack

vite生成SourceMap

在vite在文档介绍中可以看到直接设置build.sourcemap配置即可。

sourcemap可配置的值类型为(boolean, ‘inline’, ‘hidden’)几种:

boolean: true | false 默认为false,不生成map文件。当设置成true时,会生成单独的map文件,并且在对应的bundle文件中生成相应注释指明map文件。

请添加图片描述

inline 请添加图片描述

将source map作为一个data url附加在输出文件中。

hidden

跟true类似,生成一个map文件,但是在bundle问价中并不会生成注释。

webpack生成SourceMap

在webpack中也只需要通过设置devtool配置即可。值有以下多种:

eval

会生成被eval函数包裹的模块内容,其中添加了注释用来标识源文件位置(sourceURL用来指定文件名) 请添加图片描述

这种方式因为不需要生成map文件,所以很快,只需要提供对应的源文件地址就可以就进行映射。但是缺少了很多映射信息(行、列等),同时eval方法因为安全问题也不建议使用。

source-map

生成一个map文件,并在bundle文件中添加注释指向map文件。

cheap

跟source-map类似,不过生成的map文件不会生成源码的列信息(只会映射到源码的行)跟loader中的sourcemap。

通常在定义错误时,只需要关注到行就可以知道错误原因,列信息不是非常必要,这样在打包时也能更快。不过对于需要经过多loader处理的文件,由于不会生成loader相关的sourcemap,可能会导致映射信息不精确。

module

生成的sourcemap包含了loader相关的sourcemap信息。

inline

和vite的inline配置一样,直接将生成的map文件内容作为data url添加到bundle文件中,不单独生成一个map文件。

hidden

也和vite的hidden配置一样。

nosources

生成的map文件中不包含sourceContent字段(sourceContent和sources字段都可以映射源码),使得map文件体积可以更小。

除了上述几个外,webpack还支持组合方式,详情可以[文档中的devtool配置]https://www.webpackjs.com/configuration/devtool/#devtool

sourceMap 使用

对于生成的map文件,我们需要解析工具将源代码跟sourcemap进行映射。

浏览器

在目前的浏览器中大多都默认开启了sourcemap映射功能。

在浏览器中按F12进入到开发者工具可以看到: 请添加图片描述

如果js文件中有sourcemap注释,可以映射到源码中。

没有配置sourcemap时: 请添加图片描述 请添加图片描述

配置了sourcemap: 请添加图片描述 请添加图片描述

手动映射

对于生产环境,为了安全一般都不会在浏览器中进行映射。但是为了能监控定位到错误,我们可以使用手动隐射的方式。

安装source-map

npm i source-map -D

启动一个node服务用来接受错误信息并进行记录:

const { SourceMapConsumer } = require('source-map'); const fs = require('fs'); const rawSourceMap = fs.readFileSync(__dirname + '/dist/main.38f7f9c4.js.map', 'utf-8'); console.log(rawSourceMap) originalPosition('main.38f7f9c4.js:733') function originalPosition(info) { const [bundleName, line, column] = info.split(':'); SourceMapConsumer.with(rawSourceMap, null, (consumer) => { const originalPosition = consumer.originalPositionFor({ line: parseInt(line), column: parseInt(column) }) console.log(originalPosition); }) }

请添加图片描述

现在也有许多监控平台(例如sentry)可以实现源码映射,不需要我们手动映射。

SourceMap文件格式

使用webpack打包举例来看一个map文件里都有什么字段。

// index.js function log() { for(let i = 0; i for(let o=0;o


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有