adapter module compile

Signed-off-by: zhangrengao <zhangrengao1@huawei.com>
Change-Id: Ib47c77cf607a8a4af4240e22d8196fd8a350149c
This commit is contained in:
zhangrengao
2022-05-05 09:12:15 +08:00
parent 60b7d047df
commit c120766ac7
6 changed files with 280 additions and 5 deletions
+110 -1
View File
@@ -17,9 +17,15 @@ import * as fs from 'fs';
import * as path from 'path';
import cluster from 'cluster';
import process from 'process';
import * as child_process from 'child_process'
import Compiler from 'webpack/lib/Compiler';
import { logger } from './compile_info';
import { toUnixPath, toHashData } from './utils';
import {
toUnixPath,
toHashData,
genTemporaryPath } from './utils';
import { Compilation } from 'webpack';
import { projectConfig } from '../main';
const firstFileEXT: string = '_.js';
const genAbcScript = 'gen_abc.js';
@@ -65,6 +71,28 @@ export class GenAbcPlugin {
}
}
compiler.hooks.compilation.tap("GenAbcPlugin", (compilation) => {
compilation.hooks.finishModules.tap("finishModules", handleFinishModules.bind(this));
});
compiler.hooks.compilation.tap("GenAbcPlugin", (compilation) => {
compilation.hooks.afterOptimizeTree.tap("afterOptimizeModules", (chunks, modules) => {
modules.forEach(module => {
if (module != undefined && module.resourceResolveData != undefined) {
let filePath: string = module.resourceResolveData.path;
console.error(filePath);
}
});
});
compilation.hooks.processAssets.tap("processAssets", (assets) => {
Object.keys(compilation.assets).forEach(key => {
delete assets[key];
})
})
})
compiler.hooks.emit.tap('GenAbcPlugin', (compilation) => {
Object.keys(compilation.assets).forEach(key => {
// choose *.js
@@ -80,9 +108,90 @@ export class GenAbcPlugin {
buildPathInfo = output;
invokeWorkersToGenAbc();
});
}
}
function handleFinishModules(modules, callback) {
modules.forEach(module => {
if (module != undefined && module.resourceResolveData != undefined) {
let filePath: string = module.resourceResolveData.path;
console.error(filePath);
if (filePath.endsWith('ets')) {
let tempFilePath = genTemporaryPath(filePath, projectConfig.projectPath, projectConfig.buildPath);
tempFilePath = tempFilePath.replace(/\.ets$/, '.ets.js');
tempFilePath = toUnixPath(tempFilePath);
const abcFilePath = genAbcFileName(tempFilePath);
processToAbcFile(tempFilePath, abcFilePath);
} else if (filePath.endsWith('ts')) {
let tempFilePath = genTemporaryPath(filePath, projectConfig.projectPath, projectConfig.buildPath);
tempFilePath = tempFilePath.replace(/\.ts$/, '.ts.js');
tempFilePath = toUnixPath(tempFilePath);
const abcFilePath = genAbcFileName(tempFilePath);
processToAbcFile(tempFilePath, abcFilePath);
} else if (filePath.endsWith('js')) {
if (filePath.indexOf("node_modules") !== -1) {
let tempFilePath = genTemporaryPath(filePath, projectConfig.projectPath, projectConfig.buildPath);
tempFilePath = toUnixPath(tempFilePath);
const parent: string = path.join(tempFilePath, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
mkDir(parent);
}
fs.copyFileSync(filePath, tempFilePath);
const abcFilePath = genAbcFileName(tempFilePath);
processToAbcFile(tempFilePath, abcFilePath);
} else {
let tempFilePath = genTemporaryPath(filePath, projectConfig.projectPath, projectConfig.buildPath);
tempFilePath = toUnixPath(tempFilePath);
const parent: string = path.join(tempFilePath, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
mkDir(parent);
}
// fs.copyFileSync(filePath, tempFilePath);
const abcFilePath = genAbcFileName(tempFilePath);
processToAbcFile(tempFilePath, abcFilePath);
}
} else {
console.error("=========================handleFinishModules else===================");
console.error(filePath);
}
}
})
}
function genAbcFileName(temporaryFile: string): string {
let abcFile: string = temporaryFile;
if (temporaryFile.endsWith('ts')) {
abcFile = temporaryFile.replace(/\.ts$/, '.abc');
} else {
abcFile = temporaryFile.replace(/\.js$/, '.abc');
}
return abcFile;
}
function processToAbcFile(tempFilePath, outPutFile) {
let js2abc: string = path.join(arkDir, 'build', 'src', 'index.js');
if (isWin) {
js2abc = path.join(arkDir, 'build-win', 'src', 'index.js');
} else if (isMac) {
js2abc = path.join(arkDir, 'build-mac', 'src', 'index.js');
}
const args: string[] = [
'--expose-gc',
js2abc,
'-o',
outPutFile
];
if (isDebug) {
args.push('--debug');
}
args.push(tempFilePath);
child_process.execFileSync(nodeJs, args);
}
function writeFileSync(inputString: string, output: string, jsBundleFile: string): void {
const parent: string = path.join(output, '..');
if (!(fs.existsSync(parent) && fs.statSync(parent).isDirectory())) {
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import ts from 'typescript';
import path from 'path';
import { BUILD_ON } from './pre_define';
import { writeFileSyncByNode } from './utils';
export function processJs(program: ts.Program, ut = false): Function {
return (context: ts.TransformationContext) => {
return (node: ts.SourceFile) => {
if (process.env.compiler === BUILD_ON) {
if (process.env.processTs && process.env.processTs === 'false') {
writeFileSyncByNode(node, false);
}
return node;
} else {
return node;
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
import { writeFileSyncByString } from './utils';
module.exports = function processjs2file(source: string): string {
if (process.env.compilerType && process.env.compilerType === 'ark'){
writeFileSyncByString(this.resourcePath, source, false);
}
return source;
}
+8 -1
View File
@@ -49,7 +49,8 @@ import {
LogInfo,
LogType,
hasDecorator,
FileLog
FileLog,
writeFileSyncByNode
} from './utils';
import {
processComponentBlock,
@@ -82,6 +83,9 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
if (process.env.compiler === BUILD_ON) {
if (!ut && (path.basename(node.fileName) === 'app.ets' || /\.ts$/.test(node.fileName))) {
node = ts.visitEachChild(node, processResourceNode, context);
if (process.env.processTs && process.env.processTs === 'true') {
writeFileSyncByNode(node, true);
}
return node;
}
transformLog.sourceFile = node;
@@ -97,6 +101,9 @@ export function processUISyntax(program: ts.Program, ut = false): Function {
});
node = ts.factory.updateSourceFile(node, statements);
INTERFACE_NODE_SET.clear();
if (process.env.processTs && process.env.processTs === 'true') {
writeFileSyncByNode(node, true);
}
return node;
} else {
return node;
+112 -1
View File
@@ -13,16 +13,22 @@
* limitations under the License.
*/
import ts from 'typescript';
import path from 'path';
import ts from 'typescript';
import fs from 'fs';
import { projectConfig } from '../main';
import { createHash } from 'crypto';
import { processSystemApi } from './validate_ui_syntax';
export enum LogType {
ERROR = 'ERROR',
WARN = 'WARN',
NOTE = 'NOTE'
}
export const TEMPORARYS: string = 'temporarys';
export const BUILD: string = 'build';
export const SRC_MAIN: string = 'src/main';
const TS_NOCHECK: string = '// @ts-nocheck';
export interface LogInfo {
type: LogType,
@@ -234,3 +240,108 @@ export function writeFileSync(filePath: string, content: string): void {
fs.writeFileSync(filePath, content);
}
export function genTemporaryPath(filePath: string, projectPath: string, buildPath: string, toTsFile: boolean = true): string {
filePath = toUnixPath(filePath);
projectPath = toUnixPath(projectPath);
if (filePath.indexOf('node_modules') !== -1) {
const dataTmps = filePath.split('node_modules');
const preStr = dataTmps[0];
const sufStr = dataTmps[1];
const output: string = path.join(buildPath, 'node_modules', sufStr);
return output;
}
const sufStr = filePath.replace(projectPath, "");
const output: string = path.join(buildPath, sufStr);
return output;
}
export function mkdirsSync(dirname: string): boolean {
if (fs.existsSync(dirname)) {
return true;
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
return false;
}
export function writeFileSyncByString(sourcePath: string, sourceCode: string, toTsFile: boolean) {
let temporaryFile: string = genTemporaryPath(sourcePath, projectConfig.projectPath, projectConfig.buildPath, toTsFile);
mkdirsSync(path.dirname(temporaryFile));
fs.writeFileSync(temporaryFile, sourceCode);
}
export function writeFileSyncByNode(node: ts.SourceFile, toTsFile: boolean) {
if (toTsFile) {
const newStatements = [];
const tsIgnoreNode: ts.Node = ts.factory.createExpressionStatement(ts.factory.createIdentifier(TS_NOCHECK));
newStatements.push(tsIgnoreNode);
if (node.statements && node.statements.length) {
newStatements.push(...node.statements);
}
node = ts.factory.updateSourceFile(node, newStatements);
}
const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
let options : ts.CompilerOptions = {
sourceMap : true
};
let mapOpions = {
sourceMap : true,
inlineSourceMap : false,
inlineSources : false,
sourceRoot : "",
mapRoot : "",
extendedDiagnostics : false
}
let host = ts.createCompilerHost(options);
let fileName = node.fileName;
// @ts-ignore
let sourceMapGenerator = ts.createSourceMapGenerator(
host,
// @ts-ignore
ts.getBaseFileName(fileName),
"",
"",
mapOpions
);
// @ts-ignore
let writer = ts.createTextWriter(
// @ts-ignore
ts.getNewLineCharacter({newLine : ts.NewLineKind.LineFeed, removeComments : false}));
printer["writeFile"](node, writer, sourceMapGenerator);
let sourceMapJson = sourceMapGenerator.toJSON();
sourceMapJson['sources'] = [fileName];
const result: string = writer.getText();
let content: string = result;
content = processSystemApi(content, true);
if (toTsFile) {
content = result.replace(`${TS_NOCHECK};`, TS_NOCHECK);
}
const sourceMapContent = JSON.stringify(sourceMapJson);
let temporaryFile: string = genTemporaryPath(node.fileName, projectConfig.projectPath, projectConfig.buildPath, toTsFile);
let temporarySourceMapFile: string = "";
if (temporaryFile.endsWith("ets")) {
temporarySourceMapFile = temporaryFile.replace(/\.ets$/, '.ets.sourcemap');
if (toTsFile) {
temporaryFile = temporaryFile.replace(/\.ets$/, '.ets.ts');
} else {
temporaryFile = temporaryFile.replace(/\.ets$/, '.ets.js');
}
} else {
if (!toTsFile) {
temporarySourceMapFile = temporaryFile.replace(/\.ts$/, '.ts.sourcemap');
temporaryFile = temporaryFile.replace(/\.ts$/, '.ts.js');
}
}
mkdirsSync(path.dirname(temporaryFile));
fs.writeFileSync(temporaryFile, content);
if (temporarySourceMapFile.length > 0) {
fs.writeFileSync(temporarySourceMapFile, sourceMapContent);
}
}
+7 -2
View File
@@ -34,7 +34,7 @@ const { ResultStates } = require('./lib/compile_info');
const { processUISyntax } = require('./lib/process_ui_syntax');
const { IGNORE_ERROR_CODE } = require('./lib/utils');
const { BUILD_SHARE_PATH } = require('./lib/pre_define');
const { processJs } = require('./lib/process_js_ast');
process.env.watchMode = (process.env.watchMode && process.env.watchMode === 'true') || 'false';
function initConfig(config) {
@@ -80,7 +80,7 @@ function initConfig(config) {
getCustomTransformers(program) {
return {
before: [processUISyntax(program)],
after: []
after: [processJs(program)]
};
},
ignoreDiagnostics: IGNORE_ERROR_CODE
@@ -92,6 +92,7 @@ function initConfig(config) {
{
test: /\.js$/,
use: [
{ loader: path.resolve(__dirname, 'lib/process_js_file.js')},
{ loader: path.resolve(__dirname, 'lib/process_system_module.js') }
]
}
@@ -311,9 +312,13 @@ module.exports = (env, argv) => {
const workerFile = readWorkerFile();
setOptimizationConfig(config, workerFile);
setCopyPluginConfig(config);
process.env.processTs = false;
if (env.isPreview !== "true") {
loadWorker(projectConfig, workerFile);
if (env.compilerType && env.compilerType === 'ark') {
process.env.compilerType = 'ark';
let arkDir = path.join(__dirname, 'bin', 'ark');
if (env.arkFrontendDir) {
arkDir = env.arkFrontendDir;