• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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
16import cluster from 'cluster';
17import fs from 'fs';
18import path from 'path';
19import os from 'os';
20
21import {
22  DEBUG,
23  ESMODULE,
24  EXTNAME_ETS,
25  EXTNAME_JS,
26  EXTNAME_TS,
27  EXTNAME_JSON,
28  EXTNAME_CJS,
29  EXTNAME_MJS,
30  TEMPORARY
31} from './common/ark_define';
32import {
33  nodeLargeOrEqualTargetVersion,
34  genTemporaryPath,
35  mkdirsSync,
36  validateFilePathLength,
37  toUnixPath
38} from '../../utils';
39import {
40  writeMinimizedSourceCode
41} from '../../ark_utils';
42import { AOT_FULL, AOT_PARTIAL, AOT_TYPE } from '../../pre_define';
43import { newSourceMaps } from './transform';
44
45export function needAotCompiler(projectConfig: any): boolean {
46  return projectConfig.compileMode === ESMODULE && (projectConfig.anBuildMode === AOT_FULL ||
47    projectConfig.anBuildMode === AOT_PARTIAL);
48}
49
50export function isAotMode(projectConfig: any): boolean {
51  return projectConfig.compileMode === ESMODULE && (projectConfig.anBuildMode === AOT_FULL ||
52    projectConfig.anBuildMode === AOT_PARTIAL || projectConfig.anBuildMode === AOT_TYPE);
53}
54
55export function isDebug(projectConfig: any): boolean {
56  return projectConfig.buildMode.toLowerCase() === DEBUG;
57}
58
59export function isMasterOrPrimary() {
60  return ((nodeLargeOrEqualTargetVersion(16) && cluster.isPrimary) ||
61    (!nodeLargeOrEqualTargetVersion(16) && cluster.isMaster));
62}
63
64export function changeFileExtension(file: string, targetExt: string, originExt = ''): string {
65  let currentExt = originExt.length === 0 ? path.extname(file) : originExt;
66  let fileWithoutExt = file.substring(0, file.lastIndexOf(currentExt));
67  return fileWithoutExt + targetExt;
68}
69
70export async function writeFileContentToTempDir(id: string, content: string, projectConfig: any, logger: any) {
71  if (isCommonJsPluginVirtualFile(id)) {
72    return;
73  }
74
75  if (!isCurrentProjectFiles(id, projectConfig)) {
76    return;
77  }
78
79  let filePath: string;
80  if (projectConfig.compileHar) {
81    // compileShared: compile shared har of project
82    filePath = genTemporaryPath(id,
83      projectConfig.compileShared ? projectConfig.projectRootPath : projectConfig.moduleRootPath,
84      projectConfig.compileShared ? path.resolve(projectConfig.aceModuleBuild, '../etsFortgz') : projectConfig.cachePath,
85      projectConfig, projectConfig.compileShared);
86  } else {
87    filePath = genTemporaryPath(id, projectConfig.projectPath, projectConfig.cachePath, projectConfig);
88  }
89
90  switch (path.extname(id)) {
91    case EXTNAME_ETS:
92    case EXTNAME_TS:
93    case EXTNAME_JS:
94    case EXTNAME_MJS:
95    case EXTNAME_CJS:
96      await writeFileContent(id, filePath, content, projectConfig, logger);
97      break;
98    case EXTNAME_JSON:
99      mkdirsSync(path.dirname(filePath));
100      fs.writeFileSync(filePath, content, 'utf-8');
101      break;
102    default:
103      break;
104  }
105}
106
107async function writeFileContent(sourceFilePath: string, filePath: string, content: string, projectConfig: any, logger: any) {
108  if (!isSpecifiedExt(sourceFilePath, EXTNAME_JS)) {
109    filePath = changeFileExtension(filePath, EXTNAME_JS);
110  }
111
112  mkdirsSync(path.dirname(filePath));
113  // In compile har mode, the code needs to be obfuscated and compressed.
114  const isHar: boolean = projectConfig.compileHar && projectConfig.obfuscate === 'uglify';
115  if (isHar || !isDebug(projectConfig)) {
116    const relativeSourceFilePath: string = toUnixPath(sourceFilePath).replace(toUnixPath(projectConfig.projectRootPath)
117      + '/', '');
118    await writeMinimizedSourceCode(content, filePath, logger, isHar, relativeSourceFilePath, newSourceMaps);
119    return;
120  }
121
122  fs.writeFileSync(filePath, content, 'utf-8');
123}
124
125export function getEs2abcFileThreadNumber(): number {
126  const fileThreads : number = os.cpus().length < 16 ? os.cpus().length : 16;
127  return fileThreads;
128}
129
130export function isCommonJsPluginVirtualFile(filePath: string): boolean {
131  // rollup uses commonjs plugin to handle commonjs files,
132  // which will automatic generate files like 'jsfile.js?commonjs-exports'
133  return filePath.includes('\x00');
134}
135
136export function isCurrentProjectFiles(filePath: string, projectConfig: any): boolean {
137  return filePath.indexOf(projectConfig.projectRootPath) >= 0;
138}
139
140export function genTemporaryModuleCacheDirectoryForBundle(projectConfig: any) {
141  const buildDirArr: string[] = projectConfig.aceModuleBuild.split(path.sep);
142  const abilityDir: string = buildDirArr[buildDirArr.length - 1];
143  const temporaryModuleCacheDirPath: string = path.join(projectConfig.cachePath, TEMPORARY, abilityDir);
144  mkdirsSync(temporaryModuleCacheDirPath);
145
146  return temporaryModuleCacheDirPath;
147}
148
149export function isSpecifiedExt(filePath: string, fileExtendName: string) {
150  return path.extname(filePath) === fileExtendName;
151}
152
153export function genCachePath(tailName: string, projectConfig: any, logger: any): string {
154  const pathName: string = projectConfig.cachePath !== undefined ?
155    path.join(projectConfig.cachePath, TEMPORARY, tailName) : path.join(projectConfig.aceModuleBuild, tailName);
156  mkdirsSync(path.dirname(pathName));
157
158  validateFilePathLength(pathName, logger);
159  return pathName;
160}
161
162export function isTsOrEtsSourceFile(file: string): boolean {
163  return /(?<!\.d)\.[e]?ts$/.test(file);
164}
165
166export function isJsSourceFile(file: string): boolean {
167  return /\.[cm]?js$/.test(file);
168}
169
170export function isJsonSourceFile(file: string): boolean {
171  return /\.json$/.test(file);
172}
173