Skip to content

fix(tsconfig): apply each referenced project's own allowJs#1198

Merged
Boshen merged 1 commit into
oxc-project:mainfrom
shulaoda:06-03-fix_tsconfig_apply_each_referenced_project_s_own_allowjs_when_resolving_a_solution
Jun 3, 2026
Merged

fix(tsconfig): apply each referenced project's own allowJs#1198
Boshen merged 1 commit into
oxc-project:mainfrom
shulaoda:06-03-fix_tsconfig_apply_each_referenced_project_s_own_allowjs_when_resolving_a_solution

Conversation

@shulaoda

@shulaoda shulaoda commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

What

Fixes solution-style tsconfig.json resolution so that each referenced project's own allowJs decides whether it claims a .js/.jsx/.mjs/.cjs file, instead of inheriting the answer from the parent solution config.

Why

A common Vite project layout uses a solution tsconfig.json that contains nothing but references:

// tsconfig.json
{ "include": [], "references": [{ "path": "./tsconfig.app.json" }] }
// tsconfig.app.json
{
  "compilerOptions": {
    "composite": true,
    "allowJs": true,
    "paths": { "@alias/*": ["./src/*"] }
  },
  "include": ["src/**/*"]
}

The root config does not set allowJs, but the referenced tsconfig.app.json does.

resolve_tsconfig_solution used to short-circuit on tsconfig.is_file_extension_allowed_in_tsconfig(path) — i.e. the parent's allowJsbefore iterating the references. For a .js file this returned false, so no reference was ever consulted, the referenced project's paths alias never applied, and resolving @alias/foo.js from src/index.js failed with NotFound.

How

  • Remove the parent-level extension check from resolve_tsconfig_solution.
  • Add the extension check as step 0 inside is_file_included_in_tsconfig, where it is evaluated against self — i.e. each referenced project's own allowJs.

This keeps the existing is_glob_match fast-path behavior intact and makes ownership consistent with claims_ownership_of, which already evaluates references via is_file_included_in_tsconfig.

Tests

Added referenced_config_allow_js_uses_own_setting in src/tests/tsconfig_project_references.rs with a new fixture under fixtures/tsconfig/cases/project-references-ref-allow-js/ (root solution without allowJs, referenced app config with allowJs: true and a paths alias).

Resolving @alias/foo.js from src/index.js:

  • Before the fix: Err(NotFound("@alias/foo.js"))
  • After the fix: Ok(.../src/foo.js)

@codspeed-hq

codspeed-hq Bot commented Jun 3, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

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

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
pm/npm-flat 929.2 µs 984.4 µs -5.61%
pm/pnpm-isolated 1.1 ms 1.1 ms -4.78%
pm/yarn-flat 997.8 µs 1,044.3 µs -4.45%
pm/pnpm-hoisted 1.1 ms 1.1 ms +3.61%

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-03-fix_tsconfig_apply_each_referenced_project_s_own_allowjs_when_resolving_a_solution (eb4f9a2) with main (4a9f78c)

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.

@Boshen Boshen self-assigned this Jun 3, 2026
@Boshen Boshen force-pushed the 06-03-fix_tsconfig_apply_each_referenced_project_s_own_allowjs_when_resolving_a_solution branch from 262a553 to eb4f9a2 Compare June 3, 2026 09:33
@Boshen Boshen merged commit d24aa2b into oxc-project:main Jun 3, 2026
14 checks passed
@oxc-guard oxc-guard Bot mentioned this pull request Jun 3, 2026
Boshen pushed a commit that referenced this pull request Jun 3, 2026
## 🤖 New release

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

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

## `oxc_resolver`

<blockquote>

##
[11.21.0](v11.20.0...v11.21.0)
- 2026-06-03

### <!-- 0 -->🚀 Features

