首先我们需要知道source map
是什么?顾名思义资源映射
,它做的就是维护打包处理后的代码与源代码之间的映射关系,只有映射的精确性则取决于webpack
的配置项devtool
,其决定了项目打包时是否以及如何生成source map
,而生成的source map
不同决定了构建产物的体积
和构建以及重新构建的速度
的不同。具体配置项可选值可参考webpack文档这里不一一列举。
代码语言:javascript复制首先可以看一下
webpack
的源码,对应处理逻辑仅有20行:https://github.com/webpack/webpack/blob/226a77c9d46b33da5b78b1c76a10384c78132074/lib/WebpackOptionsApply.js#L188
if (options.devtool) {
if (options.devtool.includes("source-map")) {
const hidden = options.devtool.includes("hidden");
const inline = options.devtool.includes("inline");
const evalWrapped = options.devtool.includes("eval");
const cheap = options.devtool.includes("cheap");
const moduleMaps = options.devtool.includes("module");
const noSources = options.devtool.includes("nosources");
const Plugin = evalWrapped
? require("./EvalSourceMapDevToolPlugin")
: require("./SourceMapDevToolPlugin");
new Plugin({
filename: inline ? null : options.output.sourceMapFilename,
moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
fallbackModuleFilenameTemplate:
options.output.devtoolFallbackModuleFilenameTemplate,
append: hidden ? false : undefined,
module: moduleMaps ? true : cheap ? false : true,
columns: cheap ? false : true,
noSources: noSources,
namespace: options.output.devtoolNamespace
}).apply(compiler);
} else if (options.devtool.includes("eval")) {
const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
new EvalDevToolModulePlugin({
moduleFilenameTemplate: options.output.devtoolModuleFilenameTemplate,
namespace: options.output.devtoolNamespace
}).apply(compiler);
}
}
从上述代码可看出,会首先判断devtool
的值是否包含source-map
或者eval
(注意是包含判断,并不是相等判断),也就是说只要不包含两者之一,其实是什么值都无所谓,结果都一样。由此针对devtool
的不同配置项,可做这样的拆分处理:
任何不包含
source-map
或者eval
:
浏览器中不会有任何代码映射关系可寻,只能定位到打包后代码的位置。
不包含
source-map
且包含eval
:
会将打包后每个模块的代码使用 eval() 执行,且在模块最后注释有sourceURL=xxx/xx/xx/xx.js.map
类似路径,用于定位,能够定位到源码文件路径,但是代码为build
后生成的代码。具体逻辑可以看这里:传送门
包含
source-map
:
包含source-map
决定了将以更为细粒度的方式来展示代码映射的详情。
其中有根据是否包含额外字段做了不同处理:
eval
: build后的模块代码是否使用eval
执行hidden
: 是否不需要在模块末尾追加source map url(sourceMappingURL), 决定了是否可以定位到build之前的源码文件,该字段存在的话只能定位到build以后的chunk文件中对应模块及所在行。inline
: 是否使用options.output.sourceMapFilename
作为source map
文件的名称比如://# sourceMappingURL=main.chunk.js.map
,包含该字段则sourceMappingURL
值直接为base64数据,不包含则为对应map文件名称。module
: 包含 loader 直接转换的 sourcemap(比如 jsx to js ,babel 的 sourcemap),否则无法定义源文件cheap
: 该字段影响两个地方,一个当不包含module
字段且不包含cheap
时与包含module
控制功能生效;另一个是决定了定位时是否映射定位到对应列,包含则不映射定位。nosources
: 该字段存在则意味着map
文件中不存在对应源码内容
从devtool
的处理代码中可以看出,实际是根据配置项依赖EvalDevToolModulePlugin
或者SourceMapDevToolPlugin
插件生成source map
的,因此,可以通过将devtool
设置成false
,然后在webpack.plugins
中通过自定义的配置来完成对应工作,来达到更为细致的控制。
比如可以通过exclude
字段来排除一些不需要生成source map
的模块:
devtool: false,
plugins: [
new webpack.EvalSourceMapDevToolPlugin({
exclude: /node_modules/,
module: true,
columns: false
})
],
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/185426.html原文链接:https://javaforall.cn