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 path from 'path'; 17import ts from 'typescript'; 18import fs from 'fs'; 19 20import { newSourceMaps as rollupNewSourceMaps } from './fast_build/ark_compiler/transform'; 21import { 22 EXTNAME_TS, 23 EXTNAME_ETS, 24} from './pre_define'; 25import { 26 genTemporaryPath, 27 mkdirsSync, 28 toUnixPath, 29} from './utils'; 30import { 31 genSourceMapFileName, 32 newSourceMaps as webpackNewSourceMaps, 33 transformModuleSpecifier, 34 writeObfuscatedSourceCode 35} from './ark_utils'; 36import { processSystemApi } from './validate_ui_syntax'; 37import { isAotMode, isDebug } from './fast_build/ark_compiler/utils'; 38 39export const SRC_MAIN: string = 'src/main'; 40 41export async function writeFileSyncByNode(node: ts.SourceFile, projectConfig: any, logger?: any): Promise<void> { 42 const mixedInfo: {content: string, sourceMapJson: any} = genContentAndSourceMapInfo(node, projectConfig); 43 let temporaryFile: string = genTemporaryPath(node.fileName, projectConfig.projectPath, process.env.cachePath, 44 projectConfig); 45 if (temporaryFile.length === 0) { 46 return; 47 } 48 let temporarySourceMapFile: string = ''; 49 if (temporaryFile.endsWith(EXTNAME_ETS)) { 50 temporaryFile = temporaryFile.replace(/\.ets$/, EXTNAME_TS); 51 } 52 temporarySourceMapFile = genSourceMapFileName(temporaryFile); 53 mkdirsSync(path.dirname(temporaryFile)); 54 let relativeSourceFilePath = toUnixPath(node.fileName).replace(toUnixPath(projectConfig.projectRootPath) + '/', ''); 55 let sourceMaps: Object; 56 if (process.env.compileTool === 'rollup') { 57 rollupNewSourceMaps[relativeSourceFilePath] = mixedInfo.sourceMapJson; 58 sourceMaps = rollupNewSourceMaps; 59 } else { 60 webpackNewSourceMaps[relativeSourceFilePath] = mixedInfo.sourceMapJson; 61 sourceMaps = webpackNewSourceMaps; 62 } 63 if (projectConfig.compileHar || (!isDebug(projectConfig) && isAotMode(projectConfig))) { 64 await writeObfuscatedSourceCode(mixedInfo.content, temporaryFile, logger, projectConfig, relativeSourceFilePath, sourceMaps); 65 return; 66 } 67 fs.writeFileSync(temporaryFile, mixedInfo.content); 68} 69 70function genContentAndSourceMapInfo(node: ts.SourceFile, projectConfig: any): any { 71 const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); 72 const options: ts.CompilerOptions = { 73 sourceMap: true 74 }; 75 const mapOpions: any = { 76 sourceMap: true, 77 inlineSourceMap: false, 78 inlineSources: false, 79 sourceRoot: '', 80 mapRoot: '', 81 extendedDiagnostics: false 82 }; 83 const host: ts.CompilerHost = ts.createCompilerHost(options); 84 const fileName: string = node.fileName; 85 // @ts-ignore 86 const sourceMapGenerator: any = ts.createSourceMapGenerator( 87 host, 88 // @ts-ignore 89 ts.getBaseFileName(fileName), 90 '', 91 '', 92 mapOpions 93 ); 94 // @ts-ignore 95 const writer: any = ts.createTextWriter( 96 // @ts-ignore 97 ts.getNewLineCharacter({newLine: ts.NewLineKind.LineFeed, removeComments: false})); 98 printer['writeFile'](node, writer, sourceMapGenerator); 99 const sourceMapJson: any = sourceMapGenerator.toJSON(); 100 sourceMapJson['sources'] = [toUnixPath(fileName).replace(toUnixPath(projectConfig.projectRootPath) + '/', '')]; 101 let content: string = writer.getText(); 102 if (process.env.compileTool !== 'rollup') { 103 content = transformModuleSpecifier(fileName, processSystemApi(content, true), projectConfig); 104 } 105 106 return { 107 content: content, 108 sourceMapJson: sourceMapJson 109 }; 110} 111