From 36ebe21b219e954684e118553a6b756119085b50 Mon Sep 17 00:00:00 2001 From: zhangrengao Date: Mon, 14 Mar 2022 15:04:57 +0800 Subject: [PATCH] incre compiler abc Signed-off-by: zhangrengao Change-Id: Ieeeffa9f63988167726789faeee7528b2ffce0ba --- compiler/src/gen_abc.ts | 6 +-- compiler/src/gen_abc_plugin.ts | 95 ++++++++++++++++++++++++++++++++-- compiler/src/utils.ts | 9 ++++ 3 files changed, 102 insertions(+), 8 deletions(-) diff --git a/compiler/src/gen_abc.ts b/compiler/src/gen_abc.ts index 8d20e07..dde95b1 100644 --- a/compiler/src/gen_abc.ts +++ b/compiler/src/gen_abc.ts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 @@ -35,10 +35,6 @@ function js2abcByWorkers(jsonInput: string, cmd: string): Promise { return; } - if (fs.existsSync(input)) { - fs.unlinkSync(input); - } - const abcFile: string = input.replace(/\.js$/, '.abc'); if (fs.existsSync(abcFile)) { const abcFileNew: string = abcFile.replace(/_.abc$/, '.abc'); diff --git a/compiler/src/gen_abc_plugin.ts b/compiler/src/gen_abc_plugin.ts index eac73f7..f0b840d 100644 --- a/compiler/src/gen_abc_plugin.ts +++ b/compiler/src/gen_abc_plugin.ts @@ -16,9 +16,11 @@ import * as fs from 'fs'; import * as path from 'path'; import cluster from 'cluster'; -import * as process from 'process'; +import process from 'process'; import Compiler from 'webpack/lib/Compiler'; import { logger } from './compile_info'; +import { toUnixPath } from './utils'; +import { createHash } from 'crypto'; const firstFileEXT: string = '_.js'; const genAbcScript = 'gen_abc.js'; @@ -33,10 +35,15 @@ interface File { path: string, size: number } -const intermediateJsBundle: Array = []; +let intermediateJsBundle: Array = []; +let fileterIntermediateJsBundle: Array = []; +let hashJsonObject = {}; +let buildPathInfo = ""; const red: string = '\u001b[31m'; const reset: string = '\u001b[39m'; +const hashFile = 'gen_hash.json'; +const ARK = '/ark/'; export class GenAbcPlugin { constructor(output_, arkDir_, nodeJs_, isDebug_) { @@ -71,6 +78,7 @@ export class GenAbcPlugin { }); compiler.hooks.afterEmit.tap('GenAbcPluginMultiThread', () => { + buildPathInfo = output; invokeWorkersToGenAbc(); }); } @@ -146,8 +154,9 @@ function invokeWorkersToGenAbc() { js2abc = path.join(arkDir, 'build-mac', 'src', 'index.js'); } + filterIntermediateJsBundleByHashJson(buildPathInfo, intermediateJsBundle); const maxWorkerNumber = 3; - const splitedBundles = splitJsBundlesBySize(intermediateJsBundle, maxWorkerNumber); + const splitedBundles = splitJsBundlesBySize(fileterIntermediateJsBundle, maxWorkerNumber); const workerNumber = maxWorkerNumber < splitedBundles.length ? maxWorkerNumber : splitedBundles.length; const cmdPrefix: string = `${nodeJs} --expose-gc "${js2abc}" ${param} `; @@ -177,5 +186,85 @@ function invokeWorkersToGenAbc() { cluster.on('exit', (worker, code, signal) => { logger.debug(`worker ${worker.process.pid} finished`); }); + + process.on('exit', (code) => { + if (buildPathInfo.indexOf(ARK)) { + const hashPath = genHashJsonPath(buildPathInfo); + const hashFilePath = path.join(hashPath, hashFile); + const parent: string = path.join(hashFilePath, '..'); + if (!(fs.existsSync(parent) && !fs.statSync(parent).isFile())) { + mkDir(parent); + } + for (let i = 0; i < fileterIntermediateJsBundle.length; ++i) { + let input = fileterIntermediateJsBundle[i].path; + let abcPath = input.replace(/_.js$/, '.abc'); + if (fs.existsSync(input) && fs.existsSync(abcPath)) { + const inputContent = fs.readFileSync(input); + const hashInput = createHash('sha256'); + hashInput.update(inputContent); + const hashInputContentData = hashInput.digest('hex'); + const abcContent = fs.readFileSync(abcPath); + const hashAbc = createHash('sha256'); + hashAbc.update(abcContent); + const hashAbcContentData = hashAbc.digest('hex'); + hashJsonObject[input] = hashInputContentData; + hashJsonObject[abcPath] = hashAbcContentData; + } + if (fs.existsSync(input)) { + fs.unlinkSync(input); + } + } + fs.writeFileSync(hashFilePath, JSON.stringify(hashJsonObject)); + } + }) } } + +function filterIntermediateJsBundleByHashJson(buildPath: string, inputPaths: File[]) { + for (let i = 0; i < inputPaths.length; ++i) { + fileterIntermediateJsBundle.push(inputPaths[i]); + } + let updateJsonObject = {}; + if (buildPath.indexOf(ARK)) { + const hashPath = genHashJsonPath(buildPath); + const hashFilePath = path.join(hashPath, hashFile); + let jsonObject = {}; + let jsonFile = ""; + if (fs.existsSync(hashFilePath)) { + jsonFile = fs.readFileSync(hashFilePath).toString(); + jsonObject = JSON.parse(jsonFile); + fileterIntermediateJsBundle = []; + for (let i = 0; i < inputPaths.length; ++i) { + let input = inputPaths[i].path; + let abcPath = input.replace(/_.js$/, '.abc'); + if (fs.existsSync(input) && fs.existsSync(abcPath)) { + const inputContent = fs.readFileSync(input); + const hashInput = createHash('sha256'); + hashInput.update(inputContent); + const hashInputContentData = hashInput.digest('hex'); + const abcContent = fs.readFileSync(abcPath); + const hashAbc = createHash('sha256'); + hashAbc.update(abcContent); + const hashAbcContentData = hashAbc.digest('hex'); + if (jsonObject[input] === hashInputContentData && jsonObject[abcPath] === hashAbcContentData) { + updateJsonObject[input] = hashInputContentData; + updateJsonObject[abcPath] = hashAbcContentData; + fs.unlinkSync(input); + } else { + fileterIntermediateJsBundle.push(inputPaths[i]); + } + } else { + fileterIntermediateJsBundle.push(inputPaths[i]); + } + } + } + } + + hashJsonObject = updateJsonObject; +} + +function genHashJsonPath(buildPath: string) { + buildPath = toUnixPath(buildPath); + const dataTmps = buildPath.split(ARK); + return path.join(dataTmps[0], ARK); +} diff --git a/compiler/src/utils.ts b/compiler/src/utils.ts index 59e5b9b..d491a41 100644 --- a/compiler/src/utils.ts +++ b/compiler/src/utils.ts @@ -206,3 +206,12 @@ export function mkDir(path_: string): void { } fs.mkdirSync(path_); } + +export function toUnixPath(data: string): string { + if (/^win/.test(require('os').platform())) { + const fileTmps: string[] = data.split(path.sep); + const newData: string = path.posix.join(...fileTmps); + return newData; + } + return data; +} \ No newline at end of file