1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use rollupObject file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import fs from 'fs'; 17import path from 'path'; 18import { 19 COMMONJS, 20 ESM, 21 EXTNAME_PROTO_BIN, 22 EXTNAME_JS, 23 EXTNAME_TS, 24 EXTNAME_ETS 25} from '../../../../lib/fast_build/ark_compiler/common/ark_define'; 26import { 27 ModuleMode, 28 PackageEntryInfo 29} from '../../../../lib/fast_build/ark_compiler/module/module_mode'; 30import { 31 getNormalizedOhmUrlByFilepath, 32 transformOhmurlToPkgName, 33 transformOhmurlToRecordName 34} from '../../../../lib/ark_utils'; 35import { changeFileExtension } from '../../../../lib/fast_build/ark_compiler/utils'; 36import { toUnixPath } from '../../../../lib/utils'; 37import { META } from '../rollup_mock/common'; 38import { sharedModuleSet } from '../../../../lib/fast_build/ark_compiler/check_shared_module'; 39import { SourceMapGenerator } from '../../../../lib/fast_build/ark_compiler/generate_sourcemap'; 40class ModuleModeMock extends ModuleMode { 41 collectModuleFileListMock(rollupObject: object) { 42 const fileList = Array.from(rollupObject.getModuleIds()); 43 this.collectModuleFileList(rollupObject, fileList); 44 } 45 46 addModuleInfoItemMock(rollupObject: object, isCommonJs: boolean, extName: string) { 47 const mockFileList = rollupObject.getModuleIds(); 48 for (const filePath of mockFileList) { 49 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_ETS) || filePath.endsWith(EXTNAME_JS)) { 50 const moduleInfo: object = rollupObject.getModuleInfo(filePath); 51 const metaInfo: object = moduleInfo[META]; 52 this.addModuleInfoItem(filePath, isCommonJs, extName, metaInfo, this.moduleInfos); 53 } 54 } 55 } 56 57 addSourceMapMock(rollupObject: object, sourceMapGenerator: SourceMapGenerator) { 58 for (const filePath of rollupObject.getModuleIds()) { 59 const isValidSuffix: boolean = 60 filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_ETS) || filePath.endsWith(EXTNAME_JS); 61 if (!isValidSuffix) 62 continue; 63 if (sourceMapGenerator.isNewSourceMaps()) { 64 sourceMapGenerator.updateSourceMap(filePath, {}); 65 } else { 66 const filePathCache: string = this.genFileCachePath( 67 filePath, this.projectConfig.projectRootPath, this.projectConfig.cachePath) 68 sourceMapGenerator.updateSourceMap( 69 filePathCache.replace(this.projectConfig.projectRootPath + path.sep, ''), {}); 70 } 71 } 72 } 73 74 static getModuleInfosAndSourceMapMock(rollupObject: object, sourceMapGenerator: SourceMapGenerator) { 75 const moduleMode = new ModuleModeMock(rollupObject); 76 moduleMode.addSourceMapMock(rollupObject, sourceMapGenerator); 77 moduleMode.addModuleInfoItemMock(rollupObject, false, ''); 78 return { moduleInfos: moduleMode.moduleInfos, sourceMap: sourceMapGenerator.getSourceMaps() }; 79 } 80 81 generateCompileFilesInfoMock(includeByteCodeHarInfo: boolean) { 82 this.generateCompileFilesInfo(includeByteCodeHarInfo); 83 } 84 85 generateNpmEntriesInfoMock() { 86 this.generateNpmEntriesInfo(); 87 } 88 89 generateAbcCacheFilesInfoMock() { 90 this.generateAbcCacheFilesInfo(); 91 } 92 93 generateCompileContextInfoMock(rollupObject: object): void { 94 this.compileContextInfoPath = this.generateCompileContextInfo(rollupObject); 95 } 96 97 checkGenerateCompileContextInfo(rollupObject: object): boolean { 98 const cacheCompileContextInfo = fs.readFileSync(this.compileContextInfoPath, 'utf-8'); 99 100 let compileContextInfo: Object = {}; 101 let hspPkgNames: Array<string> = []; 102 for (const hspName in rollupObject.share.projectConfig.hspNameOhmMap) { 103 let hspPkgName: string = hspName; 104 if (rollupObject.share.projectConfig.dependencyAliasMap.has(hspName)) { 105 hspPkgName = rollupObject.share.projectConfig.dependencyAliasMap.get(hspName); 106 } 107 hspPkgNames.push(toUnixPath(hspPkgName)); 108 } 109 compileContextInfo.hspPkgNames = hspPkgNames; 110 let compileEntries: Set<string> = new Set(); 111 let entryObj: Object = this.projectConfig.entryObj; 112 if (this.projectConfig.widgetCompile) { 113 entryObj = this.projectConfig.cardEntryObj; 114 } 115 for (const key in entryObj) { 116 let moduleId: string = entryObj[key]; 117 let moduleInfo: Object = rollupObject.getModuleInfo(moduleId); 118 let metaInfo: Object = moduleInfo.meta; 119 const pkgParams = { 120 pkgName: metaInfo.pkgName, 121 pkgPath: metaInfo.pkgPath, 122 isRecordName: true 123 }; 124 let recordName: string = getNormalizedOhmUrlByFilepath(moduleId, rollupObject.share.projectConfig, 125 rollupObject.share.logger, pkgParams, undefined); 126 compileEntries.add(recordName); 127 } 128 this.collectDeclarationFilesEntry(compileEntries, hspPkgNames); 129 compileContextInfo.compileEntries = Array.from(compileEntries); 130 if (rollupObject.share.projectConfig.updateVersionInfo) { 131 compileContextInfo.updateVersionInfo = this.projectConfig.updateVersionInfo; 132 } else if (rollupObject.share.projectConfig.pkgContextInfo) { 133 compileContextInfo.pkgContextInfo = this.projectConfig.pkgContextInfo; 134 } 135 if (this.projectConfig.bundleType === 'shared') { 136 compileContextInfo.needModifyRecord = true; 137 compileContextInfo.bundleName = this.projectConfig.bundleName; 138 } 139 if (JSON.stringify(compileContextInfo) === cacheCompileContextInfo) { 140 return true; 141 } 142 return false; 143 } 144 145 checkGenerateCompileFilesInfo(includeByteCodeHarInfo: boolean): boolean { 146 let mockfilesInfo: string = ''; 147 const filesInfo = fs.readFileSync(this.filesInfoPath, 'utf-8'); 148 this.moduleInfos.forEach((info) => { 149 const moduleType: string = info.isCommonJs ? COMMONJS : ESM; 150 const isSharedModule: boolean = sharedModuleSet.has(info.filePath); 151 mockfilesInfo += 152 `${info.cacheFilePath};${info.recordName};${moduleType};${info.sourceFile};${info.packageName};` + 153 `${isSharedModule}\n`; 154 }); 155 if (includeByteCodeHarInfo) { 156 Object.entries(this.projectConfig.byteCodeHarInfo).forEach(([pkgName, abcInfo]) => { 157 const abcPath: string = toUnixPath(abcInfo.abcPath); 158 mockfilesInfo += `${abcPath};;;;${pkgName};\n`; 159 }); 160 } 161 if (filesInfo === mockfilesInfo) { 162 return true; 163 } 164 return false; 165 } 166 167 checkGenerateNpmEntriesInfo(): boolean { 168 let mockentriesInfo: string = ''; 169 const filesInfo = fs.readFileSync(this.npmEntriesInfoPath, 'utf-8'); 170 for (const value of this.pkgEntryInfos.values()) { 171 mockentriesInfo += `${value.pkgEntryPath}:${value.pkgBuildPath}\n`; 172 } 173 if (filesInfo === mockentriesInfo) { 174 return true; 175 } 176 return false; 177 } 178 179 checkGenerateAbcCacheFilesInfo(): boolean { 180 let mockabcCacheFilesInfo: string = ''; 181 const filesInfo = fs.readFileSync(this.cacheFilePath, 'utf-8'); 182 this.moduleInfos.forEach((info) => { 183 const abcCacheFilePath: string = changeFileExtension(info.cacheFilePath, EXTNAME_PROTO_BIN); 184 mockabcCacheFilesInfo += `${info.cacheFilePath};${abcCacheFilePath}\n`; 185 }); 186 187 const npmEntriesCacheFilePath: string = changeFileExtension(this.npmEntriesInfoPath, EXTNAME_PROTO_BIN); 188 mockabcCacheFilesInfo += `${this.npmEntriesInfoPath};${npmEntriesCacheFilePath}\n`; 189 190 if (filesInfo === mockabcCacheFilesInfo) { 191 return true; 192 } 193 return false; 194 } 195 196 checkGetPackageEntryInfo(rollup: object, isTestErrorLog: boolean = false) { 197 this.pkgEntryInfos = new Map<String, PackageEntryInfo>(); 198 const mockFileList = rollup.getModuleIds(); 199 for (const filePath of mockFileList) { 200 if (filePath.endsWith(EXTNAME_TS) || filePath.endsWith(EXTNAME_ETS) || filePath.endsWith(EXTNAME_JS)) { 201 const moduleInfos = rollup.getModuleInfo(filePath); 202 moduleInfos.setIsLocalDependency(false); 203 moduleInfos.setIsNodeEntryFile(true); 204 const metaInfo: object = moduleInfos[META]; 205 if (isTestErrorLog) { 206 metaInfo['pkgPath'] = ''; 207 } 208 this.getPackageEntryInfo(filePath, metaInfo, this.pkgEntryInfos); 209 } 210 } 211 } 212 213 updateCachedSourceMapsMock(sourceMapGenerator: Object) { 214 sourceMapGenerator.updateCachedSourceMaps(); 215 } 216 217 buildModuleSourceMapInfoMock(sourceMapGenerator: Object) { 218 sourceMapGenerator.buildModuleSourceMapInfo(); 219 } 220 221 checkModuleSourceMapInfoMock(): boolean { 222 const readSourceMap = fs.readFileSync(this.sourceMapPath, 'utf-8'); 223 const readCacheSourceMap = fs.readFileSync(this.cacheSourceMapPath, 'utf-8'); 224 if (readSourceMap.length == 0 && readCacheSourceMap.length == 0) { 225 return true; 226 } else if (readSourceMap === readCacheSourceMap) { 227 return true; 228 } else { 229 return false; 230 } 231 } 232 233 generateMergedAbcOfEs2AbcMock(parentEvent: Object) { 234 this.generateMergedAbcOfEs2Abc(parentEvent) 235 } 236 237 filterModulesByHashJsonMock() { 238 this.filterModulesByHashJson(); 239 } 240 241 invokeTs2AbcWorkersToGenProtoMock(splittedModules: Object) { 242 this.invokeTs2AbcWorkersToGenProto(splittedModules) 243 } 244 245 246} 247 248export default ModuleModeMock;