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