Skip to content

Commit 51ef61c

Browse files
yewantingyewanting
andauthored
Support monorepo ts parser v2 (#85)
* feat:support monorepo(output separate and combined) * feat:add cli options monorepo mode * feat:add fallback logic * feat:delete the monorepo yarn detect(due to impact the signle repository) * feat:add monorepo separate repository output file ignore * feat:optimize monorepo parse code into function * feat:optimize monorepo parse separately in cluster workers * feat:add the ut for monorepo * feat:optimize the large monorepo parse(dynamically select parsing strategy) * feat:support edenx workspaces mode * feat:fill the readme * fix:cluster mode graph building - Add UNKNOWN node creation for missing dependencies * feat: modify the ut * fix:fix the ut --------- Co-authored-by: yewanting <yewanting@bytedance.com>
1 parent 683a2f7 commit 51ef61c

24 files changed

Lines changed: 4869 additions & 502 deletions

ts-parser/.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ dist/
66

77
temp/
88

9-
output.json
9+
output.json
10+
11+
output/

ts-parser/README.md

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# TypeScript Parser for ABCoder
22

3-
A TypeScript AST parser that extracts method calls, variable references, and dependencies.
3+
A TypeScript AST parser that extracts method calls, variable references, and dependencies with advanced monorepo support and intelligent parsing strategies.
44

5-
Usage:
5+
## Features
6+
7+
- 🚀 **Monorepo Support**: Intelligent detection and parsing of monorepo projects
8+
-**Smart Parsing Strategy**: Automatic selection between single-process and cluster-based parsing
9+
- 📦 **Multiple Monorepo Formats**: Support for Edex, pnpm workspaces, Lerna
10+
- 🎯 **Flexible Output Modes**: Combined or separate repo output for monorepo packages
11+
12+
## Usage
613

714
Build: `npm run build`
815

@@ -11,31 +18,63 @@ Run: `node dist/index.js parse [options] <directory>`
1118
Parse a TypeScript repository and generate UNIAST JSON
1219

1320
Arguments:
14-
directory Directory to parse
21+
directory Directory to parse
22+
23+
## Examples
24+
25+
### Basic Usage
26+
27+
- **Parse a single TypeScript project** : `node dist/index.js parse ./my-project`
28+
29+
- **Parse with pretty output** : `node dist/index.js parse ./my-project --pretty`
30+
31+
- **Parse monorepo with separate package outputs** : `node dist/index.js parse ./my-monorepo --monorepo-mode separate`
32+
33+
- **Parse monorepo (combined output)**: `node dist/index.js parse ./my-monorepo`
34+
- **Parse monorepo (separate output for each package)**: `node dist/index.js parse ./my-monorepo --monorepo-mode separate`
1535

36+
- **Custom output path** : `node dist/index.js parse ./my-project -o ./output/result.json `
1637

17-
| Option | Description |
18-
|--------|-------------|
19-
| -o, --output <file> | Output file path (default: "output.json") |
20-
| -t, --tsconfig <file> | Path to tsconfig.json file, if you provide a relative path, it will be relative to **the directory of the input file** (default: "tsconfig.json") |
21-
| --no-dist | Ignore dist folder and its contents |
22-
| --pretty | Pretty print JSON output |
23-
| --src <dirs> | Directory paths to include (comma-separated) |
24-
| -h, --help | display help for command |
38+
## Options
2539

40+
| Option | Description |
41+
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
42+
| -o, --output <file> | Output file path (default: "output.json") |
43+
| -t, --tsconfig <file> | Path to tsconfig.json file, if you provide a relative path, it will be relative to **the directory of the input file** (default: "tsconfig.json") |
44+
| --no-dist | Ignore dist folder and its contents |
45+
| --pretty | Pretty print JSON output |
46+
| --src <dirs> | Directory paths to include (comma-separated) |
47+
| --monorepo-mode <mode> | Monorepo output mode: "combined" (entire repository) or "separate" (each package) (default: "combined") |
48+
| -h, --help | display help for command |
2649

2750
See `./index.ts` for more information.
2851

52+
## Monorepo Support
53+
54+
The parser automatically detects and supports various monorepo configurations:
55+
56+
- **Eden Monorepo**: Supports both `packages` format and `workspaces` format
57+
- **pnpm Workspaces**: Reads `pnpm-workspace.yaml` configuration
58+
- **Lerna**: Detects `lerna.json` configuration
59+
60+
### Parsing Strategies
61+
62+
The parser intelligently selects the optimal parsing strategy based on project size:
63+
64+
- **Single Process Mode**: For small to medium projects
65+
- **Cluster Mode**: For large projects with parallel processing across multiple CPU cores
2966

3067
## Notes
3168

32-
1. MUST correctly specify the location of the current project's `tsconfig.json`.
69+
1. MUST correctly specify the location of the current project's `tsconfig.json`.
3370

3471
2. If you provide a relative path to argument `--tsconfig`, it will be relative to **the directory of the input file**.
3572

3673
3. Before usage, please configure the dependencies for your TypeScript project, such as running npm install and setting up cross-package dependencies in monorepo.
3774

38-
4. If the repository you're analyzing is too large, you may need to adjust Node.js's maximum memory allocation.
75+
4. For large monorepo projects, the parser will automatically use cluster-based processing to improve performance.
76+
77+
5. If the repository you're analyzing is too large, you may need to adjust Node.js's maximum memory allocation.
3978

4079
## Terminology
4180

@@ -46,10 +85,9 @@ See `./index.ts` for more information.
4685

4786
This terminology mapping is used consistently throughout the parser to align with the UniAST specification, but it may initially seem counterintuitive to developers familiar with JavaScript/TypeScript conventions.
4887

49-
5088
## Some known issues
5189

5290
- When there is a circular dependency, the parser will choose one of the dependencies as the main dependency.
5391
- The parser does not handle dynamic imports.
5492
- The parser does not handle TypeScript decorators.
55-
- For external symbol which has no `.d.ts` declaration file, the parser will not be able to resolve the symbol.
93+
- For external symbol which has no `.d.ts` declaration file, the parser will not be able to resolve the symbol.

ts-parser/jest.config.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
preset: 'ts-jest',
3+
testEnvironment: 'node',
4+
roots: ['<rootDir>/src'],
5+
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
6+
transform: {
7+
'^.+\\.ts$': 'ts-jest',
8+
},
9+
collectCoverageFrom: [
10+
'src/**/*.ts',
11+
'!src/**/*.d.ts',
12+
'!src/**/*.test.ts',
13+
'!src/**/*.spec.ts',
14+
],
15+
moduleFileExtensions: ['ts', 'js', 'json'],
16+
testPathIgnorePatterns: ['/node_modules/', '/dist/', '/temp/'],
17+
coverageDirectory: 'coverage',
18+
coverageReporters: ['text', 'lcov', 'html'],
19+
};

ts-parser/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ program
2121
.option('--no-dist', 'Ignore dist folder and its contents', false)
2222
.option('--pretty', 'Pretty print JSON output', false)
2323
.option('--src <dirs>', 'Directory paths to include (comma-separated)', (value) => value.split(','))
24+
.option('--monorepo-mode <mode>', '"combined"(output entrie monorep repository) "separate"(output each app)', 'combined')
2425
.action(async (directory, options) => {
2526
try {
2627
const repoPath = path.resolve(directory);
@@ -36,9 +37,11 @@ program
3637
const repository = await parser.parseRepository(repoPath, {
3738
loadExternalSymbols: false,
3839
noDist: options.noDist,
39-
srcPatterns: options.src
40+
srcPatterns: options.src,
41+
monorepoMode: options.monorepoMode as 'combined' | 'separate'
4042
});
4143

44+
// Output the repository JSON file
4245
const outputPath = path.resolve(options.output);
4346
const jsonOutput = options.pretty
4447
? JSON.stringify(repository, null, 2)

0 commit comments

Comments
 (0)