文章目录
- 一、基本概念
- 二、output.sourceMapFilename
- 三、SourceMapDevToolPlugin
一、基本概念
Source Map 本身是一种文件,它提供了原始文件与编译后的文件之间的映射规则,使得开发者能够调试原始代码,帮助开发人员进行调试和排查。在生成的SourceMap中可以直接定位到源码,原始文件对应的SourceMap地址通常在最后一行。
//# sourceMappingURL=bundle.js.map
标记了该文件的 Source Map 地址,浏览器才可以正确的找到源代码的位置。webpack 在构建过程中如果devtool不为false,则会自动生成 SourceMap。它会遍历源代码文件,并为每个源文件创建一个单独的 SourceMap 文件。SourceMap 文件的名称通常以 .map 为后缀,并与相应的已编译文件存储在同一目录中。
现在的需求是将所有的SourceMap分离出来,单独存在同一个文件夹中,实现如下:
二、output.sourceMapFilename
config.output.sourceMapFilename = 'sourcemaps/[base].map'
这里的sourceMapFilename可以自定义路径和名称,但是需要注意,这里的路径只能写相对路径,不能写绝对路径!!
这个名称官方提供的是[file],我写的是[base],这些都是webpack里自带的可以直接使用的模板字符串
常见的有以下:
示例如下:
关于为什么我使用[base].map,而不是使用[name].js.map,是因为我有一个文件既有css也有js,都有映射,那么直接命名为[name].js.map会产生js和css的冲突,无法生成同名的map文件。
分离成功后,可以看到我的文件里只有map,并且是在当前js同级目录下有sourcemaps文件夹
但是有个问题是,config.output.sourceMapFilename = 'sourcemaps/[base].map’只能在当前js文件夹下引用,比如我设置config.output.sourceMapFilename ='../sourcemaps/[base].map'
,虽然可以在../sourcemaps
文件夹下生成map文件,但是原js文件的最后一行还是//# sourceMappingURL=sourcemaps/bundle.js.map
,并不是//# sourceMappingURL=../sourcemaps/bundle.js.map
,也就是在路径引用下无法设置其它目录。
仔细一看:确实sourceMapFilename只设置了map文件的路径,并没有设置sourceMapUrl的路径,它的map文件只会默认定位到当前目录下进行链接。
所以要对sourcemap进行更详细的设置,需要使用SourceMapDevToolPlugin
三、SourceMapDevToolPlugin
该插件是webpack里自带的,不需要额外下载
使用方法如下,注意filename
和append
的设置,分别对应了sourcemap生成的文件目录和原js最后一行链接的目录。这里的路径也只能写相对路径,不能写绝对路径
并且config.devtool必须设置为false
,因为devtool里配置sourcemap会内部默认调用SourceMapDevToolPlugin插件,如果不设置为false则调用了该插件2次:
const webpack = require('webpack');
config.devtool = false // 必须设置
config.plugins = [
new webpack.SourceMapDevToolPlugin({
filename: '../../sourcemaps/[file].map', // 指定 sourcemap 输出到上一级目录的 "sourcemaps/" 文件夹
append: '\n//# sourceMappingURL=../../sourcemaps/[file].map', // 手动指定上一级目录的 source map 引用路径
moduleFilenameTemplate: 'webpack:///[resource-path]', // source map 中模块文件的路径
})
];
重新执行build后可以看到在原js中可以更改链接目录了,不再是默认的当前路径下了。
同时我们启动软件看到源码资源也可以看到了,之前如果只设置output.sourceMapFilename并且目录不在原js文件夹下的话,链接资源是无法看到的。
这样把sourcemap全部分离后,只要不部署该文件夹,那么在生产环境将看不到源码,防止源码被获取。