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