Skip to content

Commit 5debea3

Browse files
committed
feat: support typescript tech stack parse
1 parent 298c583 commit 5debea3

File tree

9 files changed

+1252
-28
lines changed

9 files changed

+1252
-28
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ Options:
4242

4343
Configuration file:
4444

45-
You can also write configuration file named `.coderflyrc`, mainly to simplify alias. Note: **It must be written in json form**.
45+
You can also write configuration file named `.coderflyrc.js`, mainly to simplify alias.
4646

4747
```js
48-
// .coderflyrc
49-
{
50-
"src": "./test",
48+
// .coderflyrc.js
49+
const path = require('path');
50+
module.exports = {
51+
'src': path.resolve(process.cwd(), 'test'),
5152
// ...
5253
}
5354
```
@@ -158,8 +159,8 @@ console.log(impacts);
158159

159160
- [x] JavaScript
160161
- [x] Vue2
162+
- [x] TypeScript
161163
- [ ] Vue3
162-
- [ ] TypeScript
163164

164165
## how it works
165166

bin/coderfly.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const ora = require('ora');
66
const { diff, getAllFiles, getFuncTree, getImpacts } = require('../dist/index.js');
77
const pkg = require('../package.json');
88
const { CONFIG_FILENAME, TREE_FILE, REPORT_FILE } = require('../dist/const.js');
9-
const { parseAliasFromConfig, lookFileOrFolderUp } = require('../dist/utils/handle_config');
9+
const { lookFileOrFolderUp } = require('../dist/utils/handle_config');
1010

1111
const newsBoy = ora();
1212

@@ -32,8 +32,7 @@ program
3232
let configFile = path.resolve(configFolder, CONFIG_FILENAME);
3333

3434
try {
35-
let config = JSON.parse(fs.readFileSync(configFile));
36-
alias = parseAliasFromConfig(config);
35+
alias = require(configFile);
3736
} catch (error){
3837
// do nothing
3938
}

docs/README_CN.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@
4040

4141
配置文件:
4242

43-
你也可以编写 `.coderflyrc` 配置文件,这样更方便 alias 的书写。注意:**这个文件要编写为 json 形式**
43+
你也可以编写 `.coderflyrc.js` 配置文件,这样更方便 alias 的书写。
4444

4545
```js
46-
// .coderflyrc
47-
{
48-
"src": "./test",
46+
// .coderflyrc.js
47+
const path = require('path');
48+
module.exports = {
49+
'src': path.resolve(process.cwd(), 'test'),
4950
// ...
5051
}
5152
```
@@ -157,10 +158,10 @@ console.log(impacts);
157158

158159
## 支持
159160

160-
- JavaScript
161-
- Vue2
161+
- [x] JavaScript
162+
- [x] Vue2
163+
- [x] TypeScript
162164
- [ ] Vue3
163-
- [ ] TypeScript
164165

165166
## 如何工作的
166167

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
},
3232
"dependencies": {
3333
"@babel/parser": "^7.17.8",
34+
"@babel/plugin-proposal-class-properties": "^7.16.7",
35+
"@babel/plugin-proposal-object-rest-spread": "^7.17.3",
36+
"@babel/preset-env": "^7.16.11",
37+
"@babel/preset-typescript": "^7.16.7",
3438
"@types/lodash-es": "^4.17.6",
3539
"commander": "^9.1.0",
3640
"enhanced-resolve": "^5.9.2",

src/const.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ export const MUSTACHE_TAG_REG = /\{\{((?:.|\n)+?)\}\}/g;
88

99
export const TEXT_NODE_TYPES = [2, 3];
1010

11-
export const CONFIG_FILENAME = '.coderflyrc';
11+
export const CONFIG_FILENAME = '.coderflyrc.js';
1212
export const TREE_FILE = path.resolve(process.cwd(), './file_tree.json');
1313
export const REPORT_FILE = path.resolve(process.cwd(), './impact_report.json');

src/impact.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ function findWhoCallMe (treeData: FileInfoTree, funcInfo: ImpactReason, reportIn
6666
const funcName = funcInfo.name;
6767
const curPaths = funcInfo.paths;
6868

69-
// these found functions are used to find the impact of template
70-
const templateImpactSearchFunc: NameAndPath = {
71-
[funcName]: curFilePath
72-
};
73-
7469
// because the mixin function is mixed into each file,it wil be found multiple times
7570
// so we need a set
7671
const set = new Set();
7772

7873
for (const fileInfo in treeData) {
74+
// these found functions are used to find the impact of template
75+
const templateImpactSearchFunc: NameAndPath = {
76+
[funcName]: curFilePath
77+
};
78+
7979
const allFuncsInfo = treeData[fileInfo].allFuncsInfo;
8080
const templateKeyInfo = treeData[fileInfo].templateKeyInfo;
8181

@@ -101,6 +101,10 @@ function findWhoCallMe (treeData: FileInfoTree, funcInfo: ImpactReason, reportIn
101101

102102
templateImpactSearchFunc[func.name] = func.filePath;
103103
}
104+
105+
if (func.name === funcName && func.filePath === curFilePath) {
106+
templateImpactSearchFunc[funcName] = curFilePath;
107+
}
104108
});
105109

106110
// find if the function in the paths is used in the template

src/utils/function_change/diff.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as fs from 'fs';
22
import * as path from 'path';
33
import { commandSync } from 'execa';
44
import lineByLine from 'n-readlines';
5-
import { parse, visit } from 'recast';
5+
import { visit } from 'recast';
6+
import { parse } from '@babel/parser';
67
import { parseComponent } from 'vue-template-compiler';
78
import { DiffFunctionInfo, FunctionInfo } from '../../type';
89

@@ -70,7 +71,13 @@ function getFunctionBlock (filePath: string) {
7071

7172
try {
7273
ast = parse(code, {
73-
parser: require('recast/parsers/babel'),
74+
plugins: [
75+
'decorators-legacy',
76+
'typescript',
77+
'classProperties',
78+
'objectRestSpread'
79+
],
80+
sourceType: 'unambiguous'
7481
});
7582
} catch (error) {
7683
console.log(error);

src/utils/handle_file_utils.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
3-
import { parse, visit } from 'recast';
3+
import { visit } from 'recast';
4+
import { parse } from '@babel/parser';
45
import { parseComponent, compile } from 'vue-template-compiler';
56
import lineByLine from 'n-readlines';
67
import { ALLOW_EXT, IS_TOP_SCOPE, UN_KNOWN } from '../const.js';
@@ -187,8 +188,15 @@ function getFileAst (filePath: string): FileAstInfo {
187188

188189
try {
189190
jsAst = parse(fileCtx, {
190-
parser: require('recast/parsers/babel')
191+
plugins: [
192+
'decorators-legacy',
193+
'typescript',
194+
'classProperties',
195+
'objectRestSpread'
196+
],
197+
sourceType: 'unambiguous'
191198
});
199+
192200
templateAst = compile(templateCtx);
193201
} catch (error) {
194202
console.log(`ast解析错误:${filePath}`);
@@ -239,8 +247,14 @@ function getAllFunctions (jsAst: any, filePath: string, vueScriptStartLine: numb
239247

240248
// handle: function test () {}
241249
visitFunctionDeclaration(node) {
242-
let name = node.value.id.name;
250+
let name = '';
243251
let position!: string;
252+
253+
if (!node.value.id) {
254+
name = '[Anonymous]'
255+
} else {
256+
name = node.value.id.name;
257+
}
244258

245259
// this means this function is called directly in the js file,not in a function block
246260
if (name === '') {

0 commit comments

Comments
 (0)