1/* 2 * Copyright (c) 2020 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this 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 16const fs = require('fs'); 17const path = require('path'); 18const crypto = require('crypto'); 19const JSON5 = require('json5'); 20 21const { 22 readFile, 23 writeFileSync, 24 resourcesRawfile, 25 getStoredFileInfo 26} = require('./lib/utils'); 27 28const { 29 COLD_RELOAD_MODE, 30 ES2ABC, 31 FAIL, 32 TEST_RUNNER_DIR_SET, 33 TS2ABC, 34 WORKERS_DIR 35} = require('./lib/pre_define'); 36 37const { 38 checkAotConfig 39} = require('./lib/gen_aot'); 40 41const { 42 configure, 43 getLogger 44} = require('log4js'); 45 46configure({ 47 appenders: { 'ETS': {type: 'stderr', layout: {type: 'messagePassThrough'}}}, 48 categories: {'default': {appenders: ['ETS'], level: 'info'}} 49}); 50const logger = getLogger('ETS'); 51 52let staticPreviewPage = process.env.aceStaticPreview; 53let aceCompileMode = process.env.aceCompileMode || 'page'; 54const abilityConfig = { 55 abilityType: process.env.abilityType || 'page', 56 abilityEntryFile: null, 57 projectAbilityPath: [], 58 testRunnerFile: [] 59}; 60const projectConfig = {}; 61const resources = { 62 app: {}, 63 sys: {} 64}; 65const systemModules = []; 66const abilityPagesFullPath = new Set(); 67let globalModulePaths = []; 68let sdkConfigs = []; 69let defaultSdkConfigs = []; 70let extendSdkConfigs = []; 71let sdkConfigPrefix = 'ohos|system|kit|arkts'; 72let ohosSystemModulePaths = []; 73let ohosSystemModuleSubDirPaths = []; 74let allModulesPaths = []; 75 76function initProjectConfig(projectConfig) { 77 initProjectPathConfig(projectConfig); 78 projectConfig.entryObj = {}; 79 projectConfig.entryArrayForObf = []; // Only used for arkguard 80 projectConfig.cardObj = {}; 81 projectConfig.aceBuildJson = projectConfig.aceBuildJson || process.env.aceBuildJson; 82 projectConfig.xtsMode = /ets_loader_ark$/.test(__dirname) || process.env.xtsMode === 'true'; 83 projectConfig.isPreview = projectConfig.isPreview || process.env.isPreview === 'true'; 84 projectConfig.compileMode = projectConfig.compileMode || process.env.compileMode || 'jsbundle'; 85 projectConfig.runtimeOS = projectConfig.runtimeOS || process.env.runtimeOS || 'default'; 86 projectConfig.sdkInfo = projectConfig.sdkInfo || process.env.sdkInfo || 'default'; 87 projectConfig.compileHar = false; 88 projectConfig.compileShared = false; 89 projectConfig.splitCommon = false; 90 projectConfig.allowEtsAnnotations = true; 91 projectConfig.checkEntry = projectConfig.checkEntry || process.env.checkEntry; 92 projectConfig.obfuscateHarType = projectConfig.obfuscateHarType || process.env.obfuscate; 93 projectConfig.packageDir = 'node_modules'; 94 projectConfig.packageJson = 'package.json'; 95 projectConfig.packageManagerType = 'npm'; 96 projectConfig.cardEntryObj = {}; 97 projectConfig.compilerTypes = []; 98 projectConfig.isCrossplatform = projectConfig.isCrossplatform || false; 99 projectConfig.enableDebugLine = projectConfig.enableDebugLine || process.env.enableDebugLine || false; 100 projectConfig.bundleType = projectConfig.bundleType || process.env.bundleType || ''; 101 projectConfig.optLazyForEach = false; 102 projectConfig.hspResourcesMap = false; 103 projectConfig.useArkoala = false; 104 projectConfig.resetBundleName = false; 105 projectConfig.integratedHsp = false; 106 projectConfig.useTsHar = false; 107 projectConfig.optTryCatchFunc = true; 108 // All files which dependent on bytecode har, and should be added to compilation entries. 109 projectConfig.otherCompileFiles = {}; 110 // Packages which need to update version in bytecode har 111 projectConfig.updateVersionInfo = undefined; 112 projectConfig.allowEmptyBundleName = false; 113 projectConfig.uiTransformOptimization = false; 114 projectConfig.ignoreCrossplatformCheck = false; 115} 116 117function initProjectPathConfig(projectConfig) { 118 projectConfig.projectPath = projectConfig.projectPath || process.env.aceModuleRoot || 119 path.join(process.cwd(), 'sample'); 120 projectConfig.buildPath = projectConfig.buildPath || process.env.aceModuleBuild || 121 path.resolve(projectConfig.projectPath, 'build'); 122 projectConfig.aceModuleBuild = projectConfig.buildPath; // To be compatible with both webpack and rollup 123 projectConfig.manifestFilePath = projectConfig.manifestFilePath || process.env.aceManifestPath || 124 path.join(projectConfig.projectPath, 'manifest.json'); 125 projectConfig.aceProfilePath = projectConfig.aceProfilePath || process.env.aceProfilePath; 126 projectConfig.aceModuleJsonPath = projectConfig.aceModuleJsonPath || process.env.aceModuleJsonPath; 127 projectConfig.aceSuperVisualPath = projectConfig.aceSuperVisualPath || 128 process.env.aceSuperVisualPath; 129 projectConfig.hashProjectPath = projectConfig.hashProjectPath || 130 hashProjectPath(projectConfig.projectPath); 131 projectConfig.cachePath = projectConfig.cachePath || process.env.cachePath || 132 path.resolve(__dirname, 'node_modules/.cache'); 133 projectConfig.aceSoPath = projectConfig.aceSoPath || process.env.aceSoPath; 134 projectConfig.localPropertiesPath = projectConfig.localPropertiesPath || process.env.localPropertiesPath; 135 projectConfig.projectProfilePath = projectConfig.projectProfilePath || process.env.projectProfilePath; 136} 137 138function loadMemoryTrackingConfig(projectConfig) { 139 projectConfig.enableMemoryDotting = process.env.enableMemoryDotting || false; 140 projectConfig.memoryDottingPath = path.resolve(projectConfig.buildPath, '../', '../', 'dottingfile'); 141 // recordInterval config, unit is ms 142 projectConfig.memoryDottingRecordInterval = process.env.memoryDottingRecordInterval || 100; 143 // records the config interval for writing files, unit is ms. 144 projectConfig.memoryDottingWriteFileInterval = process.env.memoryDottingWriteFileInterval || 1000; 145} 146 147function loadEntryObj(projectConfig) { 148 let manifest = {}; 149 initMain(); 150 initProjectConfig(projectConfig); 151 loadMemoryTrackingConfig(projectConfig); 152 loadBuildJson(); 153 if (process.env.aceManifestPath && aceCompileMode === 'page') { 154 setEntryFile(projectConfig); 155 setFaTestRunnerFile(projectConfig); 156 } 157 if (process.env.aceModuleJsonPath) { 158 setIntentEntryPages(projectConfig); 159 setAbilityPages(projectConfig); 160 setStageTestRunnerFile(projectConfig); 161 loadNavigationConfig(aceBuildJson); 162 } 163 164 if (staticPreviewPage) { 165 projectConfig.entryObj['./' + staticPreviewPage] = projectConfig.projectPath + path.sep + 166 staticPreviewPage + '.ets?entry'; 167 setEntryArrayForObf(staticPreviewPage); 168 } else if (abilityConfig.abilityType === 'page') { 169 if (fs.existsSync(projectConfig.manifestFilePath)) { 170 const jsonString = fs.readFileSync(projectConfig.manifestFilePath).toString(); 171 manifest = JSON.parse(jsonString); 172 if (manifest && manifest.minPlatformVersion) { 173 process.env.minPlatformVersion = manifest.minPlatformVersion; 174 partialUpdateController(manifest.minPlatformVersion); 175 } 176 projectConfig.pagesJsonFileName = 'config.json'; 177 } else if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { 178 process.env.compileMode = 'moduleJson'; 179 buildManifest(manifest, projectConfig.aceModuleJsonPath); 180 } else { 181 throw Error('\u001b[31m ERROR: the manifest file ' + projectConfig.manifestFilePath.replace(/\\/g, '/') + 182 ' or module.json is lost or format is invalid. \u001b[39m').message; 183 } 184 if (!projectConfig.compileHar) { 185 if (manifest.pages) { 186 const pages = manifest.pages; 187 pages.forEach((element) => { 188 const sourcePath = element.replace(/^\.\/ets\//, ''); 189 const fileName = path.resolve(projectConfig.projectPath, sourcePath + '.ets'); 190 if (fs.existsSync(fileName)) { 191 projectConfig.entryObj['./' + sourcePath] = fileName + '?entry'; 192 // Collect the file paths in main_pages.json 193 setEntryArrayForObf(sourcePath); 194 } else { 195 throw Error('\u001b[31m10906403 ArkTS Compiler Error' + '\n' + 196 'Error Message: ' + `Page '${fileName.replace(/\\/g, '/')}' does not exist. \u001b[39m`) 197 .message; 198 } 199 }); 200 } else { 201 throw Error('\u001b[31m ERROR: missing pages attribute in ' + 202 projectConfig.manifestFilePath.replace(/\\/g, '/') + 203 '. \u001b[39m').message; 204 } 205 } 206 } 207} 208 209function loadNavigationConfig(aceBuildJson) { 210 if (aceBuildJson && aceBuildJson.routerMap && Array.isArray(aceBuildJson.routerMap)) { 211 aceBuildJson.routerMap.forEach((item) => { 212 if (item.pageSourceFile && (item.name || item.name === '') && item.buildFunction) { 213 const filePath = path.resolve(item.pageSourceFile); 214 const storedFileInfo = getStoredFileInfo(); 215 if (storedFileInfo.routerInfo.has(filePath)) { 216 storedFileInfo.routerInfo.get(filePath).push({name: item.name, buildFunction: item.buildFunction}); 217 } else { 218 storedFileInfo.routerInfo.set(filePath, [{name: item.name, buildFunction: item.buildFunction}]); 219 } 220 } 221 }); 222 } 223} 224 225function buildManifest(manifest, aceConfigPath) { 226 try { 227 const moduleConfigJson = JSON.parse(fs.readFileSync(aceConfigPath).toString()); 228 manifest.type = process.env.abilityType; 229 if (moduleConfigJson && moduleConfigJson.app && moduleConfigJson.app.minAPIVersion) { 230 if (moduleConfigJson.module && moduleConfigJson.module.metadata) { 231 partialUpdateController(moduleConfigJson.app.minAPIVersion, moduleConfigJson.module.metadata, 232 moduleConfigJson.module.type); 233 stageOptimization(moduleConfigJson.module.metadata); 234 } else { 235 partialUpdateController(moduleConfigJson.app.minAPIVersion); 236 } 237 } 238 if (moduleConfigJson.module) { 239 switch (moduleConfigJson.module.type) { 240 case 'har': 241 projectConfig.compileHar = true; 242 getPackageJsonEntryPath(); 243 break; 244 case 'shared': 245 projectConfig.compileShared = true; 246 getPackageJsonEntryPath(); 247 manifest.pages = getPages(moduleConfigJson); 248 break; 249 default: 250 manifest.pages = getPages(moduleConfigJson); 251 break; 252 } 253 } else { 254 throw Error('\u001b[31m' + 255 'BUIDERROR: the config.json file miss key word module || module[abilities].' + 256 '\u001b[39m').message; 257 } 258 } catch (e) { 259 if (/BUIDERROR/.test(e)) { 260 throw Error(e.replace('BUIDERROR', 'ERROR')).message; 261 } else { 262 throw Error('\x1B[31m' + 'ERROR: the module.json file is lost or format is invalid.' + 263 '\x1B[39m').message; 264 } 265 } 266} 267 268function getPackageJsonEntryPath() { 269 let rootPackageJsonPath = path.resolve(projectConfig.projectPath, '../../../', projectConfig.packageJson); 270 if (fs.existsSync(rootPackageJsonPath)) { 271 let rootPackageJsonContent; 272 try { 273 rootPackageJsonContent = (projectConfig.packageManagerType === 'npm' ? 274 JSON : JSON5).parse(fs.readFileSync(rootPackageJsonPath, 'utf-8')); 275 } catch (e) { 276 throw Error('\u001b[31m' + 'BUIDERROR: ' + rootPackageJsonPath + ' format is invalid.' + '\u001b[39m').message; 277 } 278 if (rootPackageJsonContent) { 279 if (rootPackageJsonContent.module) { 280 getEntryPath(rootPackageJsonContent.module, rootPackageJsonPath); 281 } else if (rootPackageJsonContent.main) { 282 getEntryPath(rootPackageJsonContent.main, rootPackageJsonPath); 283 } else { 284 getEntryPath('', rootPackageJsonPath); 285 } 286 } else if (projectConfig.compileHar) { 287 throw Error('\u001b[31m' + 'BUIDERROR: lack message in ' + projectConfig.packageJson + '.' + 288 '\u001b[39m').message; 289 } 290 } 291} 292 293function supportSuffix(mainEntryPath) { 294 if (fs.existsSync(path.join(mainEntryPath, 'index.ets'))) { 295 mainEntryPath = path.join(mainEntryPath, 'index.ets'); 296 } else if (fs.existsSync(path.join(mainEntryPath, 'index.ts'))) { 297 mainEntryPath = path.join(mainEntryPath, 'index.ts'); 298 } else if (fs.existsSync(path.join(mainEntryPath, 'index.js'))) { 299 mainEntryPath = path.join(mainEntryPath, 'index.js'); 300 } else if (projectConfig.compileHar) { 301 throw Error('\u001b[31m' + 'BUIDERROR: not find entry file in ' + projectConfig.packageJson + 302 '.' + '\u001b[39m').message; 303 } 304 return mainEntryPath; 305} 306 307function supportExtName(mainEntryPath) { 308 if (path.extname(mainEntryPath) === '') { 309 if (fs.existsSync(mainEntryPath + '.ets')) { 310 mainEntryPath = mainEntryPath + '.ets'; 311 } else if (fs.existsSync(mainEntryPath + '.ts')) { 312 mainEntryPath = mainEntryPath + '.ts'; 313 } else if (fs.existsSync(mainEntryPath + '.js')) { 314 mainEntryPath = mainEntryPath + '.js'; 315 } 316 } 317 return mainEntryPath; 318} 319 320function getEntryPath(entryPath, rootPackageJsonPath) { 321 let mainEntryPath = path.resolve(rootPackageJsonPath, '../', entryPath); 322 if (fs.existsSync(mainEntryPath) && fs.statSync(mainEntryPath).isDirectory()) { 323 mainEntryPath = supportSuffix(mainEntryPath); 324 } else { 325 mainEntryPath = supportExtName(mainEntryPath); 326 } 327 if (fs.existsSync(mainEntryPath) && fs.statSync(mainEntryPath).isFile()) { 328 const entryKey = path.relative(projectConfig.projectPath, mainEntryPath); 329 projectConfig.entryObj[entryKey] = mainEntryPath; 330 setEntryArrayForObf(entryKey); 331 abilityPagesFullPath.add(path.resolve(mainEntryPath).toLowerCase()); 332 } else if (projectConfig.compileHar) { 333 throw Error('\u001b[31m' + `BUIDERROR: not find entry file in ${rootPackageJsonPath}.` + '\u001b[39m').message; 334 } 335} 336 337function stageOptimization(metadata) { 338 if (Array.isArray(metadata) && metadata.length) { 339 metadata.some(item => { 340 if (item.name && item.name === 'USE_COMMON_CHUNK' && 341 item.value && item.value === 'true') { 342 projectConfig.splitCommon = true; 343 return true; 344 } 345 }); 346 } 347} 348 349function getPages(configJson) { 350 const pages = []; 351 let pagesJsonFileName = ''; 352 // pages is not necessary in stage 353 if (process.env.compileMode === 'moduleJson' && configJson.module && configJson.module.pages) { 354 pagesJsonFileName = `${configJson.module.pages.replace(/\$profile\:/, '')}.json`; 355 } else { 356 return pages; 357 } 358 const modulePagePath = path.resolve(projectConfig.aceProfilePath, pagesJsonFileName); 359 if (fs.existsSync(modulePagePath)) { 360 try { 361 const pagesConfig = JSON.parse(fs.readFileSync(modulePagePath, 'utf-8')); 362 if (pagesConfig && pagesConfig.src) { 363 projectConfig.pagesJsonFileName = pagesJsonFileName; 364 return pagesConfig.src; 365 } 366 } catch (e) { 367 throw Error('\x1B[31m' + `BUIDERROR: the ${modulePagePath} file format is invalid.` + 368 '\x1B[39m').message; 369 } 370 } 371 return pages; 372} 373 374function setEntryFile(projectConfig) { 375 const entryFileName = abilityConfig.abilityType === 'page' ? 'app' : abilityConfig.abilityType; 376 const extendFile = entryFileName === 'app' ? '.ets' : '.ts'; 377 const entryFileRealPath = entryFileName + extendFile; 378 const entryFilePath = path.resolve(projectConfig.projectPath, entryFileRealPath); 379 abilityConfig.abilityEntryFile = entryFilePath; 380 if (!fs.existsSync(entryFilePath) && aceCompileMode === 'page') { 381 throw Error(`\u001b[31m ERROR: missing ${entryFilePath.replace(/\\/g, '/')}. \u001b[39m`).message; 382 } 383 projectConfig.entryObj[`./${entryFileName}`] = entryFilePath + '?entry'; 384 setEntryArrayForObf(entryFileName); 385} 386 387function setIntentEntryPages(projectConfig) { 388 projectConfig.intentEntry.forEach(pages => { 389 const entryKey = path.relative(projectConfig.projectPath, pages).replace(/\.(ets|ts|js)$/, ''); 390 projectConfig.entryObj[entryKey] = pages; 391 if (/\.ets$/.test(pages)) { 392 abilityPagesFullPath.add(path.resolve(pages).toLowerCase()); 393 } 394 }); 395} 396 397function setAbilityPages(projectConfig) { 398 let abilityPages = []; 399 if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { 400 const moduleJson = JSON.parse(fs.readFileSync(projectConfig.aceModuleJsonPath).toString()); 401 abilityPages = readAbilityEntrance(moduleJson); 402 setAbilityFile(projectConfig, abilityPages); 403 setBundleModuleInfo(projectConfig, moduleJson); 404 } 405} 406 407function setTestRunnerFile(projectConfig, isStageBased) { 408 const index = projectConfig.projectPath.split(path.sep).join('/').lastIndexOf('\/'); 409 TEST_RUNNER_DIR_SET.forEach((dir) => { 410 const projectPath = isStageBased ? projectConfig.projectPath : projectConfig.projectPath.substring(0, index + 1); 411 const testRunnerPath = path.resolve(projectPath, dir); 412 if (fs.existsSync(testRunnerPath) && folderExistsCaseSensitive(testRunnerPath)) { 413 const testRunnerFiles = []; 414 readFile(testRunnerPath, testRunnerFiles); 415 testRunnerFiles.forEach((item) => { 416 if (/\.(ts|js|ets)$/.test(item)) { 417 if (/\.ets$/.test(item)) { 418 abilityPagesFullPath.add(path.resolve(item).toLowerCase()); 419 } 420 const relativePath = path.relative(testRunnerPath, item).replace(/\.(ts|js|ets)$/, ''); 421 if (isStageBased) { 422 projectConfig.entryObj[`./${dir}/${relativePath}`] = item; 423 } else { 424 projectConfig.entryObj[`../${dir}/${relativePath}`] = item; 425 } 426 setEntryArrayForObf(dir, relativePath); 427 abilityConfig.testRunnerFile.push(item); 428 } 429 }); 430 } 431 }); 432} 433 434// entryPath: the filename of the entry file and the name of the outer directory. 435// The directory should be placed before the filename, and the filename must be the last argument. 436function setEntryArrayForObf(...entryPath) { 437 projectConfig.entryArrayForObf?.push(entryPath.join('/')); 438} 439 440function folderExistsCaseSensitive(folderPath) { 441 try { 442 const folders = fs.readdirSync(path.dirname(folderPath), { withFileTypes: true }) 443 .filter(entry => entry.isDirectory()) 444 .map(entry => entry.name); 445 const targetFolderName = path.basename(folderPath); 446 return folders.includes(targetFolderName); 447 } catch (error) { 448 return false; 449 } 450} 451 452function setFaTestRunnerFile(projectConfig) { 453 setTestRunnerFile(projectConfig, false); 454} 455 456function setStageTestRunnerFile(projectConfig) { 457 setTestRunnerFile(projectConfig, true); 458} 459 460function setBundleModuleInfo(projectConfig, moduleJson) { 461 if (moduleJson.module) { 462 projectConfig.moduleName = moduleJson.module.name; 463 } 464 if (moduleJson.app) { 465 projectConfig.bundleName = moduleJson.app.bundleName; 466 } 467} 468 469function setAbilityFile(projectConfig, abilityPages) { 470 abilityPages.forEach(abilityPath => { 471 const projectAbilityPath = path.resolve(projectConfig.projectPath, '../', abilityPath); 472 if (path.isAbsolute(abilityPath)) { 473 abilityPath = '.' + abilityPath.slice(projectConfig.projectPath.length); 474 } 475 const entryPageKey = abilityPath.replace(/^\.\/ets\//, './').replace(/\.ts$/, '').replace(/\.ets$/, ''); 476 if (fs.existsSync(projectAbilityPath)) { 477 abilityConfig.projectAbilityPath.push(projectAbilityPath); 478 projectConfig.entryObj[entryPageKey] = projectAbilityPath + '?entry'; 479 setEntryArrayForObf(entryPageKey); 480 } else { 481 throw Error( 482 `\u001b[31m ERROR: srcEntry file '${projectAbilityPath.replace(/\\/g, '/')}' does not exist. \u001b[39m` 483 ).message; 484 } 485 }); 486} 487 488function readAbilityEntrance(moduleJson) { 489 const abilityPages = []; 490 if (moduleJson.module) { 491 const moduleSrcEntrance = moduleJson.module.srcEntrance; 492 const moduleSrcEntry = moduleJson.module.srcEntry; 493 if (moduleSrcEntry) { 494 abilityPages.push(moduleSrcEntry); 495 abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, moduleSrcEntry)); 496 } else if (moduleSrcEntrance) { 497 abilityPages.push(moduleSrcEntrance); 498 abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, moduleSrcEntrance)); 499 } 500 if (moduleJson.module.abilities && moduleJson.module.abilities.length > 0) { 501 setEntrance(moduleJson.module.abilities, abilityPages); 502 } 503 if (moduleJson.module.extensionAbilities && moduleJson.module.extensionAbilities.length > 0) { 504 setEntrance(moduleJson.module.extensionAbilities, abilityPages); 505 setCardPages(moduleJson.module.extensionAbilities); 506 } 507 } 508 return abilityPages; 509} 510 511function setEntrance(abilityConfig, abilityPages) { 512 if (abilityConfig && abilityConfig.length > 0) { 513 abilityConfig.forEach(ability => { 514 if (ability.srcEntry) { 515 abilityPages.push(ability.srcEntry); 516 abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, ability.srcEntry)); 517 } else if (ability.srcEntrance) { 518 abilityPages.push(ability.srcEntrance); 519 abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, ability.srcEntrance)); 520 } 521 }); 522 } 523} 524 525function setCardPages(extensionAbilities) { 526 if (extensionAbilities && extensionAbilities.length > 0) { 527 extensionAbilities.forEach(extensionAbility => { 528 if (extensionAbility.metadata) { 529 extensionAbility.metadata.forEach(metadata => { 530 if (metadata.resource) { 531 readCardResource(metadata.resource); 532 } 533 }); 534 } 535 }); 536 } 537} 538 539function readCardResource(resource) { 540 const cardJsonFileName = `${resource.replace(/\$profile\:/, '')}.json`; 541 const modulePagePath = path.resolve(projectConfig.aceProfilePath, cardJsonFileName); 542 if (fs.existsSync(modulePagePath)) { 543 const cardConfig = JSON.parse(fs.readFileSync(modulePagePath, 'utf-8')); 544 if (cardConfig.forms) { 545 cardConfig.forms.forEach(form => { 546 readCardForm(form); 547 }); 548 } 549 } 550} 551 552function readCardForm(form) { 553 if ((form.type && form.type === 'eTS') || 554 (form.uiSyntax && form.uiSyntax === 'arkts')) { 555 const sourcePath = form.src.replace(/\.ets$/, ''); 556 const cardPath = path.resolve(projectConfig.projectPath, '..', sourcePath + '.ets'); 557 if (cardPath && fs.existsSync(cardPath)) { 558 projectConfig.entryObj['../' + sourcePath] = cardPath + '?entry'; 559 setEntryArrayForObf(sourcePath); 560 projectConfig.cardEntryObj['../' + sourcePath] = cardPath; 561 projectConfig.cardObj[cardPath] = sourcePath.replace(/^\.\//, ''); 562 } 563 } 564} 565 566function getAbilityFullPath(projectPath, abilityPath) { 567 const finalPath = path.resolve(path.resolve(projectPath, '../'), abilityPath); 568 if (fs.existsSync(finalPath)) { 569 return finalPath.toLowerCase(); 570 } else { 571 return path.resolve(abilityPath).toLowerCase(); 572 } 573} 574 575function loadWorker(projectConfig, workerFileEntry) { 576 if (workerFileEntry) { 577 projectConfig.entryObj = Object.assign(projectConfig.entryObj, workerFileEntry); 578 const keys = Object.keys(workerFileEntry); 579 for (const key of keys) { 580 setEntryArrayForObf(key); 581 } 582 } else { 583 const workerPath = path.resolve(projectConfig.projectPath, WORKERS_DIR); 584 if (fs.existsSync(workerPath)) { 585 const workerFiles = []; 586 readFile(workerPath, workerFiles); 587 workerFiles.forEach((item) => { 588 if (/\.(ts|js|ets)$/.test(item)) { 589 const relativePath = path.relative(workerPath, item) 590 .replace(/\.(ts|js|ets)$/, '').replace(/\\/g, '/'); 591 projectConfig.entryObj[`./${WORKERS_DIR}/` + relativePath] = item; 592 setEntryArrayForObf(WORKERS_DIR, relativePath); 593 abilityPagesFullPath.add(path.resolve(item).toLowerCase()); 594 } 595 }); 596 } 597 } 598} 599 600let aceBuildJson = {}; 601function loadBuildJson() { 602 if (projectConfig.aceBuildJson && fs.existsSync(projectConfig.aceBuildJson)) { 603 aceBuildJson = JSON.parse(fs.readFileSync(projectConfig.aceBuildJson).toString()); 604 } 605 if (aceBuildJson.packageManagerType === 'ohpm') { 606 projectConfig.packageManagerType = 'ohpm'; 607 projectConfig.packageDir = 'oh_modules'; 608 projectConfig.packageJson = 'oh-package.json5'; 609 } 610 // add intent framework entry file 611 projectConfig.intentEntry = aceBuildJson.compileEntry || []; 612 if (!!aceBuildJson.otherCompileFiles) { 613 aceBuildJson.otherCompileFiles.forEach(pages => { 614 const entryKey = path.relative(projectConfig.projectPath, pages).replace(/\.(ets|ts|js|mjs|cjs)$/, ''); 615 projectConfig.otherCompileFiles[entryKey] = pages; 616 if (/\.ets$/.test(pages)) { 617 abilityPagesFullPath.add(path.resolve(pages).toLowerCase()); 618 } 619 }); 620 } 621 if (!!aceBuildJson.byteCodeHar) { 622 projectConfig.useTsHar = true; 623 } 624 if (aceBuildJson.updateVersionInfo) { 625 projectConfig.updateVersionInfo = aceBuildJson.updateVersionInfo; 626 } 627} 628 629function initBuildInfo() { 630 projectConfig.projectRootPath = aceBuildJson.projectRootPath; 631 if (projectConfig.compileHar && aceBuildJson.moduleName && 632 aceBuildJson.modulePathMap[aceBuildJson.moduleName]) { 633 projectConfig.moduleRootPath = aceBuildJson.modulePathMap[aceBuildJson.moduleName]; 634 } 635} 636 637function readWorkerFile() { 638 const workerFileEntry = {}; 639 if (aceBuildJson.workers) { 640 aceBuildJson.workers.forEach(worker => { 641 if (!/\.(ts|js|ets)$/.test(worker)) { 642 throw Error( 643 '\u001b[31m10906402 ArkTS Compiler Error' + '\n' + 644 'Error Message: ' + 'File: ' + worker + '.' + '\n' + 645 "The worker file can only be an '.ets', '.ts', or '.js' file.\u001b[39m" 646 ).message; 647 } 648 const relativePath = path.relative(projectConfig.projectPath, worker); 649 if (filterWorker(relativePath)) { 650 const workerKey = relativePath.replace(/\.(ts|js)$/, '').replace(/\\/g, '/'); 651 if (workerFileEntry[workerKey]) { 652 throw Error( 653 '\u001b[31m10905407 ArkTS Compiler Error' + '\n' + 654 'Error Message: ' + 'The worker file cannot use the same file name: \n' + 655 workerFileEntry[workerKey] + '\n' + worker + '\u001b[39m' 656 ).message; 657 } else { 658 workerFileEntry[workerKey] = worker; 659 abilityPagesFullPath.add(path.resolve(workerFileEntry[workerKey]).toLowerCase()); 660 } 661 } 662 }); 663 return workerFileEntry; 664 } 665 return null; 666} 667 668function readPatchConfig() { 669 if (aceBuildJson.patchConfig) { 670 projectConfig.hotReload = (process.env.watchMode === 'true' && !projectConfig.isPreview) || 671 aceBuildJson.patchConfig.mode === 'hotReload'; 672 projectConfig.coldReload = aceBuildJson.patchConfig.mode === COLD_RELOAD_MODE ? true : false; 673 // The "isFirstBuild" field indicates whether it is the first compilation of cold reload mode 674 // It is determined by hvigor and passed via env 675 projectConfig.isFirstBuild = process.env.isFirstBuild === 'false' ? false : true; 676 projectConfig.patchAbcPath = aceBuildJson.patchConfig.patchAbcPath; 677 projectConfig.changedFileList = aceBuildJson.patchConfig.changedFileList ? 678 aceBuildJson.patchConfig.changedFileList : path.join(projectConfig.cachePath, 'changedFileList.json'); 679 projectConfig.removeChangedFileListInSdk = aceBuildJson.patchConfig.removeChangedFileListInSdk === 'true' || false; 680 if (!projectConfig.removeChangedFileListInSdk && projectConfig.hotReload) { 681 writeFileSync(projectConfig.changedFileList, JSON.stringify({ 682 modifiedFiles: [], 683 removedFiles: [] 684 })); 685 } 686 } 687} 688 689function filterWorker(workerPath) { 690 return /\.(ts|js|ets)$/.test(workerPath); 691} 692 693;(function initSystemResource() { 694 const sysResourcePath = path.resolve(__dirname, './sysResource.js'); 695 if (fs.existsSync(sysResourcePath)) { 696 resources.sys = require(sysResourcePath).sys; 697 } 698 if (!process.env.externalApiPaths) { 699 return; 700 } 701 const sdkPaths = process.env.externalApiPaths.split(path.delimiter); 702 for (let i = 0; i < sdkPaths.length; i++) { 703 const sysResourceExtPath = path.resolve(__dirname, sdkPaths[i], 'sysResource.js'); 704 if (!fs.existsSync(sysResourceExtPath)) { 705 continue; 706 } 707 Object.entries(require(sysResourceExtPath).sys).forEach(([key, value]) => { 708 if (key in resources.sys) { 709 Object.assign(resources.sys[key], value); 710 } 711 }); 712 } 713})(); 714 715;(function readSystemModules() { 716 const apiDirPath = path.resolve(__dirname, '../../api'); 717 const arktsDirPath = path.resolve(__dirname, '../../arkts'); 718 const kitsDirPath = path.resolve(__dirname, '../../kits'); 719 const systemModulePathArray = [apiDirPath]; 720 if (!process.env.isFaMode) { 721 systemModulePathArray.push(arktsDirPath, kitsDirPath); 722 } 723 systemModulePathArray.forEach(systemModulesPath => { 724 if (fs.existsSync(systemModulesPath)) { 725 globalModulePaths.push(systemModulesPath); 726 const modulePaths = []; 727 readFile(systemModulesPath, modulePaths); 728 systemModules.push(...fs.readdirSync(systemModulesPath)); 729 ohosSystemModulePaths.push(...modulePaths); 730 const moduleSubdir = modulePaths.filter(filePath => { 731 const dirName = path.dirname(filePath); 732 return !(dirName === apiDirPath || dirName === arktsDirPath || dirName === kitsDirPath); 733 }).map(filePath => { 734 return filePath 735 .replace(apiDirPath, '') 736 .replace(arktsDirPath, '') 737 .replace(kitsDirPath, '') 738 .replace(/\\/g, '/') 739 .replace(/(^\/)|(.d.e?ts$)/g, ''); 740 }); 741 ohosSystemModuleSubDirPaths.push(...moduleSubdir); 742 allModulesPaths.push(...modulePaths); 743 } 744 }); 745 defaultSdkConfigs = [ 746 { 747 'apiPath': systemModulePathArray, 748 'prefix': '@ohos' 749 }, { 750 'apiPath': systemModulePathArray, 751 'prefix': '@system' 752 }, { 753 'apiPath': systemModulePathArray, 754 'prefix': '@arkts' 755 } 756 ]; 757 const externalApiPathStr = process.env.externalApiPaths || ''; 758 const externalApiPaths = externalApiPathStr.split(path.delimiter); 759 collectExternalModules(externalApiPaths); 760 sdkConfigs = [...defaultSdkConfigs, ...extendSdkConfigs]; 761})(); 762 763function collectExternalModules(sdkPaths) { 764 for (let i = 0; i < sdkPaths.length; i++) { 765 const sdkPath = sdkPaths[i]; 766 const sdkConfigPath = path.resolve(sdkPath, 'sdkConfig.json'); 767 if (!fs.existsSync(sdkConfigPath)) { 768 continue; 769 } 770 const sdkConfig = JSON.parse(fs.readFileSync(sdkConfigPath, 'utf-8')); 771 if (!sdkConfig.apiPath) { 772 continue; 773 } 774 let externalApiPathArray = []; 775 if (Array.isArray(sdkConfig.apiPath)) { 776 externalApiPathArray = sdkConfig.apiPath; 777 } else { 778 externalApiPathArray.push(sdkConfig.apiPath); 779 } 780 const resolveApiPathArray = []; 781 externalApiPathArray.forEach(element => { 782 const resolvePath = path.resolve(sdkPath, element); 783 resolveApiPathArray.push(resolvePath); 784 if (fs.existsSync(resolvePath)) { 785 const extrenalModulePaths = []; 786 globalModulePaths.push(resolvePath); 787 systemModules.push(...fs.readdirSync(resolvePath)); 788 readFile(resolvePath, extrenalModulePaths); 789 allModulesPaths.push(...extrenalModulePaths); 790 } 791 }); 792 sdkConfigPrefix += `|${sdkConfig.prefix.replace(/^@/, '')}`; 793 sdkConfig.apiPath = resolveApiPathArray; 794 extendSdkConfigs.push(sdkConfig); 795 } 796} 797 798function readHspResource() { 799 if (aceBuildJson.hspResourcesMap) { 800 projectConfig.hspResourcesMap = true; 801 for (const hspName in aceBuildJson.hspResourcesMap) { 802 if (fs.existsSync(aceBuildJson.hspResourcesMap[hspName])) { 803 const resourceMap = new Map(); 804 const hspResourceCollect = resources[hspName] = {}; 805 const hspResource = fs.readFileSync(aceBuildJson.hspResourcesMap[hspName], 'utf-8'); 806 const resourceArr = hspResource.split(/\n/); 807 processResourceArr(resourceArr, resourceMap, aceBuildJson.hspResourcesMap[hspName]); 808 for (const [key, value] of resourceMap) { 809 hspResourceCollect[key] = value; 810 } 811 } 812 } 813 } 814} 815 816function readAppResource(filePath) { 817 readHspResource(); 818 if (fs.existsSync(filePath)) { 819 const appResource = fs.readFileSync(filePath, 'utf-8'); 820 const resourceArr = appResource.split(/\n/); 821 const resourceMap = new Map(); 822 processResourceArr(resourceArr, resourceMap, filePath); 823 for (let [key, value] of resourceMap) { 824 resources.app[key] = value; 825 } 826 } 827 if (process.env.rawFileResource && process.env.compileMode === 'moduleJson') { 828 resourcesRawfile(process.env.rawFileResource, getStoredFileInfo().resourcesArr); 829 } 830} 831 832function processResourceArr(resourceArr, resourceMap, filePath) { 833 for (let i = 0; i < resourceArr.length; i++) { 834 if (!resourceArr[i].length) { 835 continue; 836 } 837 const resourceData = resourceArr[i].split(/\s/); 838 if (resourceData.length === 3 && !isNaN(Number(resourceData[2]))) { 839 if (resourceMap.get(resourceData[0])) { 840 const resourceKeys = resourceMap.get(resourceData[0]); 841 if (!resourceKeys[resourceData[1]] || resourceKeys[resourceData[1]] !== Number(resourceData[2])) { 842 resourceKeys[resourceData[1]] = Number(resourceData[2]); 843 } 844 } else { 845 let obj = {}; 846 obj[resourceData[1]] = Number(resourceData[2]); 847 resourceMap.set(resourceData[0], obj); 848 } 849 if (process.env.compileTool === 'rollup' && process.env.compileMode === 'moduleJson') { 850 getStoredFileInfo().updateResourceList(resourceData[0] + '_' + resourceData[1]); 851 } 852 } else { 853 logger.warn(`\u001b[31m ArkTS:WARN The format of file '${filePath}' is incorrect. \u001b[39m`); 854 break; 855 } 856 } 857} 858 859function hashProjectPath(projectPath) { 860 const hash = crypto.createHash('sha256'); 861 hash.update(projectPath.toString()); 862 process.env.hashProjectPath = '_' + hash.digest('hex'); 863 return process.env.hashProjectPath; 864} 865 866function loadModuleInfo(projectConfig, envArgs) { 867 if (projectConfig.aceBuildJson && fs.existsSync(projectConfig.aceBuildJson)) { 868 const buildJsonInfo = JSON.parse(fs.readFileSync(projectConfig.aceBuildJson).toString()); 869 if (buildJsonInfo.compileMode) { 870 projectConfig.compileMode = buildJsonInfo.compileMode; 871 } 872 projectConfig.projectRootPath = buildJsonInfo.projectRootPath; 873 projectConfig.modulePathMap = buildJsonInfo.modulePathMap; 874 projectConfig.isOhosTest = buildJsonInfo.isOhosTest; 875 let faultHandler = function (error) { 876 // rollup's error will be handled in fast build 877 if (process.env.compileTool === 'rollup') { 878 return; 879 } 880 logger.error(error); 881 process.exit(FAIL); 882 }; 883 projectConfig.es2abcCompileTsInAotMode = true; 884 projectConfig.es2abcCompileTsInNonAotMode = false; 885 const compileMode = process.env.compileTool === 'rollup' ? projectConfig.compileMode : buildJsonInfo.compileMode; 886 if (checkAotConfig(compileMode, buildJsonInfo, faultHandler)) { 887 projectConfig.processTs = true; 888 projectConfig.pandaMode = TS2ABC; 889 projectConfig.anBuildOutPut = buildJsonInfo.anBuildOutPut; 890 projectConfig.anBuildMode = buildJsonInfo.anBuildMode; 891 projectConfig.apPath = buildJsonInfo.apPath; 892 if (projectConfig.es2abcCompileTsInAotMode) { 893 projectConfig.pandaMode = ES2ABC; 894 } 895 } else { 896 projectConfig.processTs = false; 897 projectConfig.pandaMode = buildJsonInfo.pandaMode; 898 if (projectConfig.es2abcCompileTsInNonAotMode) { 899 projectConfig.pandaMode = ES2ABC; 900 projectConfig.processTs = true; 901 } 902 } 903 if (envArgs !== undefined) { 904 projectConfig.buildArkMode = envArgs.buildMode; 905 } 906 if (compileMode === 'esmodule') { 907 projectConfig.nodeModulesPath = buildJsonInfo.nodeModulesPath; 908 projectConfig.harNameOhmMap = buildJsonInfo.harNameOhmMap; 909 } 910 if (projectConfig.compileHar && buildJsonInfo.moduleName && 911 buildJsonInfo.modulePathMap[buildJsonInfo.moduleName]) { 912 if (projectConfig.useTsHar) { 913 projectConfig.processTs = true; 914 } 915 projectConfig.moduleRootPath = buildJsonInfo.modulePathMap[buildJsonInfo.moduleName]; 916 } 917 } 918} 919 920function checkAppResourcePath(appResourcePath, config) { 921 if (appResourcePath) { 922 readAppResource(appResourcePath); 923 if (fs.existsSync(appResourcePath) && config.cache) { 924 config.cache.buildDependencies.config.push(appResourcePath); 925 } 926 if (!projectConfig.xtsMode) { 927 const appResourcePathSavePath = path.resolve(projectConfig.cachePath, 'resource_path.txt'); 928 saveAppResourcePath(appResourcePath, appResourcePathSavePath); 929 if (fs.existsSync(appResourcePathSavePath) && config.cache) { 930 config.cache.buildDependencies.config.push(appResourcePathSavePath); 931 } 932 } 933 } 934} 935 936function saveAppResourcePath(appResourcePath, appResourcePathSavePath) { 937 let isSave = false; 938 if (fs.existsSync(appResourcePathSavePath)) { 939 const saveContent = fs.readFileSync(appResourcePathSavePath); 940 if (appResourcePath !== saveContent) { 941 isSave = true; 942 } 943 } else { 944 isSave = true; 945 } 946 if (isSave) { 947 fs.writeFileSync(appResourcePathSavePath, appResourcePath); 948 } 949} 950 951function addSDKBuildDependencies(config) { 952 if (projectConfig.localPropertiesPath && 953 fs.existsSync(projectConfig.localPropertiesPath) && config.cache) { 954 config.cache.buildDependencies.config.push(projectConfig.localPropertiesPath); 955 } 956 if (projectConfig.projectProfilePath && 957 fs.existsSync(projectConfig.projectProfilePath) && config.cache) { 958 config.cache.buildDependencies.config.push(projectConfig.projectProfilePath); 959 } 960} 961 962function getCleanConfig(workerFile) { 963 const cleanPath = []; 964 if (projectConfig.compileMode === 'esmodule') { 965 return cleanPath; 966 } 967 cleanPath.push(projectConfig.buildPath); 968 if (workerFile) { 969 const workerFilesPath = Object.keys(workerFile); 970 for (const workerFilePath of workerFilesPath) { 971 cleanPath.push(path.join(projectConfig.buildPath, workerFilePath, '..')); 972 } 973 } 974 return cleanPath; 975} 976 977function isPartialUpdate(metadata, moduleType) { 978 if (!Array.isArray(metadata) || !metadata.length) { 979 return; 980 } 981 metadata.some(item => { 982 if (item.name && item.value) { 983 if (item.name === 'ArkTSPartialUpdate' && item.value === 'false') { 984 partialUpdateConfig.partialUpdateMode = false; 985 if (projectConfig.aceModuleJsonPath) { 986 logger.warn('\u001b[33m ArkTS:WARN File: ' + projectConfig.aceModuleJsonPath + '.' + '\n' + 987 " The 'ArkTSPartialUpdate' field will no longer be supported in the future. \u001b[39m"); 988 } 989 } 990 if (item.name === 'ArkTSBuilderCheck' && item.value === 'false') { 991 partialUpdateConfig.builderCheck = false; 992 } 993 if (item.name === 'Api11ArkTSCheck' && item.value === 'SkipArkTSCheckInApi11') { 994 partialUpdateConfig.executeArkTSLinter = false; 995 } 996 if (item.name === 'Api11ArkTSCheckMode' && item.value === 'DoArkTSCheckInCompatibleModeInApi11') { 997 partialUpdateConfig.standardArkTSLinter = false; 998 } 999 if (item.name === 'ArkoalaPlugin' && item.value === 'true') { 1000 projectConfig.useArkoala = true; 1001 } 1002 if (item.name === 'ArkTSVersion') { 1003 partialUpdateConfig.arkTSVersion = item.value; 1004 } 1005 if (item.name === 'OPTLazyForEach' && item.value === 'true') { 1006 projectConfig.optLazyForEach = true; 1007 } 1008 if (item.name === 'SkipTscOhModuleCheck' && item.value === 'true') { 1009 partialUpdateConfig.skipTscOhModuleCheck = true; 1010 } 1011 if (item.name === 'SkipArkTSStaticBlocksCheck' && item.value === 'true') { 1012 partialUpdateConfig.skipArkTSStaticBlocksCheck = true; 1013 } 1014 if (item.name === 'UseTsHar' && item.value === 'true' && moduleType === 'har') { 1015 projectConfig.useTsHar = true; 1016 } 1017 if (item.name === 'OptTryCatchFunc' && item.value === 'false') { 1018 projectConfig.optTryCatchFunc = false; 1019 } 1020 } 1021 return !partialUpdateConfig.partialUpdateMode && !partialUpdateConfig.builderCheck && 1022 !partialUpdateConfig.executeArkTSLinter && !partialUpdateConfig.standardArkTSLinter && 1023 partialUpdateConfig.arkTSVersion !== undefined && projectConfig.optLazyForEach && 1024 partialUpdateConfig.skipTscOhModuleCheck && partialUpdateConfig.skipArkTSStaticBlocksCheck; 1025 }); 1026} 1027 1028function applicationConfig() { 1029 const localProperties = path.resolve(aceBuildJson.projectRootPath, 'local.properties'); 1030 if (fs.existsSync(localProperties)) { 1031 try { 1032 const localPropertiesFile = fs.readFileSync(localProperties, {encoding: 'utf-8'}).split(/\r?\n/); 1033 localPropertiesFile.some((item) => { 1034 const builderCheckValue = item.replace(/\s+|;/g, ''); 1035 if (builderCheckValue === 'ArkTSConfig.ArkTSBuilderCheck=false') { 1036 partialUpdateConfig.builderCheck = false; 1037 return true; 1038 } 1039 }); 1040 } catch (err) { 1041 } 1042 } 1043} 1044 1045function partialUpdateController(minAPIVersion, metadata = null, moduleType = '') { 1046 projectConfig.minAPIVersion = minAPIVersion; 1047 if (minAPIVersion >= 9) { 1048 partialUpdateConfig.partialUpdateMode = true; 1049 } 1050 const MIN_VERSION_OPTIMIZE_COMPONENT = 10; 1051 if (minAPIVersion < MIN_VERSION_OPTIMIZE_COMPONENT) { 1052 partialUpdateConfig.optimizeComponent = false; 1053 } 1054 if (metadata) { 1055 isPartialUpdate(metadata, moduleType); 1056 } 1057 if (aceBuildJson.projectRootPath) { 1058 applicationConfig(); 1059 } 1060} 1061 1062const globalProgram = { 1063 builderProgram: null, 1064 program: null, 1065 watchProgram: null, 1066 checker: null, 1067 strictChecker: null, 1068 strictLanguageService: null, 1069}; 1070 1071const partialUpdateConfig = { 1072 partialUpdateMode: false, 1073 builderCheck: true, 1074 executeArkTSLinter: true, 1075 standardArkTSLinter: true, 1076 optimizeComponent: true, 1077 arkTSVersion: undefined, 1078 skipTscOhModuleCheck: false, 1079 skipArkTSStaticBlocksCheck: false 1080}; 1081 1082function resetMain() { 1083 staticPreviewPage = undefined; 1084 aceCompileMode = 'page'; 1085 resetAbilityConfig(); 1086 resetProjectConfig(); 1087 resources.app = {}; 1088 abilityPagesFullPath.clear(); 1089 aceBuildJson = {}; 1090 partialUpdateConfig.builderCheck = true; 1091 globalModulePaths = []; 1092 sdkConfigs = []; 1093 defaultSdkConfigs = []; 1094 extendSdkConfigs = []; 1095 sdkConfigPrefix = 'ohos|system|kit'; 1096 ohosSystemModulePaths = []; 1097 ohosSystemModuleSubDirPaths = []; 1098 allModulesPaths = []; 1099} 1100 1101function resetAbilityConfig() { 1102 abilityConfig.abilityType = 'page'; 1103 abilityConfig.abilityEntryFile = null; 1104 abilityConfig.projectAbilityPath = []; 1105 abilityConfig.testRunnerFile = []; 1106} 1107 1108function resetProjectConfig() { 1109 projectConfig.entryObj = {}; 1110 projectConfig.entryArrayForObf = []; 1111 projectConfig.cardObj = {}; 1112 projectConfig.compileHar = false; 1113 projectConfig.compileShared = false; 1114 projectConfig.packageDir = 'node_modules'; 1115 projectConfig.packageJson = 'package.json'; 1116 projectConfig.packageManagerType = 'npm'; 1117 projectConfig.cardEntryObj = {}; 1118 projectConfig.compilerTypes = []; 1119 projectConfig.optLazyForEach = false; 1120 projectConfig.hspResourcesMap = false; 1121 projectConfig.coldReload = undefined; 1122 projectConfig.hotReload = undefined; 1123 projectConfig.isFirstBuild = undefined; 1124 projectConfig.changedFileList = undefined; 1125 projectConfig.patchAbcPath = undefined; 1126 projectConfig.removeChangedFileListInSdk = false; 1127 projectConfig.allowEmptyBundleName = false; 1128 projectConfig.uiTransformOptimization = false; 1129 projectConfig.ignoreCrossplatformCheck = false; 1130 const props = ['projectPath', 'buildPath', 'aceModuleBuild', 'manifestFilePath', 'aceProfilePath', 1131 'aceModuleJsonPath', 'aceSuperVisualPath', 'hashProjectPath', 'aceBuildJson', 'cachePath', 1132 'aceSoPath', 'localPropertiesPath', 'projectProfilePath', 'isPreview', 'compileMode', 'runtimeOS', 1133 'sdkInfo', 'checkEntry', 'obfuscateHarType', 'isCrossplatform', 'enableDebugLine', 'bundleType' 1134 ]; 1135 for (let key in projectConfig) { 1136 if (props.includes(key)) { 1137 projectConfig[key] = undefined; 1138 } 1139 } 1140 projectConfig.otherCompileFiles = {}; 1141 projectConfig.updateVersionInfo = undefined; 1142} 1143 1144function resetGlobalProgram() { 1145 globalProgram.builderProgram = null; 1146 globalProgram.program = null; 1147 globalProgram.checker = null; 1148 globalProgram.strictChecker = null; 1149 globalProgram.strictLanguageService = null; 1150} 1151 1152function initMain() { 1153 staticPreviewPage = process.env.aceStaticPreview; 1154 aceCompileMode = process.env.aceCompileMode || 'page'; 1155 abilityConfig.abilityType = process.env.abilityType || 'page'; 1156} 1157 1158exports.globalProgram = globalProgram; 1159exports.projectConfig = projectConfig; 1160exports.loadEntryObj = loadEntryObj; 1161exports.readAppResource = readAppResource; 1162exports.resources = resources; 1163exports.loadWorker = loadWorker; 1164exports.abilityConfig = abilityConfig; 1165exports.readWorkerFile = readWorkerFile; 1166exports.abilityPagesFullPath = abilityPagesFullPath; 1167exports.loadModuleInfo = loadModuleInfo; 1168exports.systemModules = systemModules; 1169exports.checkAppResourcePath = checkAppResourcePath; 1170exports.addSDKBuildDependencies = addSDKBuildDependencies; 1171exports.partialUpdateConfig = partialUpdateConfig; 1172exports.readPatchConfig = readPatchConfig; 1173exports.initBuildInfo = initBuildInfo; 1174exports.getCleanConfig = getCleanConfig; 1175exports.globalModulePaths = globalModulePaths; 1176exports.defaultSdkConfigs = defaultSdkConfigs; 1177exports.extendSdkConfigs = extendSdkConfigs; 1178exports.sdkConfigs = sdkConfigs; 1179exports.sdkConfigPrefix = sdkConfigPrefix; 1180exports.ohosSystemModulePaths = ohosSystemModulePaths; 1181exports.resetMain = resetMain; 1182exports.ohosSystemModuleSubDirPaths = ohosSystemModuleSubDirPaths; 1183exports.allModulesPaths = allModulesPaths; 1184exports.resetProjectConfig = resetProjectConfig; 1185exports.resetGlobalProgram = resetGlobalProgram; 1186exports.setEntryArrayForObf = setEntryArrayForObf; 1187exports.getPackageJsonEntryPath = getPackageJsonEntryPath; 1188exports.setIntentEntryPages = setIntentEntryPages; 1189