今天在调试网站时,发现 Chrome 的开发者工具的面板切换到源代码/来源之后,会把项目名和所有组件源码都显示出来了?而且各种入口文件、API接口文件的注释等等全部都毫无保留地能随意查看?!

这是什么天大的玩笑,这与把别人内裤扒了有什么区别?

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

分析问题

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

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

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

什么是SourceMap?[4]

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

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

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

//# sourceMappingURL=85.2018f4f0.js.map

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

解决方法

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

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

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 脚手架版本号是:

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

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

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

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

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

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

module.exports = {
    bulid: {
        productionSourceMap: false
    }
}

总结

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

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

(adsbygoogle = window.adsbygoogle || []).push({});