- *(tsconfig)* support package.json imports field in extends
([#1199](#1199)) (by
@Boshen)

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

- *(tsconfig)* apply each referenced project's own `allowJs`
([#1198](#1198)) (by
@shulaoda)
- make symlink_metadata VPath-aware for Yarn PnP
([#1183](#1183)) (by
@Boshen)

### <!-- 4 -->⚡ Performance

- borrow relative main field instead of allocating a "./" prefix
([#1187](#1187)) (by
@Boshen)
- *(cache)* move package.json path into parse instead of cloning
([#1186](#1186)) (by
@Boshen)
- eliminate symlink stat syscalls by reusing canonicalization
([#1184](#1184)) (by
@Boshen)
- reduce resolution syscalls by unifying stat and lstat
([#1182](#1182)) (by
@Boshen)

### <!-- 9 -->💼 Other

- add baselines for each package manager x node_modules layout
([#1176](#1176)) (by
@Boshen)

### Contributors

* @shulaoda
* @Boshen
* @renovate[bot]
</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>
shulaoda added a commit to rolldown/rolldown that referenced this pull request Jun 3, 2026
> [!IMPORTANT]
> **This is a minor release.** Two changes alter default behavior compared to `1.0.3`. Please read this section before upgrading. Everything else is additive (new features, fixes, deps).

## ⚠️ Notable behavior changes

### 1. `experimental.lazyBarrel` is now enabled by default (#9632)

**What changed.** `experimental.lazyBarrel` now defaults to `true`. When a barrel module is recognized as side-effect-free, Rolldown skips compiling the re-exported modules that are never actually used.

**Impact.** For codebases with large barrel files (component libraries such as Ant Design, `@mui/icons-material`, etc.) this is a meaningful build-time speedup, and for the vast majority of projects the emitted output is unchanged. In rare cases where a barrel is *incorrectly* treated as side-effect-free, the optimization could drop a module that was being relied on for its side effects.

**How to opt out (backward compatible).**

```js
// rolldown.config.js
export default {
  experimental: { lazyBarrel: false },
}
```

> Note: this opt-out flag is planned to be removed in a future release. If you have a case where you must turn it off, please open an issue so we can fix the underlying detection instead.

---

### 2. `tsconfig` project-reference resolution now aligns with TypeScript

Upgrading `oxc_resolver` (`11.19.1` → `11.20.0` in #9549, then `→ 11.21.0` in #9634) changes how a *solution-style* `tsconfig.json` (one that only lists `references` and delegates the real settings to `tsconfig.app.json` / `tsconfig.node.json`, as Vite scaffolds) is resolved, bringing it **in line with how TypeScript (`tsc`) itself behaves**:

- **Reference match priority** (oxc-resolver [#1151](oxc-project/oxc-resolver#1151)): when the root has `references`, a referenced project that includes the file now **takes precedence over the root**, instead of the root matching it first (this is what TypeScript already does). So that project's `compilerOptions.paths` now apply.
- **`allowJs`** (oxc-resolver [#1198](oxc-project/oxc-resolver#1198)): whether a `.js`/`.jsx`/`.mjs`/`.cjs` file is included is now decided by **each referenced project's own** `allowJs`, not the root's (again matching TypeScript). So `tsconfig.app.json` with `allowJs: true` + `paths` now resolves aliases for `.js` files even when the root doesn't set `allowJs`.

For most projects this is a fix (the standard Vite `paths` aliases now resolve, closes #8468), but it **is** a behavior change if you relied on the previous behavior, where the root's `paths` / `allowJs` took precedence.

**If you relied on the old "root wins" behavior.** There is no exact toggle back, because the old behavior was the bug being fixed. The recommended path is to align your config with TypeScript: declare the `paths` / `allowJs` on the referenced project that actually owns the files.

If you must keep the old precedence while still using `references`: a referenced project's match wins, and **the first matching `references` entry takes priority** (the root is only a fallback when no reference claims the file). So extract the old root settings into their own config and list it **first**:

```jsonc
// tsconfig.json (solution root)
{
  "files": [],
  "references": [
    { "path": "./tsconfig.base.json" }, // old root paths/allowJs — listed first, so it wins
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
```

`tsconfig.base.json` should carry the `paths` you previously declared on the root, plus `allowJs: true` if it needs to claim `.js` files (the extension is checked against each config's own `allowJs`). With no `include`, it defaults to `**/*` under its directory and claims every file first.

Alternatively, bypass reference resolution entirely by pointing the top-level `tsconfig` option at a single config: `export default { tsconfig: './tsconfig.app.json' }`.

---

## [1.1.0] - 2026-06-03

### 🚀 Features

- enable `experimental.lazyBarrel` by default (#9632) by @shulaoda
- `import.meta.glob` support `caseSensitive` option (#9594) by @btea
- add `SOURCEMAP_BROKEN` warning for renderChunk hook (#9601) by @sapphi-red
- add `SOURCEMAP_BROKEN` warning for transform hook (#9600) by @sapphi-red
- add `@__NO_SIDE_EFFECTS__` hint for invalid `@__PURE__` before function declarations (#9505) by @Copilot
- code-splitting: support group-local `includeDependenciesRecursively` (#9587) by @hyf0

### 🐛 Bug Fixes

- report TSCONFIG_ERROR instead of UNHANDLEABLE_ERROR for a missing tsconfig file (#9633) by @shulaoda
- browser: add missing exports and ensure consistency with `rolldown` package (#9629) by @sapphi-red
- should build test-dev-server when test-node (#9610) by @situ2001
- chunk-optimizer: refuse asymmetric merge for cyclic dynamic entries (#9320) (#9322) by @aminpaks
- dev: handle the remaining errors in dev (#9570) by @h-a-n-a
- handle slash-normalized ids with preserveModulesRoot (#9595) by @IWANABETHATGUY
- json: preserve .default access on JSON default imports (#9568) by @IWANABETHATGUY
- testing: remove unintended trigger_full_build from test harness (#9573) by @hyf0

### 🚜 Refactor

- js-regex: use regress native replace/replace_all (#9607) by @IWANABETHATGUY
- remove never-constructed `ImportStatus` variants (#9606) by @Boshen

### 📚 Documentation

- clarify that `RolldownBuild::close` method should be called in most cases (#9619) by @sapphi-red

### ⚡ Performance

- avoid unnecessary intermediate sourcemaps (#9599) by @sapphi-red

### 🧪 Testing

- add unit test for collapsing module sourcemap (#9626) by @sapphi-red
- cover vite-alias regex capture-group expansion (#9602) (#9608) by @IWANABETHATGUY

### ⚙️ Miscellaneous Tasks

- deps: update oxc_resolver to 11.21.0 (#9634) by @shulaoda
- update invalid option diagnostic link to point to Rolldown docs (#9631) by @sapphi-red
- deps: update vite+ to v0.1.24 (#9628) by @renovate[bot]
- deps: update oxc resolver to v11.20.0 (#9549) by @renovate[bot]
- deps: update dependency vite-plus to v0.1.24 (#9470) by @renovate[bot]
- deps: update npm packages (#9614) by @renovate[bot]
- deps: upgrade oxc to 0.134.0 (#9625) by @shulaoda
- deps: update crate-ci/typos action to v1.47.0 (#9620) by @renovate[bot]
- deps: update rollup submodule for tests to v4.61.0 (#9623) by @rolldown-guard[bot]
- deps: update github actions (#9613) by @renovate[bot]
- deps: update pnpm to v11.4.0 (#9616) by @renovate[bot]
- deps: update rust crates (#9615) by @renovate[bot]
- deps: update test262 submodule for tests (#9624) by @rolldown-guard[bot]
- deps: update dependency @napi-rs/cli to v3.7.0 (#9588) by @renovate[bot]
- deps: update dependency rust to v1.96.0 (#9596) by @renovate[bot]
- re-enable WASI testing with proper infrastructure (#9397) by @Boshen

### ❤️ New Contributors

* @aminpaks made their first contribution in [#9322](#9322)

Co-authored-by: shulaoda <[email protected]>
shulaoda added a commit to rolldown/rolldown that referenced this pull request Jun 3, 2026
…ior (#9641)

## What

Updates `packages/rolldown/src/options/docs/tsconfig.md` to describe how a tsconfig's `references` are resolved as of **v1.1.0**. Docs-only, no behavior or code change.

## Why

The reference resolution behavior changed in v1.1.0 through the `oxc_resolver` upgrades:

- **#9549** (`oxc_resolver` → `11.20.0`) brought in oxc-resolver [#1151](oxc-project/oxc-resolver#1151): a referenced project that includes the file takes precedence over the root, instead of the root claiming it first.
- **#9634** (`oxc_resolver` → `11.21.0`) brought in oxc-resolver [#1198](oxc-project/oxc-resolver#1198): whether a `.js`/`.jsx`/`.mjs`/`.cjs` file is included is decided by each referenced project's own `allowJs`, not the root's.

The existing docs still described the previous model (root matches first, references consulted only as a fallback), which no longer holds. A solution-style `tsconfig.json` (only `references`, as Vite scaffolds) now resolves the way TypeScript does, which is also what made the standard Vite `paths` aliases resolve correctly again (#8468).

## Changes

- Rewrote the `references` resolution paragraph: a referenced project that includes the file takes precedence over the root, each referenced project uses its own `allowJs` (so a `.js`/`.jsx`/`.mjs`/`.cjs` file is only included where that project enables it), and the root is used only when no referenced project includes the file.
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