Repository navigation
fix(compiler): resolve the swc source root per application - #3589
Merged
kamilmysliwiec merged 2 commits intoSep 24, 2026
Merged
Conversation
In a monorepo, `nest build <app> --builder swc` compiled the default project's sources into the named application's outDir and exited 0, so `nest start <app> --builder swc` then failed with "Cannot find module dist/apps/<app>/main". swcDefaultsFactory read the root "sourceRoot", which is the default project's, while outDir came from the selected application's tsconfig. Resolve "sourceRoot" through getValueOrDefault and the application name, the way base-compiler and assets-manager already do. Watch mode read the same root key and forked the type checker with it, which pointed the CLI plugin metadata at a directory that does not exist; it now resolves the same way.
@swc/cli strips only the first path segment, so a monorepo source root such as apps/api/src was emitted as api/src/main.js, which nest start cannot resolve. Skip stripping for nested source roots so the output follows the <outDir>/<sourceRoot>/<entryFile> layout nest start expects.
4 of 5 tasks
kamilmysliwiec
pushed a commit
that referenced
this pull request
Sep 25, 2026
In watch mode with --type-check, the swc compiler forks the type checker with the root "compilerOptions.plugins" only. In a monorepo an application can declare its own plugins under "projects.<app>.compilerOptions.plugins", and the non-watch path already loads them per application through loadPlugins(), so `nest build api --builder swc --type-check` generated the CLI plugin metadata while `nest start api --builder swc --type-check --watch` reported "Found 0 issues" and generated none. Resolve the plugins through getValueOrDefault with the application name, the same way #3589 did for "sourceRoot" one argument above.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
After upgrading to 12.0.5 I tried swc on a two-app monorepo —
demois thedefault project,
apisits beside it.nest build api --builder swcprintsSuccessfully compiled: 5 filesand exits 0, but what lands indist/apps/apiis the default app:nest start api --builder swcthen fails withCannot find module .../dist/apps/api/main.(The workspace
nest newgenerates pins"builder": "rspack"innest-cli.json, so--builder swcon the command line is what selects swc —it is not the flag picking the wrong builder.)
swcDefaultsFactoryreadsconfiguration.sourceRootstraight off the root ofnest-cli.json. In a monorepo that key is the default project's source root,while
outDircomes from the selected application's tsconfig — so swc gets oneapp's sources and another app's output directory.
What is the new behavior?
sourceRootis resolved withgetValueOrDefaultand the application name, thelookup
base-compilerandassets-manageralready use, sofilenamesand thestripLeadingPathsderived from it follow the app being built. A project thatdeclares no
sourceRootof its own still falls back to the root value.runTypeCheckerread the same root key and now resolves it the same way.Same command on the same workspace:
and
nest start api --builder swcbootsApiModule.Tests: three in
swc-defaults.spec.ts(the named app'ssourceRootwins overthe root one,
stripLeadingPathsfollows it, a project without its ownsourceRootstill falls back), one inswc-compiler.spec.tsfor the forkedtype checker, and one e2e in
build.command.e2e-spec.tsthat builds the secondapp of a scaffolded monorepo with swc and asserts the default app's modules are
not in its
dist. An existing assertion inswc-compiler.spec.tsgained afourth argument, since
swcDefaultsFactorynow takes the application name.Does this PR introduce a breaking change?
stripLeadingPathsnow derives from the app's own source root, so a workspacethat pins root-level
builder.options.filenameswhile its approotDiris itsown
srcgets a different output layout. Measured on a monorepo whose rootsourceRootisapps/demo/src, withcompilerOptions.builder.options.filenames: ["apps/api/src"]andapps/api/tsconfig.app.jsonsetting"rootDir": "src",nest build api:Where the root
sourceRootalready is the built app's, nothing moves.Other information
runTypeCheckerforksforked-type-checker.jswith the sourceroot, and that argument is where the CLI plugin metadata file goes. With a
plugin configured,
nest build api --builder swc --watch --type-checkdied onENOENT ... apps/api/apps/demo/src/metadata.ts; it now writesapps/api/src/metadata.ts.Switching the same workspace to
nest buildwith no project name builds thedefault app correctly, so this only bites the named ones.