「隐藏」线上环境的sourceMap

245 阅读2分钟

背景

  1. 不少文章介绍,项目打包混淆上线的代码,不能将对应的sourceMap文件一起上传,避免用户获取sourceMap文件从而还原出JS代码。推荐的做法是将sourceMap文件本地保存一份,这样如果线上出现JS报错被一些第三方监控平台检测到,我们可以通过本地的sourceMap文件可以还原定位问题。
  2. 但项目每次发布,保存对应的sourceMap到本地,这种方式非常不太友好,需要手动处理;且有时候本地打包混淆,和线上发布机器的打包混淆,生成的文件hash可能不太一样,对应的sourceMap文件名也会有不同,就会导致文件对应关系有点混乱。

简单解法

这里介绍一个简单的思路。

  1. 打包混淆JS代码的同时,生成sourceMap文件;
  2. 打包完成之后,脚本将所有的sourceMap文件名中,添加一个固定长度的salt字符串;
  3. 将重命名后的sourceMap文件随项目代码一起发布上线。

这样就能实现:外部人员无法知道JS对应的sourceMap,内部人员可以查看并下载sourceMap。

打包时生成sourceMap文件

这个就比较简单了,webpack和vite都能做到,这里不介绍配置了。

重命名sourceMap文件

打包完成之后,运行一个node脚本,该脚本读取项目中的所有sourceMap文件,然后运行重命名程序。

正常的打包命令:

cross-env NODE_ENV=production vite build --mode production 

修改为:

cross-env NODE_ENV=production vite build --mode production && esno ./build/script/postBuild.js

postBuild.js文件的逻辑如下:

// #!/usr/bin/env node
  const SOURCE_MAP_PATH_NAME_SALT = 'cjSPLcrTV99WB'
  const directory = '../dist/assets'
  fs.readdirSync(directory).forEach((file) => {
    if (path.extname(file) === `.map`) {
      const newFile = file.replace(`.map`, `.${SOURCE_MAP_PATH_NAME_SALT}.map`)
      fs.renameSync(path.join(directory, file), path.join(directory, newFile))
    }
  })

其中SOURCE_MAP_PATH_NAME_SALT就是对应的salt字符串,一般只有开发人员才会知道,directory就是对应的项目打包后sourceMap文件所在的目录。

可以看到,正常的一个js文件,对应的sourceMap文件名和js是同名的。 比如:

index.683befbc.js
index.683befbc.js.map

增加的salt字符串之后,变成了

index.683befbc.js
index.683befbc.js.cjSPLcrTV99WB.map

这样外部人员(包括一些默认下载解析sourceMap文件的浏览器)就无从得知sourceMap具体文件名了,因为这个salt只有内部人员才知道。

总结

我们可以将每次打包生成的sourceMap,通过统一在sourceMap文件名中增加一个salt字符串,从而达到了外部人员无从得知具体的sourceMap文件名,而内部人员可以知道。