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