Skip to content

Commit deff947

Browse files
committed
perf: performance improved
1 parent 9c7bd9b commit deff947

File tree

10 files changed

+134
-10
lines changed

10 files changed

+134
-10
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"execa": "5.1.1",
4242
"lodash-es": "^4.17.21",
4343
"n-readlines": "^1.0.1",
44+
"nanoid": "^3.3.4",
4445
"ora": "5.4.1",
4546
"recast": "^0.20.5",
4647
"vue-template-compiler": "^2.6.14"

src/const.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ export const CONFIG_FILENAME = '.coderflyrc.js';
1414
export const MATCHED_VUE = path.resolve(CODERFLY_FOLDER, 'matched_vue');
1515
export const TREE_FILE = path.resolve(CODERFLY_FOLDER, 'file_tree.json');
1616
export const REPORT_FILE = path.resolve(CODERFLY_FOLDER, 'impact_report.json');
17+
export const FILE_MODIFY_DETAIL = path.resolve(CODERFLY_FOLDER, 'file_modify_detail.json');

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ async function coderfly (srcPath: string) {
2828

2929
const files = getAllFiles(path.resolve(process.cwd(), srcPath));
3030

31-
const tree = getFuncTree(files, {
31+
const tree = await getFuncTree(files, {
3232
alias
3333
});
3434

src/match_version.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import { commandSync } from "execa";
2+
import fs from 'fs';
23
import path from "path";
4+
import { MATCHED_VUE } from "./const.js";
35
import { lookFileOrFolderUp } from "./utils/handle_config.js";
6+
import { confirmFolderExist } from "./utils/handle_file_utils.js";
47

58
export function matchVueVersion () {
9+
confirmFolderExist();
10+
11+
if (fs.existsSync(MATCHED_VUE)) {
12+
return;
13+
}
14+
615
let vueVersion = 'latest';
716
let vueTemplateCompilerVersion = '';
817

@@ -27,4 +36,6 @@ export function matchVueVersion () {
2736
try { commandSync('npm uninstall vue-template-compiler') } catch {}
2837
commandSync(`npm install vue-template-compiler@${vueVersion}`);
2938
}
39+
40+
fs.writeFileSync(MATCHED_VUE, 'true');
3041
}

src/type.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,13 @@ export interface FileAstInfo {
111111
templateAst: CompiledResult<string> | undefined; // vue template ast
112112
extName: string;
113113
vueScriptStartLine: number; // vue script 开始行数
114+
}
115+
116+
export interface GetFileInfoWorkerData {
117+
files: string[];
118+
fileModifyDetail: {
119+
[filePath: string]: number;
120+
};
121+
tree: FileInfoTree;
122+
options?: GetTreeOptions;
114123
}

src/utils/function_change/diff.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { visit } from 'recast';
66
import { parse } from '@babel/parser';
77
import { parseComponent } from 'vue-template-compiler';
88
import { DiffFunctionInfo, FunctionInfo } from '../../type';
9+
import { nanoid } from 'nanoid';
910

1011
// get the change of function before and after file change
1112
export function getFunctionDiffInfo (filePath: string, commitSha?: string) {
@@ -60,7 +61,7 @@ function getFunctionBlock (filePath: string) {
6061
const extName = path.extname(filePath);
6162

6263
let ast;
63-
const tempFile = path.resolve(process.cwd(), 'temp_vue_script.js');
64+
const tempFile = path.resolve(process.cwd(), `temp_vue_script_${nanoid(10)}.js`);
6465

6566
if (extName === '.vue') {
6667
const compilerResult = parseComponent(code);

src/utils/handle_file_utils.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { visit } from 'recast';
44
import { parse } from '@babel/parser';
55
import { parseComponent, compile } from 'vue-template-compiler';
66
import lineByLine from 'n-readlines';
7-
import { ALLOW_EXT, CODERFLY_FOLDER, IS_TOP_SCOPE, TS_DECLARATION_EXT, UN_KNOWN } from '../const.js';
7+
import { ALLOW_EXT, CODERFLY_FOLDER, IS_TOP_SCOPE, TREE_FILE, TS_DECLARATION_EXT, UN_KNOWN } from '../const.js';
88
import {
99
AllFuncsInfo,
1010
FileAstInfo,
@@ -15,6 +15,7 @@ import {
1515
TemplateKeyInfo
1616
} from '../type';
1717
import { getTemplateInfo } from './parse_template_ast.js';
18+
import { getFileInfoWorker } from '../worker/run_worker.js';
1819

1920
const { create } = require('enhanced-resolve');
2021

@@ -45,13 +46,8 @@ function getAllFiles (folderPath: string): string[] {
4546
return fileList;
4647
}
4748

48-
function getFuncTree (files: string[], options?: GetTreeOptions): FileInfoTree {
49-
const tree: FileInfoTree = {};
50-
51-
for (const file of files) {
52-
const fileInfo = getFileInfo(file, options);
53-
tree[file] = fileInfo;
54-
}
49+
async function getFuncTree (files: string[], options?: GetTreeOptions): Promise<FileInfoTree> {
50+
const tree = await getFileInfoWorker(files, options);
5551

5652
for (const file in tree) {
5753
const fileInfo = tree[file];
@@ -124,6 +120,8 @@ function getFuncTree (files: string[], options?: GetTreeOptions): FileInfoTree {
124120
});
125121
}
126122

123+
fs.writeFileSync(TREE_FILE, JSON.stringify(tree, null, 4));
124+
127125
return tree;
128126
}
129127

src/worker/get_file_info_thread.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import fs from "fs";
2+
import { parentPort, workerData } from "worker_threads";
3+
import { FileInfoTree, GetFileInfoWorkerData } from "../type";
4+
import { getFileInfo } from "../utils/handle_file_utils.js";
5+
6+
parentPort?.postMessage(_getFilesInfo(workerData));
7+
8+
function _getFilesInfo (workerData: GetFileInfoWorkerData) {
9+
const currentTree: FileInfoTree = {};
10+
11+
for (const file of workerData.files) {
12+
const mtime = fs.statSync(file).mtimeMs;
13+
/**
14+
* 1. if has been scan latest
15+
* i. if has the same mtime ,don't need scan again, use the value in cache
16+
* ii. if has different mtime, scan again
17+
*
18+
* 2. if don't has scan record, scan again
19+
*/
20+
if (workerData.fileModifyDetail[file] &&
21+
workerData.fileModifyDetail[file] === mtime &&
22+
workerData.tree[file]) {
23+
currentTree[file] = workerData.tree[file];
24+
continue;
25+
}
26+
27+
const fileInfo = getFileInfo(file, workerData.options);
28+
currentTree[file] = fileInfo;
29+
30+
workerData.fileModifyDetail[file] = mtime;
31+
}
32+
33+
return {
34+
tree: currentTree,
35+
fileModifyDetail: workerData.fileModifyDetail,
36+
};
37+
}

src/worker/run_worker.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { Worker } from 'worker_threads';
2+
import { cpus } from 'os';
3+
import path from 'path';
4+
import fs from 'fs';
5+
import { FileInfoTree, GetTreeOptions } from '../type';
6+
import { FILE_MODIFY_DETAIL, TREE_FILE } from '../const.js';
7+
8+
export function getFileInfoWorker (files: string[], options?: GetTreeOptions): Promise<FileInfoTree> {
9+
return new Promise((resolve, reject) => {
10+
let fileModifyDetail = {};
11+
12+
if (fs.existsSync(FILE_MODIFY_DETAIL)) {
13+
fileModifyDetail = JSON.parse(fs.readFileSync(FILE_MODIFY_DETAIL, 'utf8'));
14+
}
15+
16+
let tree: FileInfoTree = {};
17+
if (fs.existsSync(TREE_FILE)) {
18+
tree = JSON.parse(fs.readFileSync(TREE_FILE, 'utf8'));
19+
}
20+
21+
const threadCount = cpus().length;
22+
const threads: Set<Worker> = new Set();
23+
const everyWorkerFileCount = Math.ceil(files.length / threadCount);
24+
25+
for (let i = 0; i < threadCount; i++) {
26+
threads.add(new Worker(path.resolve(__dirname, './get_file_info_thread.js'), {
27+
workerData: {
28+
files: files.splice(0, everyWorkerFileCount),
29+
options,
30+
fileModifyDetail,
31+
tree,
32+
}
33+
}));
34+
}
35+
36+
for (const worker of threads) {
37+
worker.on('error', (err) => {
38+
reject(new Error(`worker stopped with ${err}`));
39+
});
40+
41+
worker.on('exit', (code) => {
42+
threads.delete(worker);
43+
// console.log(`Thread exiting, ${threads.size} running...`)
44+
45+
if (code !== 0) {
46+
reject(new Error(`stopped with ${code} exit code`))
47+
}
48+
49+
if (threads.size === 0) {
50+
fs.writeFileSync(FILE_MODIFY_DETAIL, JSON.stringify(fileModifyDetail, null, 4));
51+
resolve(tree);
52+
}
53+
})
54+
55+
worker.on('message', (msg) => {
56+
Object.assign(tree, msg.tree);
57+
Object.assign(fileModifyDetail, msg.fileModifyDetail);
58+
});
59+
}
60+
});
61+
}

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,6 +1856,11 @@ n-readlines@^1.0.1:
18561856
resolved "https://registry.yarnpkg.com/n-readlines/-/n-readlines-1.0.1.tgz#bbb7364d38bc31a170a199f986fcacfa76b95f6e"
18571857
integrity sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==
18581858

1859+
nanoid@^3.3.4:
1860+
version "3.3.4"
1861+
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
1862+
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
1863+
18591864
natural-compare@^1.4.0:
18601865
version "1.4.0"
18611866
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"

0 commit comments

Comments
 (0)