Vue 项目交付第三方开发,如何隐藏核心 JS 源码?

前言

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

整个 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

代码如下:

javascript 复制代码
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"}删除再运行)

相关推荐
之歆1 小时前
Node.js 与 NPM 包管理完全指南
前端·npm·node.js
小二·1 小时前
Vue 3 组合式 API 进阶实战
前端·javascript·vue.js
12点一刻1 小时前
npx 使用入门教程:是什么、怎么用、和 npm 有什么区别
前端·npm·node.js
console.log('npc')1 小时前
将 Figma 接入 Codex MCP:从 `/plugins` 到本地插件配置的完整教程
前端·人工智能·python·figma·code·codex·mcp
大家的林语冰2 小时前
React 生态大迁徙,脸书源码仓库跑路,核心技术栈全员加盟 React 基金会!
前端·javascript·react.js
Sca_杰2 小时前
速通抖音开放平台API-生活服务商应用
javascript·node.js
AI智图坊2 小时前
亚马逊多站点Listing视觉制作的效率瓶颈与AI解决方案:GPT-Image-2与Nano Banana Pro双模型分析
大数据·前端·数据库·人工智能·自动化·aigc
Rain5092 小时前
1.3. Next.js与Nest.js在AI数据分析中的角色
前端·javascript·人工智能·后端·数据分析·node.js·ai编程
wanghao6664552 小时前
精益方法论:用更少的资源创造更大的价值
大数据·前端·数据库·敏捷开发