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 69803a7520a185c7c6bee39ad9eb4ce4925f0271..13197d6774f45b43c1a32ab7d06a00cb81ad72e9 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 4fe0e8fd91f3b8fef3c47204181a1843518d645a..3a4e9f0cd1c26b9dddc0c4ea3364a3a95923e342 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 e8c2932a24de5a38d3bccdc1e85b0fcabe912915..cf0a880fc5fb79fcab21d6817f5d3425fc57fdaa 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 7b0a287a9963c60b92aedf56941748867058c237..2686ddb48ef2d2ddd055b050470dc5b2bc68565a 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 {