1. 什么是sourceMap
sourceMap 是一个信息文件, 维护着代码转换编译前后的映射关系;
2. devtool : 选项控制是否生成,以及如何生成 source map source Map对应的模式
1)inline
2) cheap
3)module
4) eval
5) source-map
3-21 加载 Source Map · 深入浅出 Webpack
然后根据上述几种 进行组合 验证 devtool 名称时, 我们期望使用某种模式, 注意不要混淆 devtool 字符串的顺序, 模式是: [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
.
见图:
如果是eval / inline 模式 不会生成单独.map 文件, 会以dataUrl 的形式 存在打包文件后的结尾
source-map 会生成单独的.map 文件
3 . 浏览器中的表现形式
如果加载的js 的文件 结尾有#sourceMap(eval) 或者 #sourceMapUrl(source-map)(比如如果是hidden-source-map 这种打包出来的js 文件 就没有 ,所以不会自动关联), 可以右键 选择 添加源映射
解析到#sourceMap 或者 #sourceMapUrl 的时候 会自动去关联到(hidden-xxx 的除外)
4. 使用了压缩插件 uglifyjs-webpack-plugin或者terser-webpack-plugin 如果想使用source-map 如果再设置下sourceMap: true, 因为压缩插件里面 默认 sourceMap: false
chainWebpack(config) {
config
.devtool('hidden-source-map')
.end()
config
.when(process.env.NODE_ENV === 'production',
config => {
config.optimization.minimizer('js').use(
new uglifyjs({
sourceMap: true
uglifyOptions: {
warnings: false,
compress: {
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log', 'console.warn']
}
}
})
)
})
}
5. 生产环境下一般使用source-map 或者 hidden-source-map 模式 , 具体可以参考官网推荐, 生成的map 文件 不要和业务代码部署到一起, 防止被别人看到, 可以单独进行部署,实现私有化, 只能特定网络下访问, 比如部署到公司内网服务器, 此时就要修改js 文件结尾的#sourceMapUrl 链接地址
//# sourceMappingURL=app.fea6fcf0.js.map 修改为
//# sourceMappingURL=http: xxxxx:xxxx/app.fea6fcf0.js.map
6. 插件 : 实现了对 source map 生成内容进行更细粒度的控制
| webpack 中文文档
你可以直接使用
SourceMapDevToolPlugin
/EvalSourceMapDevToolPlugin
来替代使用devtool
选项,因为它有更多的选项。切勿同时使用devtool
选项和SourceMapDevToolPlugin
/EvalSourceMapDevToolPlugin
插件。devtool
选项在内部添加过这些插件,所以你最终将应用两次插件。
比如我们要单独部署.map 文件 需要修改map链接的地址, 可以设置这个时候publicPath或者 append 就可以使用插件:
const webpack = require('webpack')
module.exports = {
productionSourceMap: true,
chainWebpack(config) {
config.plugin('SourceMapDevToolPlugin')
.use(webpack.SourceMapDevToolPlugin).tap(args => {
return [{
filename: '[file].map',
publicPath: 'https://exmaple.com/',
// append: "\n//# sourceMappingURL=http://example.com/sourcemap/[url]",
moduleFilenameTemplate: 'source-map'
}]
})
}
}
上述代码打包之后 发现 js文件 结尾会有两个#sourceMapUrl
{return l&&h.REQUIRED&&d(e)&&!n(e,c)&&p(e),e},h=e.exports={REQUIRED:!1,fastKey:f,getWeakData:m,onFreeze:b};i[c]=!0}}]);
//# sourceMappingURL=https://exmaple.com/static/js/chunk-540c250b.99bc351b.js.map
//# sourceMappingURL=chunk-540c250b.99bc351b.js.map
这个就说明 vue-cli4(目前我使用的版本) 中使用了 devtool ,devtool 和SourceMapDevToolPlugin 插件同时存在,所以导致了两个sourceMap指向, SourceMapDevToolPlugin插件是用来替代devtool,
看源码会发现 cli中有多处会根据 productionSourceMap这个布尔值来设置是否使用 devtool ;需要注意的是vue-cli4默认的js 压缩插件 是 terser-webpack-plugin, 如果想生成sourceMap 压缩插件这个属性必须设置true
两处源码如下:
可能你会想直接设置productionSourceMap为false, 这个时候 就会导致 terser-webpack-plugin 插件sourceMap 也会为false, map文件就生成不了, 我们的目标是生成map文件 , 同时去掉自带的devtool 保留SourceMapDevToolPlugin
插件
所以第一种就是设置productionSourceMap为true, 同时在chainWebpack手动设置devtool:false, 覆盖自带的devtool,
const webpack = require('webpack')
module.exports = {
productionSourceMap: true,
chainWebpack(config) {
config.devtool(false).end()
config.plugin('SourceMapDevToolPlugin')
.use(webpack.SourceMapDevToolPlugin).tap(args => {
return [{
filename: '[file].map',
publicPath: 'https://exmaple.com/',
moduleFilenameTemplate: 'source-map'
}]
})
}
}
第二种就是 设置productionSourceMap:false 同时设置压缩插件的sourceMap: true (但是这种不能保证其他插件需不需要设置 ) 所以最好还是选择第一种吧
const webpack = require('webpack')
const terser = require('terser-webpack-plugin')
module.exports = {
productionSourceMap: false,
chainWebpack(config) {
config.plugin('SourceMapDevToolPlugin')
.use(webpack.SourceMapDevToolPlugin).tap(args => {
return [{
filename: '[file].map',
publicPath: 'https://exmaple.com/',
moduleFilenameTemplate: 'source-map'
}]
})
// vue-cli4 这种方式生效
config.optimization.minimizer('terser').tap((args) => {
args[0].sourceMap = true
return args
})
}
}
同样css 也有sourceMap, vue-cli3 默认是关闭的
css: {
sourceMap: true
},
参考:
Devtool | webpack 中文文档
何为SourceMap?讲讲SourceMap食用姿势 - 知乎
https://www.jianshu.com/p/721b0d26e1ea
Webpack devtool source map « Cheng's Blog
Source Maps
深入浅出的webpack构建工具---devTool中SourceMap模式详解(四) - 龙恩0707 - 博客园
Webpack 实战系列一:正确使用 Sourcemap-51CTO.COM
webpack - vue-cli sourcemap私有化部署配置_个人文章 - SegmentFault 思否