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