Vue 项目交付第三方开发,如何隐藏核心 JS 源码?
2026/6/12 7:52:58 网站建设 项目流程

前言

最近遇到了一个实际需求:

整个 Vue/Vite 项目需要交给第三方继续开发,但是部分核心 JS 文件(例如无人机轨迹算法、设备通信协议、加密逻辑等)不希望暴露源码。

要求如下:

✓ 不影响原有项目运行 ✓ npm run dev 正常开发 ✓ npm run build 正常打包 ✓ 原有 import 路径不变 ✓ 不需要修改大量业务代码 ✓ 核心实现无法直接查看

一开始尝试过:

  • javascript-obfuscator 直接混淆源码;
  • Vite 打包阶段混淆;
  • 运行时动态替换源码;

但都存在各种问题,例如:

❌ import/export 被破坏 ❌ 路径解析异常 ❌ 开发环境无法运行 ❌ 需要修改大量引用代码

最终采用了一套比较稳妥的方案。


最终方案

将核心文件拆分成三部分:

src/utils/ ├── identifyPos.js ← 对外代理文件 ├── identifyPos.min.js ← 混淆后的文件 └── identifyPos.source.js ← 原始源码(自己保存)

项目中原来的引用方式:

import identifyPos from '@/utils/identifyPos'

保持完全不变。


实现原理

代理文件:

export { default } from './identifyPos.min' export * from './identifyPos.min'

这样:

业务代码 ↓ identifyPos.js ↓ identifyPos.min.js

开发人员只能看到混淆后的实现。


安装依赖

npm install javascript-obfuscator terser -D

编写一键保护脚本

创建:

scripts/protect.js

代码如下:

const fs = require('fs'); const path = require('path'); const terser = require('terser'); const JavaScriptObfuscator = require('javascript-obfuscator'); // 需要保护的文件 const files = [ 'js/identifyPos.js', ]; async function build(filePath) { const absolutePath = path.resolve(filePath); if (!fs.existsSync(absolutePath)) { console.error(`文件不存在:${filePath}`); return; } const dir = path.dirname(absolutePath); const ext = path.extname(absolutePath); const fileName = path.basename(absolutePath, ext); const sourcePath = path.join(dir, `${fileName}.source${ext}`); const minPath = path.join(dir, `${fileName}.min${ext}`); // 第一次执行时自动备份源码 if (!fs.existsSync(sourcePath)) { fs.copyFileSync(absolutePath, sourcePath); console.log(`已备份源码:${sourcePath}`); } // 永远从 source 文件生成 const sourceCode = fs.readFileSync(sourcePath, 'utf8'); // 压缩 const minified = await terser.minify(sourceCode, { module: true, compress: { drop_console: false, drop_debugger: true, }, mangle: true, }); if (minified.error) { throw minified.error; } // 混淆 const obfuscated = JavaScriptObfuscator.obfuscate(minified.code, { compact: true, identifierNamesGenerator: 'hexadecimal', stringArray: true, rotateStringArray: true, stringArrayThreshold: 0.75, renameGlobals: false, controlFlowFlattening: false, deadCodeInjection: false, selfDefending: false, }).getObfuscatedCode(); // 输出 min 文件 fs.writeFileSync(minPath, obfuscated); // 生成代理文件 const proxyCode = ` export { default } from './${fileName}.min'; export * from './${fileName}.min'; `.trim(); fs.writeFileSync(absolutePath, proxyCode); console.log(`保护完成:${filePath}`); } (async () => { try { for (const file of files) { await build(file); } console.log('\n全部完成'); } catch (e) { console.error(e); } })();

package.json 配置

{ "scripts": { "protect": "node scripts/protect.js" } }

使用方式

第一次执行:

npm run protect

目录会变成:

src/utils/ ├── identifyPos.js ├── identifyPos.min.js └── identifyPos.source.js

以后修改核心逻辑时:

只修改:

identifyPos.source.js

然后重新执行:

npm run protect

即可重新生成混淆文件。


最终交付

交付项目时:

保留:

identifyPos.js identifyPos.min.js

删除:

identifyPos.source.js

这样:

✓ 第三方正常开发 ✓ 项目正常运行 ✓ 原有代码零修改 ✓ import 路径保持不变 ✓ 核心源码得到保护

注意事项

该方案适用于:

✓ 普通 JS 工具库 ✓ 算法实现 ✓ 数据处理逻辑 ✓ 加密逻辑 ✓ 协议解析

不建议用于:

✗ Vue 单文件组件(.vue) ✗ 大型业务控制器 ✗ 依赖复杂的页面逻辑

对于复杂业务文件,更推荐将核心算法抽离成独立模块后再进行保护。


总结

前端源码无法做到绝对隐藏,但可以有效提高逆向成本。

对于需要交付源码、又希望保护部分核心实现的 Vue/Vit 项目来说:

源码备份 ↓ 压缩 + 混淆 ↓ 生成 .min.js ↓ 代理转发 ↓ 删除 source.js

是一种改动最小、兼容性最好、实际项目中可落地的方案。

如果你也有类似需求,不妨试试这套方法。

(如果打包报错,试试把package.json中 {"type": "module"}删除再运行)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询