Skip to content

Commit 82d7d01

Browse files
authored
Merge pull request #16 from code-found/feature/esm-support
Feature/esm support
2 parents 1670015 + 86d3887 commit 82d7d01

12 files changed

Lines changed: 572 additions & 356 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# rts.js
22

3+
## 0.0.13
4+
5+
### Patch Changes
6+
7+
- 2844694: Use Node.js isBuiltin for reliable builtin module detection
8+
9+
## 0.0.13-alpha.0
10+
11+
### Patch Changes
12+
13+
- Use Node.js isBuiltin for reliable builtin module detection
14+
315
## 0.0.12
416

517
### Patch Changes

CLAUDE.md

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
## Project Overview
5+
This is a Node.js runtime transformer system (RTS) that enables direct execution of TypeScript, JSX, TSX, and CSS files without requiring pre-compilation. Built with SWC for fast compilation and designed for seamless integration with Node.js module system.
6+
7+
## Package Management
8+
- **Use pnpm as the package manager**
9+
- Always use `pnpm install` instead of `npm install`
10+
- Use `pnpm add <package>` for adding dependencies
11+
- Use `pnpm add -D <package>` for adding dev dependencies
12+
- Use `pnpm remove <package>` for removing dependencies
13+
- Use `pnpm run <script>` for running scripts
14+
15+
## Code Style and Comments
16+
- **All comments must be in English**
17+
- Use JSDoc style comments for functions and classes
18+
- Include comprehensive parameter descriptions
19+
- Add usage examples in comments where appropriate
20+
- Use clear, descriptive variable and function names
21+
- Follow TypeScript best practices
22+
23+
## Commit Messages
24+
- **All commit messages must be in English**
25+
- Use conventional commit format: `type(scope): description`
26+
- Examples:
27+
- `feat(resolver): add module alias support`
28+
- `fix(transformer): handle JSX syntax correctly`
29+
- `docs(readme): update installation instructions`
30+
- `test(integration): add end-to-end test cases`
31+
32+
## Project Conventions
33+
34+
- **Package manager**: Use `pnpm` (not npm or yarn)
35+
- **Comments**: All comments and commit messages must be in English
36+
- **Documentation**: Bilingual (English and Chinese) in `docs/` folder
37+
- **File naming**: kebab-case for files, PascalCase for classes, camelCase for functions/variables
38+
- **Exports**: Named exports preferred, avoid `export default` unless specifically requested
39+
- **Test files**: Use `*.test.ts` pattern
40+
- **Commit format**: `type(scope): description` (e.g., `feat(resolver): add module alias support`)
41+
42+
## Development Commands
43+
44+
```bash
45+
# Package management
46+
pnpm install
47+
pnpm add <package>
48+
pnpm add -D <package>
49+
pnpm remove <package>
50+
51+
# Run TypeScript files directly with rts.js
52+
node -r ./run-ts.js src/bin/index.ts
53+
54+
# Run tests
55+
pnpm test
56+
57+
# Run tests in watch mode
58+
pnpm run test:watch
59+
60+
# Run tests with coverage
61+
pnpm run test:coverage
62+
63+
# Lint code
64+
pnpm run lint
65+
66+
# Fix linting issues
67+
pnpm run lint:fix
68+
69+
# Type checking
70+
pnpm run check
71+
72+
# Fix type checking issues
73+
pnpm run check:fix
74+
75+
# Format code
76+
pnpm run format
77+
78+
# Create a changeset (for release)
79+
pnpm changeset
80+
81+
# Full release process
82+
pnpm run release
83+
84+
# Release dry run
85+
pnpm run release --dry-run
86+
```
87+
88+
## Architecture Overview
89+
90+
RTS (Runtime Transformer System) is a Node.js runtime transformer that enables direct execution of TypeScript, JSX, TSX, and CSS files without pre-compilation. It uses SWC for fast compilation.
91+
92+
### Core Components
93+
94+
**src/index.ts**: Main entry point exporting `registerRTS()`. This function:
95+
- Loads configuration from cwd (`rts.config.json` or `rtsrts.config.js`)
96+
- Merges configuration (default, file, and options)
97+
- Applies aliases and transformers to a global ModuleResolver instance
98+
- Registers hooks with Node.js module system
99+
- Returns cleanup function
100+
101+
**src/register.ts**: Auto-registration module used via `node -r rts.js/register`. Simply calls `registerRTS()` with defaults.
102+
103+
**src/resolver/index.ts**: `ModuleResolver` class - the heart of the system that:
104+
- Extends `ModuleTransformer` from `t-packer` dependency
105+
- Handles module path resolution with alias support
106+
- Caches resolved paths
107+
- Integrates with Node.js module system via hooks
108+
- Supports both Node.js >=24 (native `Module.registerHooks`) and <24 (polyfill)
109+
- Native: Uses `resolve` and `load` hooks
110+
- Polyfill: Overrides `_resolveFilename` and `_extensions`
111+
- Uses `tryToFindFile()` for file discovery
112+
113+
**src/config/index.ts** and **src/config/loader.ts**: Configuration management:
114+
- `RTSOptions` interface with `alias` and `transformers` fields
115+
- `mergeConfig()` deep-merges configs (alias merged, transformers concatenated)
116+
- `loadConfigFromCwd()` loads `rts.config.json` or `rts.config.js`
117+
118+
**src/bin/index.ts**: CLI entry point that spawns a new node process with `rts.js/register` preloaded.
119+
120+
**run-ts.js**: Standalone CommonJS module that registers a `.ts` loader using SWC directly. Used by the project itself to run TypeScript files (like in npm scripts and AVA config).
121+
122+
### Key Patterns
123+
124+
- Configuration hierarchy: default → file config → options (merged sequentially)
125+
- Module resolution: first checks aliases, then tries file system lookup with supported extensions
126+
- Node.js version compatibility: Detected at runtime via `process.versions.node`
127+
- Transformer chain: Multiple transformers can be registered and applied in sequence
128+
129+
### Dependencies
130+
131+
- `@swc/core`: Fast TypeScript/JSX compilation
132+
- `t-packer`: Provides `ModuleTransformer` base class and `TransformerHook` type
133+
- `@changesets/cli`: Version management and releases
134+
135+
### Testing
136+
137+
Tests use AVA framework. Configuration in `ava.config.js`:
138+
- Requires `./run-ts.js` for TypeScript support
139+
- 2-minute timeout
140+
- Files in `test/**/*.ts`
141+
142+
Test structure:
143+
- `test/index.test.ts` - Main functionality tests
144+
- `test/resolver.test.ts` - Module resolver tests
145+
- `test/transformer.test.ts` - Transformer tests
146+
- `test/config.test.ts` - Configuration tests
147+
- `test/integration.test.ts` - Integration tests
148+
- Temporary test files should be placed in `test/temp/` and cleaned up after tests
149+
150+
Test guidelines:
151+
- Use descriptive test names
152+
- Test both success and failure scenarios
153+
- Clean up resources after tests
154+
- Mock external dependencies when appropriate
155+
- Aim for high test coverage
156+
157+
### Release Process
158+
159+
Uses Changesets:
160+
1. Create changeset: `pnpm changeset`
161+
2. Release: `pnpm run release` (builds, tests, versions, publishes, tags)
162+
3. Build uses `t-packer`'s `assemble()` function
163+
164+
## Code Quality Guidelines
165+
166+
### TypeScript
167+
- Use strict TypeScript configuration
168+
- Define proper interfaces and types
169+
- Use ES modules (`import`/`export`)
170+
- Include JSDoc comments for functions and classes with parameter descriptions
171+
- Add usage examples in comments where appropriate
172+
173+
### Error Handling
174+
- Implement proper error handling with try-catch blocks where appropriate
175+
- Provide clear, descriptive error messages with context
176+
- Include actionable suggestions in error messages
177+
- Use English for all error messages
178+
179+
### Performance
180+
- Cache frequently accessed data
181+
- Minimize file system operations
182+
- Use efficient algorithms
183+
- Consider memory usage for large files
184+
185+
### Security
186+
- Validate all inputs
187+
- Sanitize file paths
188+
- Handle file system operations safely
189+
- Avoid code injection vulnerabilities
190+
191+
## File Organization
192+
193+
```
194+
src/
195+
├── index.ts # Main entry
196+
├── register.ts # Auto-registration module
197+
├── resolver/ # Module resolver
198+
├── config/ # Configuration utilities
199+
└── bin/ # CLI entry
200+
201+
test/
202+
├── temp/ # Temporary test files (cleaned up after tests)
203+
└── *.test.ts # Test files
204+
205+
docs/
206+
├── en/ # English documentation
207+
└── zh/ # Chinese documentation
208+
209+
scripts/ # Build and utility scripts
210+
```

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rts.js",
3-
"version": "0.0.12",
3+
"version": "0.0.13",
44
"description": "nodejs runtime transformer,cans transform ts、js、jsx、tsx、css code to nodejs code",
55
"main": "src/index.ts",
66
"types": "src/index.ts",
@@ -80,7 +80,7 @@
8080
"license": "ISC",
8181
"dependencies": {
8282
"@swc/core": "^1.13.3",
83-
"t-packer": "^0.0.3"
83+
"t-packer": "^0.0.4"
8484
},
8585
"devDependencies": {
8686
"@biomejs/biome": "^2.1.3",
@@ -89,4 +89,4 @@
8989
"ava": "^6.4.1",
9090
"c8": "^10.1.3"
9191
}
92-
}
92+
}

