Files
lucky_shop/scripts/harmony.patch.js
ZF sun 6178f699ed feat(scripts): add harmony component placeholder injection logic
新增鸿蒙组件级componentPlaceholder自动注入脚本,解决diy组件编译为asyncComponent导致的运行时报错,自动遍历处理非页面组件的json配置文件,同时添加异常捕获避免构建中断
2026-07-10 17:28:52 +08:00

143 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* harmony.patch.js
*
* 该脚本用于鸿蒙元服务的构建后处理(仅在生产构建时由 vue.config.js 触发):
* 1. 拷贝 harmony-configs 配置文件到构建产物目录
* 2. 拷贝 site.js 到构建产物目录
* 3. 创建 ZIP 压缩包
*
* 使用:
* node harmony.patch.js # 拷贝文件并创建 ZIP(默认 mode=production)
* node harmony.patch.js --no-zip # 只拷贝文件,不创建 ZIP
*/
const fs = require('fs');
const fsp = fs.promises;
const path = require('path');
const { openFileDirectory } = require('./open-directory');
const { createZipWithSystemCommand } = require('./create-zip');
async function syncSiteToStub(mode = 'production') {
try {
const cwd = path.join(__dirname, '..');
const srcSitePath = path.join(cwd, 'site.js');
const stubSitePath = path.join(cwd, 'stub-app-projects', 'mp-harmony', 'ascf', 'ascf_src', 'site.js');
if (await exists(srcSitePath)) {
await fsp.copyFile(srcSitePath, stubSitePath);
console.log('site.js 已同步到 stub 项目源码目录');
}
} catch (err) {
console.error('同步 site.js 到 stub 失败:', err);
process.exitCode = 1;
}
}
async function copyAssets(mode = 'production') {
try {
const cwd = path.join(__dirname, '..');
const destDir = path.join(cwd, 'unpackage', 'dist', mode === 'production' ? 'build' : 'dev', '.mp-harmony');
await ensureDir(destDir);
const copyPromises = [];
if (await exists(path.join(cwd, 'harmony-configs'))) {
copyPromises.push(copyDirectory(path.join(cwd, 'harmony-configs'), path.join(destDir, 'harmony-configs')));
}
const srcSitePath = path.join(cwd, 'site.js');
if (await exists(srcSitePath)) {
copyPromises.push(fsp.copyFile(srcSitePath, path.join(destDir, 'site.js')));
// 同步一份到 entry rawfile,让 FormAbility 能在运行时 getRawFileContent('site.js') 读取
// (FormAbility 进程读不到 ascf_src/ 那份 webpack bundle,需要 rawfile 副本)
const rawfileSitePath = path.join(cwd, 'stub-app-projects', 'mp-harmony', 'entry', 'src', 'main', 'resources', 'rawfile', 'site.js');
copyPromises.push(fsp.copyFile(srcSitePath, rawfileSitePath));
}
await Promise.all(copyPromises);
// 给所有子组件 .json 注入 componentPlaceholder, 避免 "diy-* is asyncComponent" 报错.
// 见 scripts/harmony-component-placeholder.js 说明. 该脚本跳过页面级, 只处理组件.
try {
const { execFileSync } = require('child_process');
execFileSync(process.execPath, [
path.join(__dirname, 'harmony-component-placeholder.js'),
destDir,
], { stdio: 'inherit', cwd });
} catch (e) {
console.warn('[harmony.patch] ⚠️ harmony-component-placeholder 注入失败:', e.message);
}
console.log('HarmonyOS 资源拷贝完成');
} catch (err) {
console.error('发生错误:', err);
process.exitCode = 1;
}
}
async function copyDirectory(src, dest) {
await ensureDir(dest);
const entries = await fsp.readdir(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
if (entry.isDirectory()) {
await copyDirectory(srcPath, destPath);
} else {
await fsp.copyFile(srcPath, destPath);
}
}
}
async function main() {
const argv = process.argv.slice(2);
const options = {
noZip: argv.includes('--no-zip'),
mode: 'production'
};
const modeIndex = argv.indexOf('--mode');
if (modeIndex !== -1 && modeIndex + 1 < argv.length) {
options.mode = argv[modeIndex + 1];
}
// 同步 site.js 到 stub 项目源码目录,确保编译时能动态导入
await syncSiteToStub(options.mode);
await copyAssets(options.mode);
if (!options.noZip && options.mode === 'production') {
const cwd = path.join(__dirname, '..');
const sourceDir = path.join(cwd, 'unpackage', 'dist', 'build', '.mp-harmony');
const destDir = path.join(cwd, 'unpackage', 'dist', 'build');
const zipFilePath = await createZipWithSystemCommand(sourceDir, destDir, 'mp-harmony');
console.log(`ZIP 文件路径: ${zipFilePath}`);
await openFileDirectory(zipFilePath);
} else {
console.log('跳过创建 ZIP 文件和打开目录');
}
}
async function exists(p) {
try {
await fsp.access(p, fs.constants.F_OK);
return true;
} catch (e) {
return false;
}
}
async function ensureDir(dirPath) {
try {
await fsp.mkdir(dirPath, { recursive: true });
} catch (e) {
if (e.code !== 'EEXIST') throw e;
}
}
main();