Skip to content

Conversation

@xiaoxiaojx
Copy link
Member

No description provided.

@codecov
Copy link

codecov bot commented Sep 11, 2025

Codecov Report

❌ Patch coverage is 95.04950% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.38%. Comparing base (79e2961) to head (b2f5489).

Files with missing lines Patch % Lines
lib/TsconfigPathsPlugin.js 95.97% 7 Missing ⚠️
lib/util/fs.js 61.53% 4 Missing and 1 partial ⚠️
lib/index.js 0.00% 2 Missing ⚠️
lib/util/path.js 95.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #463      +/-   ##
==========================================
+ Coverage   93.13%   93.38%   +0.25%     
==========================================
  Files          45       49       +4     
  Lines        2155     2375     +220     
  Branches      654      716      +62     
==========================================
+ Hits         2007     2218     +211     
- Misses        119      128       +9     
  Partials       29       29              
Flag Coverage Δ
integration 93.38% <95.04%> (+0.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@xiaoxiaojx xiaoxiaojx changed the title [WIP] feat: add TsconfigPathsPlugin feat: add TsconfigPathsPlugin Sep 12, 2025
? this.configFile
: resolver.join(process.cwd(), this.configFile);

const mainOptions = await this.readTsconfigCompilerOptions(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can cache readTsconfigCompilerOptions using (and the same for readTsconfigCompilerOptions below)

this.tsconfigProcessorCache = new WeakMap<TS_CONFIG_JSON_VALUE, { aliases: Aliases, references: References }>;

So we will read everything only on the first run, and will keep results until GC allow it

Feel free to think how we can avoid more tasks on the second and third calls

This comment was marked as outdated.

Copy link
Member Author

@xiaoxiaojx xiaoxiaojx Sep 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we just store the data on this.tsconfigPathsData?
It doesn’t need to be garbage-collected anyway, so the cache implementation doesn’t have to be too complex.

Copy link
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments, also let's add test cases, good start for this plugin, thank you

@xiaoxiaojx

This comment was marked as outdated.

@xiaoxiaojx xiaoxiaojx changed the title feat: add TsconfigPathsPlugin [WIP] feat: add TsconfigPathsPlugin Sep 24, 2025
@xiaoxiaojx xiaoxiaojx force-pushed the feat/tsconfigPaths branch 2 times, most recently from b1a6c4e to f45b2f3 Compare September 25, 2025 18:22
@xiaoxiaojx xiaoxiaojx changed the title [WIP] feat: add TsconfigPathsPlugin feat: add TsconfigPathsPlugin Sep 25, 2025
@xiaoxiaojx xiaoxiaojx force-pushed the feat/tsconfigPaths branch 2 times, most recently from 4362983 to 50aa0ca Compare September 27, 2025 16:33
if (
!exists &&
extendedConfigValue.includes("/") &&
extendedConfigValue.includes(".")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you describe these checks? Maybe we can just check if exist?

Copy link
Member Author

@xiaoxiaojx xiaoxiaojx Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The goal here is to resolve the extendedConfigValue path from node_modules, e.g. extends: "react/tsconfig". Reference: https://github.com/jonaskello/tsconfig-paths/blob/master/src/tsconfig-loader.ts#L187

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!compilerOptions) return null;

return {
...tsconfigPathsToResolveOptions(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can cache this, look at ExportsFieldPlugin.js plugin, we have this.fieldProcessorCache to cache processed export fields, so let's use the same logic, just using this.tsconfigProcessorCache name and cache result of this function

Copy link
Member Author

@xiaoxiaojx xiaoxiaojx Oct 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tsconfigPathsToResolveOptions function only runs once per resolve. However, the key of this.fieldProcessorCache is JsonObject(ExportsFieldPlugin.fieldProcessorCache: WeakMap<JsonObject, FieldProcessor>), and since each resolve produces a different JsonObject reference, this cache becomes ineffective in scenarios where it should run only once per resolve. This makes me wonder whether the cache in ExportsFieldPlugin(this.fieldProcessorCache) aligns with the original intent—perhaps the key should be a string rather than an object reference.

Copy link
Member Author

@xiaoxiaojx xiaoxiaojx Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous conclusion was incorrect — if we use fileSystem.readJson, it returns the same JsonObject reference.
https://github.com/webpack/enhanced-resolve/blob/main/lib/DescriptionFileUtils.js#L104

The same caching logic can't be applied to tsconfigPaths because tsconfigPaths might be a JSON that combines multiple "extends", and the references will always be new. The cost of caching won't be less than that of running the original function.

@alexander-akait
Copy link
Member

Add let's add more test cases to improve coverage

module.exports._getPrefixLength = getPrefixLength;
module.exports._mergeTsconfigs = mergeTsconfigs;
module.exports._sortByLongestPrefix = sortByLongestPrefix;
module.exports._tsconfigPathsToResolveOptions = tsconfigPathsToResolveOptions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to expose it? For testing purposes?

lib/index.js Outdated
extensions: [".js", ".json", ".node"],
useSyncFileSystemCalls: true,
fileSystem: getNodeFileSystem(),
tsconfig: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to pass false here?

README.md Outdated
| restrictions | [] | A list of resolve restrictions |
| roots | [] | A list of root paths |
| symlinks | true | Whether to resolve symlinks to their symlinked location |
| tsconfig | true | Path to tsconfig.json for paths mapping. Default true loads tsconfig.json, or pass a string path. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be false by default

}

const content = await new Promise((resolve, reject) => {
fileSystem.readFile(jsonFilePath, "utf8", (err, data) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's avoid using utf8 for any reads for caching purposes

@alexander-akait
Copy link
Member

@xiaoxiaojx Looked at code, and it looks good, let's do some options refactor like oxc have for typescript - https://github.com/oxc-project/oxc-resolver?tab=readme-ov-file#typescript-configuration, i.e. tsconfig: true | false | { configFile: string | true | false , references: "auto" | string[], paths: "auto" | string[], ...etc }, provided option will override tsconfig.json values

@xiaoxiaojx xiaoxiaojx force-pushed the feat/tsconfigPaths branch 7 times, most recently from 271e145 to f07913d Compare November 15, 2025 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants