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