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