feat: support opt-in tsconfigPaths #427
Conversation
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... 📒 Files selected for processing (1)
✏️ Tip: You can disable in-progress messages and the fortune message in your review settings. Tip You can disable poems in the walkthrough.Disable the 📝 WalkthroughWalkthroughAdds an opt-in Changes
Sequence Diagram(s)sequenceDiagram
participant App as App (consumer)
participant Jiti as Jiti Loader
participant Resolve as jitiResolve
participant TSFinder as get-tsconfig
participant FS as Filesystem
App->>Jiti: import "alias/path"
Jiti->>Resolve: jitiResolve(id)
Resolve->>Jiti: checks ctx.resolveTsConfigPaths?
alt tsconfigPaths enabled
Jiti->>TSFinder: discover/parse tsconfig (lazy)
TSFinder->>FS: read tsconfig.json
TSFinder-->>Jiti: paths candidates[]
Jiti->>Resolve: try each candidate (recursive resolve, skip re-entry)
Resolve->>FS: resolve candidate -> file path
Resolve-->>Jiti: resolved path
end
Resolve->>FS: fallback to alias/normal resolution
Resolve-->>Jiti: module file path
Jiti-->>App: return module
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
tsConfigPaths
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/jiti.ts (1)
52-65: Avoid non-null assertion whencreatePathsMatchercan returnnull.
createPathsMatcherreturnsnullwhen nopathsare defined in the tsconfig. Using!on line 63 bypasses TypeScript's null check but assignsnullto a variable typed as(...) | undefined. While this works at runtime (both are falsy), it's misleading and could cause issues if the type is relied upon elsewhere.♻️ Proposed fix
const tsconfig = getTsconfig(searchPath); if (tsconfig) { - resolveTsConfigPaths = createPathsMatcher(tsconfig)!; + resolveTsConfigPaths = createPathsMatcher(tsconfig) ?? undefined; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/jiti.ts` around lines 52 - 65, The code currently uses a non-null assertion on createPathsMatcher(tsconfig) when initializing resolveTsConfigPaths; instead call createPathsMatcher(tsconfig) into a temporary (e.g., matcher) and only assign to resolveTsConfigPaths if matcher is non-null, removing the "!" so resolveTsConfigPaths remains undefined when createPathsMatcher returns null; update the block where getTsconfig and createPathsMatcher are used (symbols: resolveTsConfigPaths, createPathsMatcher, getTsconfig, opts.tsconfigPaths, filename) accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@package.json`:
- Line 110: The package currently lists "get-tsconfig" only under
devDependencies but src/jiti.ts requires it at runtime when the tsconfigPaths
option is enabled; move the "get-tsconfig" entry from devDependencies into
dependencies in package.json so production installs include it, ensuring the
runtime require in src/jiti.ts (the code that references get-tsconfig when
tsconfigPaths is true) will not throw a "Cannot find module" error.
In `@src/options.ts`:
- Line 30: The tsconfigPaths option currently calls _jsonEnv<boolean |
string>("JITI_TSCONFIG_PATHS", false) which JSON.parse()s the env value and
silently falls back to false for plain path strings; update the handling so
JITI_TSCONFIG_PATHS accepts either a JSON boolean or a plain string path: modify
the logic used for tsconfigPaths (replace or wrap the call to _jsonEnv) to try
JSON.parse but on parse failure return the raw string value (or the default
false if the env is empty), preserving types boolean | string and ensuring
tsconfigPaths and _jsonEnv/JITI_TSCONFIG_PATHS references reflect this behavior.
---
Nitpick comments:
In `@src/jiti.ts`:
- Around line 52-65: The code currently uses a non-null assertion on
createPathsMatcher(tsconfig) when initializing resolveTsConfigPaths; instead
call createPathsMatcher(tsconfig) into a temporary (e.g., matcher) and only
assign to resolveTsConfigPaths if matcher is non-null, removing the "!" so
resolveTsConfigPaths remains undefined when createPathsMatcher returns null;
update the block where getTsconfig and createPathsMatcher are used (symbols:
resolveTsConfigPaths, createPathsMatcher, getTsconfig, opts.tsconfigPaths,
filename) accordingly.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yamltest/__snapshots__/fixtures.test.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (10)
README.mdlib/types.d.tspackage.jsonsrc/jiti.tssrc/options.tssrc/resolve.tssrc/types.tstest/fixtures/tsconfig-paths/index.mjstest/fixtures/tsconfig-paths/src/config.tstest/fixtures/tsconfig-paths/tsconfig.json
tsConfigPaths tsconfigPaths
add rawFallback param to _jsonEnv to return raw env value on JSON.parse failure
|
Thanks for merging! Any chance of a new release anytime soon? Hope to release something depending on this and would rather not use a fork :) |
|
surely soon. please ping me by this week if forgot. |
|
@pi0 Ping as requested ;) |
|
Hate to keep pinging, but wondering if there's any chance of a new release @pi0 ? |
|
Would be great to have this released 🙏 Can't wait! |
|
Hi. Sorry for delay it is out! https://github.com/unjs/jiti/releases/tag/v2.7.0 |
Resolves TypeScript
compilerOptions.pathsaliases at runtime, matching tsc behavior.Resolves #373
Usage
true- auto-discovertsconfig.jsonby walking up from the jiti instance's parent pathstring- explicit path to atsconfig.jsonfalse(default) - disabled (backwards compatible)Also configurable via
JITI_TSCONFIG_PATHSenvironment variable.Implementation
Uses get-tsconfig (same library used by tsx and bundle-require) to parse the tsconfig and create a paths matcher. The matcher is created once per jiti instance, not re-parsed on every resolve call.
In the resolve chain (
resolve.ts), tsconfig path candidates are tried before alias resolution and before Node's native resolution. Each candidate is resolved through jiti's existing file resolution (including extension handling), and thefirst that exists on disk wins.
Handles the full tsc path matching spec:
@/*→./src/*)@config→./src/config)*→./types/*)foo/*/bar→./src/*/baz)@/*→./src/*,./generated/*) - tries each in orderget-tsconfig)Edge cases:
Aside
Really happy with jiti - it handles compatibility better than both tsx and bundle-require - the only thing missing is TS paths support :)
Let me know if you need something to change! I ran into an issue when running tests locally that I attempted to fix in #426
Summary by CodeRabbit