3***@qq.com
3***@qq.com
  • 发布:2025-09-11 19:03
  • 更新:2025-09-11 19:17
  • 阅读:92

打包时实现环境隔离

分类:HBuilderX

我现在实现了根据不同的环境调用不同的后端接口,但是现在遇到了一个问题,每次发布版本的时候很容易拉错代码,因为发行后的文件都在unpackage\dist\build\web这个目录下,但是我想根据不同的环境是否可以生成这样的目录unpackage\dist\dev\build\web, unpackage\dist\test\build\web , unpackage\dist\prod\build\web 可以更好的区分项目,文档说编译时会把outputDir 给覆盖掉,那么还有什么别的方法可以实现这个功能吗,有大神了解的吗

2025-09-11 19:03 负责人:无 分享
已邀请:
DCloud_UNI_JBB

DCloud_UNI_JBB

你可以写个vite插件,在打包结束之后把文件内容移动到指定的目录下,比如 test 或 prod

  • 3***@qq.com (作者)

    我没用vite,我用是vue 我如何保证我的插件是发行完成在执行的脚本

    2025-09-15 11:04

  • DCloud_UNI_JBB

    回复 3***@qq.com: 一样的,vue2 就写个webpack 插件 或者写个脚本

    2025-09-15 11:09

  • 3***@qq.com (作者)

    回复 DCloud_UNI_JBB: 这是我的vue.config.js文件


    // console.log('vue.config.js 执行了')  
    // console.log('%O', process.UNI_SCRIPT_ENV)

    // 定义AfterBuildPlugin插件
    class AfterBuildPlugin {
    constructor(options) {
    this.options = options || {};
    }

    apply(compiler) {
    // 在webpack构建完成后执行脚本
    compiler.hooks.done.tap('AfterBuildPlugin', (stats) => {
    // 检查构建是否成功完成
    if (stats.hasErrors()) {
    console.error('构建过程中存在错误,跳过after-build脚本执行');
    return;
    }

    const { execSync } = require('child_process');

    try {
    console.log(`执行构建后脚本: ${this.options.script}`);
    // 执行指定的脚本命令
    execSync(this.options.script, { stdio: 'inherit' });
    console.log('构建后脚本执行完成');
    } catch (error) {
    console.error('构建后脚本执行失败:', error);
    }
    });
    }
    }

    module.exports = {
    chainWebpack: (config) => {
    // 使用AfterBuildPlugin并传递参数
    config.plugin('after-build').use(new AfterBuildPlugin({
    script: 'node "' + __dirname + '/afterBuilder.js" --env ' + process.UNI_SCRIPT_ENV.ENV
    }))
    }
    }

    这是我的afterBuilder.js 脚本文件


    const fs = require('fs-extra');  
    const path = require('path');

    // 获取命令行参数
    function getCommandLineArgs() {
    const args = {};
    process.argv.slice(2).forEach(arg => {
    const matches = arg.match(/--(\w+)=(.+)/);
    if (matches) {
    args[matches[1]] = matches[2];
    } else if (arg.startsWith('--')) {
    const key = arg.slice(2);
    args[key] = process.argv[process.argv.indexOf(arg) + 1] || true;
    }
    });
    return args;
    }

    const commandLineArgs = getCommandLineArgs();
    // 配置路径 - 根据你的实际情况修改
    const config = {
    // HBuilder打包输出目录
    buildOutputDir: path.join(__dirname, 'unpackage/dist/build/web'),
    // 目标复制目录
    targetDir: path.join(__dirname, 'unpackage/dist/' + commandLineArgs.env + '/build/web'),
    // 临时备份目录
    backupDir: path.join(__dirname, 'unpackage/backup')
    };

    async function main() {
    try {
    console.log('开始执行打包后处理脚本...');

    // 1. 检查打包目录是否存在
    if (!await fs.pathExists(config.buildOutputDir)) {
    throw new Error(`打包目录不存在: ${config.buildOutputDir}`);
    }

    // 2. 创建备份目录
    await fs.ensureDir(config.backupDir);
    console.log(`已创建备份目录: ${config.backupDir}`);

    // 3. 备份原始文件
    await fs.copy(config.buildOutputDir, config.backupDir, {
    overwrite: true
    });
    console.log('原始文件备份完成');

    // 4. 创建目标目录
    await fs.ensureDir(config.targetDir);
    console.log(`已创建目标目录: ${config.targetDir}`);

    // 5. 复制文件到目标目录
    await fs.copy(config.buildOutputDir, config.targetDir, {
    overwrite: true
    });
    console.log(`文件已复制到目标目录: ${config.targetDir}`);

    // 6. 执行其他自定义操作(可选)
    console.log('执行额外操作...');
    // 例如: 记录版本信息
    const versionInfo = {
    timestamp: new Date().toISOString(),
    version: require('./package.json').version,
    buildNumber: new Date().getTime().toString()
    };
    await fs.writeJson(path.join(config.targetDir, 'version.json'), versionInfo, { spaces: 2 });

    // 7. 恢复原始文件
    await fs.copy(config.backupDir, config.buildOutputDir, {
    overwrite: true
    });
    console.log('原始文件已恢复');

    // 8. 清理备份目录
    await fs.remove(config.backupDir);
    console.log('备份目录已清理');

    console.log('所有操作完成!');
    } catch (err) {
    console.error('处理过程出错:', err.message);
    process.exit(1);
    }
    }

    // 执行主函数
    main();

    这是HBuilder X 的输出结果


    [HBuilder] 14:00:58.134 项目 测试打包项目 [__UNI__19908F9] 开始发布到Web...  
    [HBuilder] 14:00:59.329 正在编译中...
    [HBuilder] 14:01:11.020 执行构建后脚本: node "D:\code\test-dev\web\测试打包项目/afterBuilder.js" --env test
    [HBuilder] 14:01:11.130 开始执行打包后处理脚本...
    [HBuilder] 14:01:11.130 等待Web项目导出完成...
    [HBuilder] 14:01:11.130 检测到Web项目已导出完成,耗时0ms
    [HBuilder] 14:01:11.130 已创建备份目录: D:\code\test-dev\web\测试打包项目\unpackage\backup
    [HBuilder] 14:01:11.161 原始文件备份完成
    [HBuilder] 14:01:11.161 已创建目标目录: D:\code\test-dev\web\测试打包项目\unpackage\dist\test\build\web
    [HBuilder] 14:01:11.161 文件已复制到目标目录: D:\code\test-dev\web\测试打包项目\unpackage\dist\test\build\web
    [HBuilder] 14:01:11.161 执行额外操作...
    [HBuilder] 14:01:11.161 原始文件已恢复
    [HBuilder] 14:01:11.161 备份目录已清理
    [HBuilder] 14:01:11.161 所有操作完成!
    [HBuilder] 14:01:11.167 构建后脚本执行完成
    [HBuilder] 14:01:11.167 项目 测试打包项目 编译成功。
    [HBuilder] 14:01:11.233 项目 测试打包项目 导出Web成功,路径为:D:\code\test-dev\web\测试打包项目\unpackage\dist\build\web
    [HBuilder] 14:01:11.233 注意请部署到web服务器使用,不要使用资源管理器直接打开,除非进行相对路径配置,具体参考:https://ask.dcloud.net.cn/article/37432。

    脚本好像在编译中的时候就触发了,而不是在项目导出成功后触发,请问一下,有钩子函数或者其他配置可以在导出成功后再执行脚本吗

    2025-09-15 14:33

要回复问题请先登录注册