Skip to content

fix(tsconfig): walk up for non-TS and allowJs-off .js importers#1216

Merged
Boshen merged 1 commit into
oxc-project:mainfrom
shulaoda:06-17-fix_tsconfig_walk_up_for_non-ts_and_allowjs-off_.js_importers
Jun 17, 2026
Merged

fix(tsconfig): walk up for non-TS and allowJs-off .js importers#1216
Boshen merged 1 commit into
oxc-project:mainfrom
shulaoda:06-17-fix_tsconfig_walk_up_for_non-ts_and_allowjs-off_.js_importers

Conversation

@shulaoda

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1213. When auto-discovering a tsconfig.json for an importer, claims_ownership_of treated any file the tsconfig doesn't compile as "owned by the nearest tsconfig" and stopped the upward walk. That blanket shortcut intercepted files that an ancestor project genuinely owns.

The problem

The guard was:

if !self.is_file_extension_allowed_in_tsconfig(path) {
    return true; // claimed by the nearest tsconfig
}

is_file_extension_allowed_in_tsconfig is true only for TS extensions (and JS when allowJs is on), so the negation claimed non-TS files (.vue, .css), extensionless paths, and allowJs-off .js alike. Two concrete failures:

  1. Non-TS files don't reach their solution project. A child tsconfig.json including only **/*.ts would claim a sibling App.vue. Auto-discovery stopped at the child, so a solution root that references a config with include: ["src/**/*.vue"] and a @/* alias never owned the file and the alias didn't resolve.
  2. allowJs-off .js leaks a referenced project's paths. A referenced project with allowJs off but include: ["src/**/*.js"] would still route a .js importer through itself, applying its @lib/* paths to a file TypeScript excludes from the program.

The fix

  • claims_ownership_of — narrow the early return true to path.extension().is_none(). A directory (extensionless importer) isn't a file, so files/include ownership doesn't apply and the nearest enclosing tsconfig governs it (many discovery cases rely on its paths/baseUrl/extends). A genuine file — including an allowJs-off .js this config won't compile — is claimed only when actually owned, otherwise the walk continues up.
  • is_file_included_in_tsconfig — reject non-program inputs (an allowJs-off .js, even when a glob names .js; or an extensionless path) before consulting include, so resolve_tsconfig_solution won't route such files to a referenced project.
  • Extracted is_extensionless_or_uncompiled_js to share that predicate.

Directory importers are unchanged: they still resolve against their nearest tsconfig (verified by the existing tsconfig_discovery cases).

Tests

  • solution_style_nested_non_ts_walks_up (new) — a child config including only **/*.ts no longer intercepts App.vue; the walk reaches the solution project that owns @/*. A .ts the child includes stays on the child; an allowJs-off legacy.js walks up like the .vue.
  • referenced_config_drops_js_when_allow_js_off (new) — a .ts importer resolves @lib/*; a .js importer does not (dropped because allowJs is off).
  • solution_style_non_ts_extensions (updated) — a .css matched by no include walks past the solution root to the outermost ancestor, and the @/* alias does not leak into it.

New fixtures under fixtures/tsconfig/cases/referenced-allow-js-off/ and fixtures/tsconfig/cases/solution-style-non-ts/src/feature/.

@Boshen Boshen merged commit d0d956b into oxc-project:main Jun 17, 2026
14 checks passed
@oxc-guard oxc-guard Bot mentioned this pull request Jun 17, 2026
Boshen pushed a commit that referenced this pull request Jun 17, 2026
## 🤖 New release

* `oxc_resolver`: 11.21.0 -> 11.21.1
* `oxc_resolver_napi`: 11.21.0 -> 11.21.1

<details><summary><i><b>Changelog</b></i></summary><p>

## `oxc_resolver`

<blockquote>

##
[11.21.1](v11.21.0...v11.21.1)
- 2026-06-17

### <!-- 1 -->🐛 Bug Fixes

- *(tsconfig)* walk up for non-TS and `allowJs`-off `.js` importers
([#1216](#1216)) (by
@shulaoda)
- *(tsconfig)* honor explicit non-TS extensions in `include`
([#1213](#1213)) (by
@shulaoda)

### <!-- 2 -->🚜 Refactor

- *(cache)* replace papaya with dashmap
([#1214](#1214)) (by
@Boshen)

### <!-- 6 -->🧪 Testing

- verify node_modules canonicalization across layouts
([#1200](#1200)) (by
@Boshen)

### Contributors

* @shulaoda
* @Boshen
</blockquote>



</p></details>

---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
@codspeed-hq

codspeed-hq Bot commented Jun 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

⚡ 3 improved benchmarks
❌ 1 regressed benchmark
✅ 17 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
pm/yarn-isolated 1 ms 1.1 ms -5.54%
pm/pnpm-isolated 1.1 ms 1 ms +5.35%
pm/bun-flat 999.7 µs 950.9 µs +5.13%
pm/npm-flat 960.7 µs 932.6 µs +3.02%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing shulaoda:06-17-fix_tsconfig_walk_up_for_non-ts_and_allowjs-off_.js_importers (4db9ff8) with main (c55a3e1)

Open in CodSpeed

Footnotes

  1. 5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@oxc-guard oxc-guard Bot mentioned this pull request Jun 17, 2026
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.

2 participants