|
| 1 | +## Overview |
| 2 | + |
| 3 | +**jiti** (`unjs/jiti`) — Runtime TypeScript and ESM support for Node.js. |
| 4 | + |
| 5 | +Zero-dependency, slim runtime that provides seamless TypeScript/ESM/CJS interop. |
| 6 | +Used by Nuxt, Tailwind, ESLint, Docusaurus, and 300M+ monthly npm downloads. |
| 7 | + |
| 8 | +> [!IMPORTANT] |
| 9 | +> Keep `AGENTS.md` updated with project status. |
| 10 | +
|
| 11 | +## Architecture |
| 12 | + |
| 13 | +### Source (`src/`) ~1300 LoC total |
| 14 | + |
| 15 | +| File | Purpose | |
| 16 | +|------|---------| |
| 17 | +| `jiti.ts` | Main entry — `createJiti()` factory, configures options and returns jiti instance | |
| 18 | +| `eval.ts` | Evaluates transformed code (both sync `require` and async `import`) | |
| 19 | +| `require.ts` | Sync `require()` replacement with CJS/ESM interop | |
| 20 | +| `resolve.ts` | Module resolution with alias support | |
| 21 | +| `transform.ts` | Orchestrates Babel transformation | |
| 22 | +| `babel.ts` | Babel config and plugin setup (TypeScript, JSX, decorators, etc.) | |
| 23 | +| `cache.ts` | Filesystem transpile cache with etag-based invalidation | |
| 24 | +| `options.ts` | Options normalization and defaults | |
| 25 | +| `utils.ts` | Helpers (debug logging, readFile, interopDefault proxy, etc.) | |
| 26 | +| `types.ts` | Core type definitions | |
| 27 | +| `plugins/` | Babel plugins for `import.meta.env`, `import.meta.url/dirname/filename`, `import.meta.resolve` | |
| 28 | + |
| 29 | +### Build |
| 30 | + |
| 31 | +- **Bundler**: rspack (`rspack.config.mjs`) — bundles `src/` → `dist/jiti.cjs` + `dist/babel.cjs` |
| 32 | +- Babel is lazy-loaded from `dist/babel.cjs` only when transformation is needed |
| 33 | +- `lib/` contains thin ESM/CJS wrappers, CLI, register hook, and type declarations (not bundled, shipped as-is) |
| 34 | + |
| 35 | +### Exports |
| 36 | + |
| 37 | +- `jiti` (main) — CJS + ESM dual export |
| 38 | +- `jiti/register` — Node.js ESM loader hook (`--import jiti/register`) |
| 39 | +- `jiti/native` — Uses Node.js native `--experimental-strip-types` when available |
| 40 | +- `jiti` CLI binary — `lib/jiti-cli.mjs` |
| 41 | + |
| 42 | +## Testing |
| 43 | + |
| 44 | +- **Framework**: vitest (`vitest.config.ts`) |
| 45 | +- **Main test**: `test/fixtures.test.ts` — runs each fixture in `test/fixtures/` via jiti |
| 46 | +- **Other tests**: `test/utils.test.ts`, `test/node-register.test.mjs`, `test/bun.test.ts` |
| 47 | +- **Native runtime tests**: `test/native/` (node, bun, deno) |
| 48 | +- **Snapshots**: `test/__snapshots__/` |
| 49 | + |
| 50 | +### Running tests |
| 51 | + |
| 52 | +```bash |
| 53 | +# Single test file (preferred) |
| 54 | +pnpm vitest run test/fixtures.test.ts |
| 55 | + |
| 56 | +# Node register test |
| 57 | +pnpm test:node-register |
| 58 | + |
| 59 | +# Native runtime tests |
| 60 | +pnpm test:native:node |
| 61 | +pnpm test:native:bun |
| 62 | +pnpm test:native:deno |
| 63 | + |
| 64 | +# Full suite |
| 65 | +pnpm test |
| 66 | +``` |
| 67 | + |
| 68 | +## Key Commands |
| 69 | + |
| 70 | +```bash |
| 71 | +pnpm build # Clean + rspack bundle |
| 72 | +pnpm dev # Watch mode |
| 73 | +pnpm lint # ESLint + Prettier |
| 74 | +pnpm lint:fix # Auto-fix |
| 75 | +pnpm test # Full test suite (lint + types + vitest + register + bun + native) |
| 76 | +pnpm test:types # tsgo --noEmit |
| 77 | +``` |
| 78 | + |
| 79 | +## Fixtures |
| 80 | + |
| 81 | +Test fixtures in `test/fixtures/<name>/` each have an `index.ts` (or similar entry). |
| 82 | +The fixture test runner executes them via jiti and snapshots stdout. |
| 83 | + |
| 84 | +## Notes |
| 85 | + |
| 86 | +- Package manager: pnpm |
| 87 | +- Node version: see `.nvmrc` |
| 88 | +- Type checking uses `tsgo` (TypeScript native preview) |
| 89 | +- Babel plugins are bundled into `dist/babel.cjs` and lazy-loaded |
| 90 | +- `stubs/` provides lightweight shims for heavy Babel packages to reduce bundle size |
0 commit comments