sourceMap的作用
通常,js代码出错,控制台会提示第几行第几列代码出错。但是webpack
打包压缩后的代码,都被压缩到了一行,变量也变成了a,b,c,d。代码出错,控制台就没法正确的提示错误位置。
sourceMap
就可以解决这个问题。sourceMap
就是一个信息文件,里面储存着打包前的位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。具体如何编码,可以看下阮一峰的文章。
有了它,出错的时候,浏览器控制台将直接显示原始代码出错的位置,而不是转换后的代码,点击出错信息将直接跳转到原始代码位置。
sourceMap的调试
- Console直接点击错误提示跳转到源码(如上图所示)
一般浏览器会默认开启sourceMap
调试,如果控制台不能显示源码错误位置,则需要打开配置。
打开浏览器的这个配置后,控制台的Console
面板的错误提示,直接点击就会跳转到对应的源文件出错位置。
- Sources面板找到源文件,进行断点调试
如果没Console
没报错,但是页面显示不正确。可以点击控制台的Sources
面板,源文件都在 webpack://
目录下,或者直接搜索文件,打开源文件后进行断点调试。
按需加载的路由,只有页面加载了,源文件才会在这个目录下显示。
webpack配置
vue-cli3的vue.config.js文件:
module.exports = {
productionSourceMap: false, //默认是true
}
打包后的文件:
对于打包后的sourceMap
,webpack提供多种类型的配置。
其中,开发环境使用:
- eval:会把每个模块封装到
eval
里包裹起来执行,并且会在末尾追加map
文件的地址。map
文件映射到转换后的代码(可执行的js文件),而不是映射到原始代码(vue文件),所以不能正确的显示错误行数。
-
eval-source-map: 和
eval
类似,为每个模块生成原始的sourceMap
,map
文件会以dataURL
的形式添加到js中(类似于图片的base64形式)。原始的sourceMap
可以正确提示错误行数。 -
eval-cheap-source-map: 跟
eval-source-map
相同,唯一不同的就是增加了cheap
,cheap
是指忽略了列信息(绝大部分时候列信息对于错误提示没啥用,只需要提示行数就行)。 -
cheap-module-eval-source-map: 与
eval-cheap-source-map
相同,但是包含了不同loader
模块之间的sourceMap
。例如借助babel
编译ES6
,如果生成不包含loader
的sourcemap
,此时debug
到的将是编译后的代码,而非原始代码。
生产环境使用:
- source-map:
map
文件包含完整的原始代码,但是打包会很慢。打包后的js
最后一行是map
文件地址的注释
-
hidden-source-map:与
sourceMap
相同,也生成map文件,但是打包后的js
最后没有map
文件地址的引用。浏览器不会主动去请求map
文件,一般用于网站错误分析,需要让错误分析工具按名称匹配到map
文件。 -
nosources-source-map:生成的
map
文件不包含源码,但是会正确提示错误的行数。另外项目的目录结构和文件名称会暴露在Sources
面板
特定环境用(针对一些第三方工具,用的很少,暂不详细讨论):
- inline-source-map
- inline-cheap-source-map
- inline-cheap-module-source-map
- cheap-source-map
- cheap-module-source-map
其实就是inline
,cheap
,module
,source-map
的自由组合。
- inline 是以
dateURL
的形式添加map
,不额外生成map
文件 - cheap 是没有列信息
- module 是包含了
loader
的sourcemap
- source-map 则是映射到源文件
不同的参数,生成的sourceMap
不同,打包速度、体积、错误提示的效果也不同。而vue-cli3
帮我们预选了一种模式:
开发环境,配置文件位置:node_modules\\@vue\cli-service\lib\config\dev.js
,第5行
生产环境,配置文件位置: \node_modules\\@vue\cli-service\lib\config\prod.js
,第11行
另外:css
同样有sourceMap
,不过vue-cli3是默认关闭的:
module.exports = {
css: {
sourceMap: false, //默认false
}
}
sourceMap的安全问题
事情都是具有两面性的,方便调试的同时,也将源码暴露在控制台,可能会导致代码泄露的安全问题。
虽然说前端代码是公开的,但是代码的压缩混淆也一定程度上提高了安全性。
代码泄露可能导致的问题:
- 代码被抄袭
场景:给A客户写了一个地图功能,A客户展示给B客户,B客户想要写地图,但是不会,查看源码后,抄走了地图功能
- 业务流失
场景:竞争对手拿到了源码,挑出其中的漏洞或者缺陷,大肆宣传。或者直接写一份后台,成本少,价格低导致业务被抢走
- 系统被攻击
场景:由于项目急,鉴权是通过前端动态生成路由控制的,后台没做判断,导致修改源码后,可以获得更多的权限(数据被删除)
例如常见的视频播放网站,如果不加密,直接一个<video>
标签,那么就很容易被人拿到视频资源,自己的会员业务也会损失。
sourceMap的处理
如果无特殊需求,生产环境是需要关闭这个选项的,vue-cli3
直接配置productionSourceMap: false
即可。或者不关闭但是在测试环境迁移到正式环境时删掉map
文件。也可以通过服务器配置,特殊账号(调试专用)能访问到map文件,其他用户则不行。
如果需要控制台能正确提示报错的位置而不暴露源码,推荐用nosources-source-map
模式,但是这个模式会暴露源码的目录结构与文件命名。一般测试环境用这个比较好,QA测试出来的问题能正确提示错误,即使运维忘了删除sourceMap
文件,也不会暴露源码。
// vue.config.js
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {//只修改生产环境配置
return {
devtool: 'nosources-source-map',
};
}
}
}
补充:本地sourceMap调试
- 办法1 : 网络拦截
webpack
打包仍然生成sourceMap
,但是将map文件挑出放到本地服务器,将不含有map文件的部署到服务器,借助第三方软件(例如fiddler),将浏览器对map
文件的请求拦截到本地服务器,就可以实现本地sourceMap
调试。
- 办法2 : 修改webpack打包,测试环境不放map文件,修改sourceMap的引用到本地服务器
可行性:本地调试专用,由于测试环境和本机属于同一个局域网,所以测试环境可以请求到本地服务器上的sourceMap
文件,部署之后,客户访问则不能访问到本机的局域网IP,也就无法拿到sourceMap
文件。
缺点:其他人打包需要修改电脑IP和本地服务器文件地址,无法直接复用,优点是绝对安全。或者可以提供另一台专门放map
文件的服务器,打包之后自动上传map文件到这个服务器。
借助SourceMapDevToolPlugin
修改打包后的文件对map
文件的引用地址,同时借助filemanager-webpack-plugin
将map
文件移到到本地服务器上。代码如下(vue.config.js
):
const webpack = require('webpack')
const FileManagerPlugin = require('filemanager-webpack-plugin');
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
return {
devtool: false, // 注意SourceMapDevToolPlugin和devtool不可共存
plugins: [
new webpack.SourceMapDevToolPlugin({
append: '\n//# sourceMappingURL=http://192.168.23.230/sourceMap/[url]', // 192.168.23.230是本机局域网IP
filename: '[file].map',
}),
new FileManagerPlugin({
onEnd: {
copy: [{
source: './dist/js/*.map',
destination: 'D:/xampp/htdocs/sourceMap', // D:/xampp/htdocs/是本地服务器的文件地址
}],
delete: ['./dist/js/*.map'],
archive: [{ //顺便把网站文件压缩一下
source: './dist',
destination: './dist/dist.zip',
}]
}
})
]
};
}
}
}
这个插件主要是实现了对sourceMap
的更精细控制,比如打包之后的位置,以及修改js/css
文件最后面对sourceMap
的引用地址。 这里主要用到修改sourceMap
引用地址的功能。
使用这个必须关闭
devtool
这个插件的主要功能是打包之后文件的移动,删除,拷贝,压缩等功能,使用之前需要先安装: npm install filemanager-webpack-plugin --save-dev
注意: 这个插件有bug,移动操作不支持模糊匹配,只能改成复制+删除
最后
有什么问题,欢迎指出。
今天的文章【webpack】你所不知道的sourceMap分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22378.html