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