pnpm-lock.yaml

Lines changed: 5 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#!/usr/bin/env node
22

33
import { spawn } from "child_process";
4-
import { registerRTS } from "../index";
4+
// import { registerRTS } from "../index";
55

66
// Register RTS hooks when this module is loaded
7-
registerRTS();
7+
// registerRTS();
88

99
spawn(`node`, ["-r", "rts.js/register", ...process.argv.slice(2)], {
1010
cwd: process.cwd(),

src/config/index.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export interface RTSOptions {
88
alias?: Record<string, string[] | string>;
99
/** Custom transformers for additional file type support */
1010
transformers?: TransformerHook[];
11+
/** Default module type for transformation ("esm" or "commonjs") */
12+
module?: "esm" | "commonjs";
1113
}
1214

1315
/**
@@ -38,7 +40,7 @@ export function mergeConfig(
3840
): RTSOptions {
3941
if (!newConfig || typeof newConfig !== "object")
4042
return oldConfig as RTSOptions;
41-
const target: RTSOptions = { ...oldConfig };
43+
const target: Partial<RTSOptions> = { ...oldConfig };
4244
for (const key in newConfig) {
4345
switch (key) {
4446
case "alias":
@@ -50,11 +52,15 @@ export function mergeConfig(
5052
...(newConfig.transformers ?? []),
5153
];
5254
break;
55+
case "module":
56+
// module is a single value, not an array, so newConfig overwrites oldConfig
57+
target.module = newConfig.module;
58+
break;
5359
default:
54-
target[key] = newConfig[key];
60+
(target as Record<string, unknown>)[key] = (newConfig as Record<string, unknown>)[key];
5561
}
5662
}
57-
return target;
63+
return target as RTSOptions;
5864
}
5965

6066
export { loadConfigFromCwd } from "./loader";

0 commit comments

Comments
 (0)