AI总结:本篇博客主要讲述了作者在使用webpack打包Vue项目时,如何解决在浏览器开发者工具中显示源代码的问题。作者以诙谐幽默的语言,生动形象地描述了他在开发过程中遇到的问题和解决问题的过程,引人入胜,让人哭笑不得。作者首先发现了问题,然后通过控制台查看源代码,发现项目名和所有组件源码都被显示出来了。这让作者感到非常震惊,因为这直接暴露了源码,对于企业来说,这是一个非常大的安全隐患。因此,作者决定解决这个问题,以保护源代码的安全。

发现问题

最近在开发一个网站,怎么看怎么别扭,就是那种说不出的丑陋。于是我把字体从 微软雅黑 全站换成了华为的鸿蒙字体 HarmonyOS_Regular,啊~瞬间舒服了,果然是设计不够字体来凑。(其实苹果的苹方字体 PingFang SC 也不错,但是我只找到了鸿蒙字体的在线引用链接,好像是 B 站的在线资源哈哈)

正当我在控制台开心地把玩字体相关的 CSS,为我做的这个“英明神武”的决策沾沾自喜之时,将 Chrome 的开发者工具的面板切换到源代码/来源之后傻眼了:卧槽!怎么项目名和所有组件源码都显示出来了?而且各种入口文件、API接口文件的注释等等全部都毫无保留地能随意查看?!

2023-130 (1)

这是什么天大的玩笑,这与把别人内裤扒了有什么区别?还把别人裸照扔到大街上让人观赏,苍天呐,大地啊!

好了,言归正传,这件事绝对不容小觑,这已经不是安全隐患了,这是直接把源码甩别人脸上了,要是在企业里的话,竞争对手脸上都得乐开花。

分析问题

问题重大,话不宜迟,我开始思考为什么会显示源码。

这时我想到了 vue-cli 打包后,会在生成 js 文件的同时,生成很多同名的 .js.map 的文件,这种后缀的文件通常比其对应的 .js 文件体积大,好像是用来作为什么映射原的。

2023-130 (2)

经过求证[1-3],这个 .js.map 文件确实是涉嫌此案件的“罪魁祸首”!

什么是SourceMap?[4]

简单来说,Sourcemap 就是一个信息文件,它里面存储着代码转换前后的对应位置信息,也就是转换压缩后的代码所对应的转换前的源代码位置,是源代码和生产代码的映射, Sourcemap 解决了在打包过程中,代码经过压缩,去空格以及 babel 编译转化后,由于代码之间差异性过大,debug 困难的问题

大家的项目在开发完进行build后,在打包文件夹里除了有js,css,图片等资源,一定还见过 .js.map文件,这种就是sourcemap文件

比如一个经过 webpack 打包生成的 85.2018f4f0.js 文件,在它的最后一行可以看到如下记录:

1
//# sourceMappingURL=85.2018f4f0.js.map

它是什么?它是记录映射转换过后的代码和源代码之间的关系的同名 .js.map 啊,这样浏览器就可以顺藤摸瓜还原出 85.2018f4f0.js 文件打包前的样子了。

解决问题

那既然揪出了内鬼是 webpack 在通风报信,下面就需要好好“惩治”一下它这种行为了,咱们一起把它阉了!

首先要了解你的 vue-cli 脚手架的版本,在 CMD 中输入命令 vue -V ,注意 V 是大写,用于输出 version number:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Usage: vue <command> [options]

Options:
-V, --version output the version number
-h, --help display help for command

Commands:
create [options] <app-name> create a new project powered by vue-cli-service
add [options] <plugin> [pluginOptions] install a plugin and invoke its generator in an already created project
invoke [options] <plugin> [pluginOptions] invoke the generator of a plugin in an already created project
inspect [options] [paths...] inspect the webpack config in a project with vue-cli-service
serve alias of "npm run serve" in the current project
build alias of "npm run build" in the current project
ui [options] start and open the vue-cli ui
init [options] <template> <app-name> generate a project from a remote template (legacy API, requires
@vue/cli-init)
config [options] [value] inspect and modify the config
outdated [options] (experimental) check for outdated vue cli service / plugins
upgrade [options] [plugin-name] (experimental) upgrade vue cli service / plugins
migrate [options] [plugin-name] (experimental) run migrator for an already-installed cli plugin
info print debugging information about your environment
help [command] display help for command

Run vue <command> --help for detailed usage of given command.

比如我的 vue 脚手架版本号是:

1
2
E:\vue2_demo\dist\js>vue -V
@vue/cli 5.0.4

根据官网 Vue CLI 配置参考 所言,需要在配置文件 vue.config.js 中将 productionSourceMap 的值设置为 false,这样就可以不再生成生产环境的 source map,还可以加速生产环境的构建,也就是加快打包速度。参考代码如下(适用于Vue-cli3及以上版本):

1
2
3
4
5
6
7
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: './',
// 生产环境不生成sourcemap
productionSourceMap: false,
})

OK,现在再进行项目的打包 npm run build 重新生成 dist 目录,可以看到 dist/js 目录下已经不再生成 .js.map 文件了:

2023-130 (3)

部署到服务器后打开控制台,也看不到项目源码了:

2023-130 (4)

大功告成!如果还有问题的话,估计是你的 vue 脚手架版本太老了,好像 Vue-cli2 要修改配置的话需要这样添加 vue.config.js 配置:

1
2
3
4
5
module.exports = {
bulid: {
productionSourceMap: false
}
}

危机总结

总之吧,以前没注意过这种事情,或者以前以为只有本地开发的时候才能在控制台看见 webpack 打包前的源码。这次的发现也可能减少了一次未来可能发生的源码泄露事件,也算是因祸得福吧。

但是我可想吐槽一句为什么 SourceMap 这个玩意儿生产环境的默认配置不是关闭的呢,这太危险了吧!


【参考内容】

[1] vue项目控制台调试时显示源码的解决方法

[2] 解决Vue项目F12查看源代码问题

[3] 如何通过浏览器的开发者工具查看经过webpack打包后的Vue组件的源码?

[4] 聊一聊SourceMap - 知乎

[5] Vue-cli4x项目优化实践(关闭productionSourceMap)

[6] Vue CLI 配置参考(productionSourceMap)

[7] 记一次Vue源码泄露

[8] 前端源码泄露

[9] Sourcemap安全问题

[10] 挖洞思路:前端源码泄露漏洞并用source map文件还原