diff --git a/compiler/src/fast_build/ark_compiler/interop/pre_define.ts b/compiler/src/fast_build/ark_compiler/interop/pre_define.ts index eaa908d4149f56a25a56bee5b66a7200743d75d5..d640e203aa8fb0d9fd67e6f34e0cf2ac084408c4 100644 --- a/compiler/src/fast_build/ark_compiler/interop/pre_define.ts +++ b/compiler/src/fast_build/ark_compiler/interop/pre_define.ts @@ -16,4 +16,7 @@ export const ARKTS_1_2: string = '1.2'; export const ARKTS_1_1: string = '1.1'; export const ARKTS_1_0: string = '1.0'; -export const ARKTS_HYBRID: string = 'hybrid'; \ No newline at end of file +export const ARKTS_HYBRID: string = 'hybrid'; + +export const GEN_ABC_CMD: string = 'genAbcCmd'; +export const GEN_ABC_CMD_FILE_PATH: string = 'genAbcCmd.json'; \ No newline at end of file diff --git a/compiler/src/fast_build/ark_compiler/interop/run_es2abc_standalone.ts b/compiler/src/fast_build/ark_compiler/interop/run_es2abc_standalone.ts new file mode 100644 index 0000000000000000000000000000000000000000..e05b3fb0f9aa020e54ed7c023e6cf14e7927e016 --- /dev/null +++ b/compiler/src/fast_build/ark_compiler/interop/run_es2abc_standalone.ts @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs'; +import path from 'path'; +import childProcess from 'child_process'; +import { + COMPILE_CONTEXT_INFO_JSON, + FILESINFO_TXT, + MODULES_ABC, + MODULES_CACHE, + NPMENTRIES_TXT, + SOURCEMAPS, + SOURCEMAPS_JSON, +} from '../common/ark_define'; +import { GEN_ABC_CMD_FILE_PATH } from './pre_define'; + +/** + * A script is called by hvigor in a mixed compilation scenario which 1.0 module is not main module,np + * such as module1.2-> module1.0-> module1.2 -> module1.0, compile all 1.0 modules + * and has nothing to do with the ace_ets2bundle process. + */ + +/** + * + * @param cachePathList projectConfig.cachePath of the modules to be merged + * @param targetCachePath The merged target cache directory + * @param aceModuleBuild The aceModuleBuild path of the target module is used to write the abc file to the disk + * @returns erro.toString() + */ +export function run(cachePathList: string[], targetCachePath: string, aceModuleBuild: string): void { + if (!cachePathList || cachePathList.length === 0) { + return; + } + mergeCacheData(cachePathList, targetCachePath, FILESINFO_TXT); + mergeCacheData(cachePathList, targetCachePath, MODULES_CACHE); + mergeCacheData(cachePathList, targetCachePath, NPMENTRIES_TXT); + mergeCompileContextInfo(cachePathList, targetCachePath); + mergeSourceMap(cachePathList, targetCachePath); + const cmd: string[] = JSON.parse(fs.readFileSync(path.join(cachePathList[0], GEN_ABC_CMD_FILE_PATH), 'utf-8')); + updateCmd(cmd, targetCachePath, aceModuleBuild); + execCmd(cmd); +} + +export function mergeCacheData(cachePathList: string[], targetCachePath: string, fileName: string): void { + const dataSet: Set = new Set(); + cachePathList.forEach(cachePath => { + processCachePath(cachePath, fileName, dataSet); + }); + + const outputFilePath: string = path.join(targetCachePath, fileName); + fs.writeFileSync(outputFilePath, Array.from(dataSet).join('\n')); +} + +function processCachePath(cachePath: string, fileName: string, dataSet: Set): void { + const inputFilePath = path.join(cachePath, fileName); + if (!fs.existsSync(inputFilePath)) { + return; + } + + const fileData = fs.readFileSync(inputFilePath).toString(); + const lines = fileData.split('\n'); + + for (const data of lines) { + if (data) { + dataSet.add(data); + } + } +} + +function execCmd(cmd: string[]): string { + try { + const result = childProcess.execSync(cmd.join(' '), { + windowsHide: true, + encoding: 'utf-8' + }); + return result; + } catch (error) { + return error.toString(); + } +} + +export function updateCmd(cmd: string[], targetCachePath: string, aceModuleBuild: string): void { + for (let i = 0; i < cmd.length; i++) { + if (cmd[i].indexOf('filesInfo.txt') !== -1) { + const filesInfoPath: string = path.join(targetCachePath, FILESINFO_TXT); + cmd[i] = `"@${filesInfoPath}"`; + continue; + } + if (cmd[i] === ('--output')) { + const moduleAbcPath = path.join(aceModuleBuild, MODULES_ABC); + cmd[++i] = `"${moduleAbcPath}"`; + continue; + } + if (cmd[i] === ('--cache-file')) { + const cacheFilePath = path.join(targetCachePath, MODULES_CACHE); + cmd[++i] = `"@${cacheFilePath}"`; + continue; + } + if (cmd[i] === ('--npm-module-entry-list')) { + const npmEntriesInfoPath = path.join(targetCachePath, NPMENTRIES_TXT); + cmd[++i] = `"@${npmEntriesInfoPath}"`; + continue; + } + if (cmd[i] === (`--compile-context-info`)) { + const compileContextInfoPath = path.join(targetCachePath, COMPILE_CONTEXT_INFO_JSON); + cmd[++i] = `"${compileContextInfoPath}"`; + continue; + } + } +} + +function deepMerge(target: Object, source: Object): Object { + for (const key of Object.keys(source)) { + if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { + target[key] = deepMerge(target[key] || {}, source[key]); + } else { + target[key] = source[key]; + } + } + return target; +} + +export function mergeCompileContextInfo(cachePathList: string[], targetCachePath: string): void { + const mergedData = { + hspPkgNames: [], + compileEntries: [], + updateVersionInfo: {} + }; + + cachePathList.forEach(cachePath => { + const compileContextPath = path.join(cachePath, COMPILE_CONTEXT_INFO_JSON); + + if (fs.existsSync(compileContextPath)) { + const data = JSON.parse(fs.readFileSync(compileContextPath, 'utf-8')); + + mergedData.hspPkgNames = [...mergedData.hspPkgNames, ...data.hspPkgNames]; + mergedData.compileEntries = [...mergedData.compileEntries, ...data.compileEntries]; + + mergedData.updateVersionInfo = deepMerge(mergedData.updateVersionInfo, data.updateVersionInfo); + } + }); + + const targetPath = path.join(targetCachePath, COMPILE_CONTEXT_INFO_JSON); + fs.writeFileSync(targetPath, JSON.stringify(mergedData, null, 2)); +} + +export function mergeSourceMap(cachePathList: string[], targetCachePath: string): void { + const mergedMap: Record = {}; + cachePathList.forEach((item) => { + /** + * Prevent sourcemap.json file from not being generated. + * Some bug scenarios only have one file written to disk. + */ + const possiblePaths = [ + path.join(item, SOURCEMAPS), + path.join(item, SOURCEMAPS_JSON), + ]; + + const sourceMapPath = possiblePaths.find(fs.existsSync); + if (!sourceMapPath) { + return; + } + const sourceMap = JSON.parse(fs.readFileSync(sourceMapPath, 'utf-8')); + Object.assign(mergedMap, sourceMap); + }); + + const outputPath = path.join(targetCachePath, SOURCEMAPS); + fs.writeFileSync(outputPath, JSON.stringify(mergedMap, null, 2), 'utf-8'); +} diff --git a/compiler/src/fast_build/ark_compiler/module/module_mode.ts b/compiler/src/fast_build/ark_compiler/module/module_mode.ts index 5f897415aa694bdb93e3763dc5af4728e2267a07..3384e526458a7af2abc26239df858e1c7191bfb6 100644 --- a/compiler/src/fast_build/ark_compiler/module/module_mode.ts +++ b/compiler/src/fast_build/ark_compiler/module/module_mode.ts @@ -126,6 +126,7 @@ import { import { isMixCompile } from '../interop/interop_manager'; +import { GEN_ABC_CMD } from '../interop/pre_define'; export class ModuleInfo { filePath: string; @@ -177,6 +178,7 @@ export class ModuleMode extends CommonMode { compileContextInfoPath: string; abcPaths: string[] = []; byteCodeHar: boolean; + rollupCache: Object; constructor(rollupObject: Object) { super(rollupObject); @@ -209,6 +211,7 @@ export class ModuleMode extends CommonMode { if (this.useNormalizedOHMUrl) { this.compileContextInfoPath = this.generateCompileContextInfo(rollupObject); } + this.rollupCache = rollupObject.cache; } private generateCompileContextInfo(rollupObject: Object): string { @@ -684,6 +687,13 @@ export class ModuleMode extends CommonMode { let errMsg: string = ''; const genAbcCmd: string = this.cmdArgs.join(' '); + const eventGenDescriptionsForMergedEs2abc = createAndStartEvent(parentEvent, 'generate descriptions for merged es2abc'); + stopEvent(eventGenDescriptionsForMergedEs2abc); + + if (this.projectConfig.invokeEs2abcByHvigor) { + this.rollupCache.set(GEN_ABC_CMD, this.cmdArgs); + return; + } try { let eventGenAbc: Object; const child = this.triggerAsync(() => { diff --git a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts index eecd0756ac82ed51ea0e871fefc524a471a9a0d0..f5f6eafe136b4fdb78c59821ddfb6863c7c6195e 100644 --- a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts +++ b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts @@ -105,7 +105,7 @@ export function etsChecker() { const logger = this.share.getLogger('etsChecker'); const rootFileNames: string[] = []; const resolveModulePaths: string[] = []; - rootFileNamesCollect(rootFileNames); + rootFileNamesCollect(rootFileNames, this.share); if (this.share && this.share.projectConfig && this.share.projectConfig.resolveModulePaths && Array.isArray(this.share.projectConfig.resolveModulePaths)) { resolveModulePaths.push(...this.share.projectConfig.resolveModulePaths);