From 1cd36cd8610060dd3a10ffed17f86f1666951e14 Mon Sep 17 00:00:00 2001 From: Yenan Date: Sun, 24 Aug 2025 17:03:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96rawfile=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E5=A2=9E=E9=87=8F=E7=BC=96=E8=AF=91=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Yenan --- .../common/rollup-plugin-watch-change.ts | 5 +- .../ets_ui/rollup-plugin-ets-typescript.ts | 50 ++++++++++++++++--- compiler/src/process_ui_syntax.ts | 9 +++- compiler/src/utils.ts | 49 +++++++++++------- 4 files changed, 85 insertions(+), 28 deletions(-) diff --git a/compiler/src/fast_build/common/rollup-plugin-watch-change.ts b/compiler/src/fast_build/common/rollup-plugin-watch-change.ts index 69803a752..13197d677 100644 --- a/compiler/src/fast_build/common/rollup-plugin-watch-change.ts +++ b/compiler/src/fast_build/common/rollup-plugin-watch-change.ts @@ -60,8 +60,9 @@ export function watchChangeFiles() { resources.app = {}; readAppResource(process.env.appResource); if (process.env.rawFileResource) { - resourcesRawfile(process.env.rawFileResource, storedFileInfo.resourcesArr); - this.share.rawfilechanged = differenceResourcesRawfile(storedFileInfo.lastResourcesSet, storedFileInfo.resourcesArr); + resourcesRawfile(process.env.rawFileResource, storedFileInfo.resourcesArr, this.share.getHashByFilePath); + this.share.rawfilechanged = differenceResourcesRawfile(storedFileInfo.lastResourcesSet, + storedFileInfo.resourcesArr, storedFileInfo.changedResourcesSet); } } ShouldEnableDebugLine.enableDebugLine = false; diff --git a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts index 4fe0e8fd9..3a4e9f0cd 100644 --- a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts +++ b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-typescript.ts @@ -161,12 +161,19 @@ export function etsTransform() { cacheFile = this.cache.get('transformCacheFiles'); storedFileInfo.addGlobalCacheInfo(this.cache.get('resourceListCacheInfo'), this.cache.get('resourceToFileCacheInfo'), cacheFile); - if (this.cache.get('lastResourcesArr')) { - storedFileInfo.lastResourcesSet = new Set([...this.cache.get('lastResourcesArr')]); + if (this.cache.has('lastResourcesArr') && this.cache.has('lastResourcesForFiles')) { + storedFileInfo.lastResourcesSet = this.cache.get('lastResourcesArr'); + storedFileInfo.lastResourcesForFiles = this.cache.get('lastResourcesForFiles'); + storedFileInfo.hasResourcesCache = true; + } else { + storedFileInfo.lastResourcesSet = new Map(); + storedFileInfo.lastResourcesForFiles = new Map(); + storedFileInfo.hasResourcesCache = false; } if (process.env.rawFileResource) { - resourcesRawfile(process.env.rawFileResource, storedFileInfo.resourcesArr); - this.share.rawfilechanged = differenceResourcesRawfile(storedFileInfo.lastResourcesSet, storedFileInfo.resourcesArr); + resourcesRawfile(process.env.rawFileResource, storedFileInfo.resourcesArr, this.share.getHashByFilePath); + this.share.rawfilechanged = differenceResourcesRawfile(storedFileInfo.lastResourcesSet, + storedFileInfo.resourcesArr, storedFileInfo.changedResourcesSet); } } if (!!this.cache.get('enableDebugLine') !== projectConfig.enableDebugLine) { @@ -198,7 +205,7 @@ export function etsTransform() { const fileName: string = path.resolve(options.id); let shouldDisable: boolean = shouldDisableCache || disableNonEntryFileCache(fileName) || ShouldEnableDebugLine.enableDebugLine; if (process.env.compileMode === 'moduleJson') { - shouldDisable = shouldDisable || storedFileInfo.shouldInvalidFiles.has(fileName) || this.share.rawfilechanged; + shouldDisable = shouldDisable || storedFileInfo.shouldInvalidFiles.has(fileName) || checkRawFileChange(fileName); if (cacheFile && cacheFile[fileName] && cacheFile[fileName].children.length) { for (let child of cacheFile[fileName].children) { const newTimeMs: number = fs.existsSync(child.fileName) ? fs.statSync(child.fileName).mtimeMs : -1; @@ -280,7 +287,11 @@ export function etsTransform() { } shouldDisableCache = false; this.cache.set('disableCacheOptions', disableCacheOptions); - this.cache.set('lastResourcesArr', [...storedFileInfo.resourcesArr]); + this.cache.set('lastResourcesArr', new Map(storedFileInfo.resourcesArr)); + storedFileInfo.resourcesForFiles.forEach((value, key) => { + storedFileInfo.lastResourcesForFiles.set(key, value); + }); + this.cache.set('lastResourcesForFiles', new Map(storedFileInfo.lastResourcesForFiles)); if (projectConfig.enableDebugLine) { this.cache.set('enableDebugLine', true); } else { @@ -338,6 +349,33 @@ function judgeCacheShouldDisabled(): void { } } + +/** + * Checks if a given file needs to be recompiled due to changes in raw resource files. + * + * This function determines whether the specified file has dependencies on raw files + * (resources) that have been modified since the last compilation. It checks against + * a cache of stored file information and a set of changed resources. + * + * @param {string} file - The path or identifier of the file to check for recompilation need + * @returns {boolean} Returns true if the file needs recompilation due to raw file changes, + * false otherwise + */ +function checkRawFileChange(file: string): boolean { + if (!storedFileInfo.hasResourcesCache) { + return true; + } + if (!storedFileInfo.lastResourcesForFiles.has(file)) { + return false; + } + for (const singleRawfiles of storedFileInfo.lastResourcesForFiles.get(file)) { + if (storedFileInfo.changedResourcesSet.has(singleRawfiles)) { + return true; + } + } + return false; +} + interface EmitResult { outputText: string, sourceMapText: string, diff --git a/compiler/src/process_ui_syntax.ts b/compiler/src/process_ui_syntax.ts index e8c2932a2..cf0a880fc 100644 --- a/compiler/src/process_ui_syntax.ts +++ b/compiler/src/process_ui_syntax.ts @@ -747,7 +747,7 @@ export function processResourceData(node: ts.CallExpression, filePath: string, const resourceData: string[] = (node.arguments[0] as ts.StringLiteral).text.trim().split('.'); const isResourceModule: boolean = resourceData.length && /^\[.*\]$/g.test(resourceData[0]); if (node.expression.getText() === RESOURCE_RAWFILE) { - isResourcefile(node, previewLog, isResourceModule, isTemplateString, isCorrectResources); + isResourcefile(node, previewLog, isResourceModule, isTemplateString, isCorrectResources, filePath); if (isCorrectResources.booleanValue) { resourcePreviewMessage(previewLog); return createResourceParamWithVariable(node, -1, RESOURCE_TYPE.rawfile); @@ -815,7 +815,7 @@ function getResourceDataNode(node: ts.CallExpression, previewLog: {isAccelerateP } function isResourcefile(node: ts.CallExpression, previewLog: {isAcceleratePreview: boolean, log: LogInfo[]}, isResourceModule: boolean, - isTemplateString: boolean, isCorrectResources: isCorrectResourcesType): void { + isTemplateString: boolean, isCorrectResources: isCorrectResourcesType, filePath: string): void { if (!isResourceModule && process.env.rawFileResource && !storedFileInfo.resourcesArr.has(node.arguments[0].text) && !previewLog.isAcceleratePreview && process.env.compileMode === 'moduleJson') { isTemplateString && (isCorrectResources.booleanValue = true); @@ -825,6 +825,11 @@ function isResourcefile(node: ts.CallExpression, previewLog: {isAcceleratePrevie pos: node.getStart(), code: '10904333' }); + } else if (!isResourceModule && process.env.rawFileResource) { + if (!storedFileInfo.resourcesForFiles.has(filePath)) { + storedFileInfo.resourcesForFiles.set(filePath, []); + } + storedFileInfo.resourcesForFiles.get(filePath).push(node.arguments[0].text); } } diff --git a/compiler/src/utils.ts b/compiler/src/utils.ts index 7b0a287a9..2686ddb48 100644 --- a/compiler/src/utils.ts +++ b/compiler/src/utils.ts @@ -787,8 +787,12 @@ export class ProcessFileInfo { resourceTableChanged: boolean = false; currentArkTsFile: SpecialArkTSFileInfo; reUseProgram: boolean = false; - resourcesArr: Set = new Set(); - lastResourcesSet: Set = new Set(); + resourcesArr: Map = new Map(); // Rawfile and its hash + lastResourcesSet: Map = new Map(); + changedResourcesSet: Set = new Set(); // Rawfiles that are modified + resourcesForFiles: Map = new Map(); // Rawfiles used by each source file + lastResourcesForFiles: Map = new Map(); + hasResourcesCache: boolean = false; transformCacheFiles: { [fileName: string]: CacheFile } = {}; processBuilder: boolean = false; processGlobalBuilder: boolean = false; @@ -961,6 +965,10 @@ export class ProcessFileInfo { this.lastResourceList = new Set([...this.resourceList]); this.shouldInvalidFiles.clear(); this.resourcesArr.clear(); + this.lastResourcesSet.clear(); + this.changedResourcesSet.clear(); + this.resourcesForFiles.clear(); + this.lastResourcesForFiles.clear(); } setCurrentArkTsFile(): void { this.currentArkTsFile = new SpecialArkTSFileInfo(); @@ -1031,36 +1039,41 @@ export interface ExtendResult { componentName: string; } -export function resourcesRawfile(rawfilePath: string, resourcesArr: Set, resourceName: string = ''): void { +export function resourcesRawfile(rawfilePath: string, resourcesArr: Map, + getHashByFilePathFunc: Function | undefined, resourceName: string = ''): void { + if (!getHashByFilePathFunc) { + getHashByFilePathFunc = (filePath: string): string => '0'; + } if (fs.existsSync(process.env.rawFileResource) && fs.statSync(rawfilePath).isDirectory()) { const files: string[] = fs.readdirSync(rawfilePath); files.forEach((file: string) => { if (fs.statSync(path.join(rawfilePath, file)).isDirectory()) { - resourcesRawfile(path.join(rawfilePath, file), resourcesArr, resourceName ? resourceName + '/' + file : file); + resourcesRawfile(path.join(rawfilePath, file), resourcesArr, getHashByFilePathFunc, + resourceName ? resourceName + '/' + file : file); } else { if (resourceName) { - resourcesArr.add(resourceName + '/' + file); + resourcesArr.set(resourceName + '/' + file, getHashByFilePathFunc(rawfilePath + '/' + file)); } else { - resourcesArr.add(file); + resourcesArr.set(file, getHashByFilePathFunc(rawfilePath + '/' + file)); } } }); } } -export function differenceResourcesRawfile(oldRawfile: Set, newRawfile: Set): boolean { - if (oldRawfile.size !== 0 && oldRawfile.size === newRawfile.size) { - for (const singleRawfiles of oldRawfile.values()) { - if (!newRawfile.has(singleRawfiles)) { - return true; - } +export function differenceResourcesRawfile(oldRawfile: Map, newRawfile: Map, + changedRawFile: Set): boolean { + let res: boolean = oldRawfile.size !== newRawfile.size; + oldRawfile.forEach((hash, file) => { + if (!newRawfile.has(file)) { + changedRawFile.add(file); + res = true; + } else if (newRawfile.get(file) !== hash || newRawfile.get(file) === '0') { + changedRawFile.add(file); + res = true; } - return false; - } else if (oldRawfile.size === 0 && oldRawfile.size === newRawfile.size) { - return false; - } else { - return true; - } + }); + return res; } export function isString(text: unknown): text is string { -- Gitee