Serve fails to serve node_modules assets in monorepos

Open
#31,016 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
58/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
typescript, vite

Research direction

Start with packages/angular/build/src/builders/dev-server/vite/server.ts around the serverOptions.fs.allow setup, then compare it with Vite's searchForWorkspaceRoot behavior and reproduce the issue with the linked monorepo and npm start. Done means assets from node_modules outside the Angular project root load successfully without a 403 response.

Written by the indexing model from the issue text.

Description

area: @angular/build devkit/build-angular:dev-server freq1: low severity3: broken type: bug/fix
Command

serve

Is this a regression?
  • Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was

No response

Description

In a monorepo, node_modules may be located outside the Angular project root folder.

If a library from such outside node_modules tries to load any asset, e.g. a font file from a CSS file, the import is blocked by Vite's dev server with a 403 error.

Minimal Reproduction
  1. Clone this repo

    git clone https://github.com/maxpatiiuk/angular-monorepo-asset-serve-error
    cd angular-monorepo-asset-serve-error
    
  2. Install dependencies

    # To keep reproduction size minimal, I hardcoded a minimal root-level node_modules
    # So, install Angular dependencies only in the app folder:
    cd app
    npm install
    
  3. Start the development server in the app folder

    npm start
    

    See this error in the browser console:

    (index):14  GET http://localhost:4200/@fs/Users/.../angular-monorepo-asset-serve-error/node_modules/external-library/NotoSans.woff2 net::ERR_ABORTED 403 (Forbidden)
    
Exception or Error
(index):14  GET http://localhost:4200/@fs/Users/.../angular-monorepo-asset-serve-error/node_modules/external-library/NotoSans.woff2 net::ERR_ABORTED 403 (Forbidden)
Your Environment
Angular CLI: 20.2.0
Node: 22.16.0
Package Manager: npm 10.9.2
OS: darwin arm64
    

Angular: 20.2.1
... compiler-cli, core, platform-browser

Package                      Version
------------------------------------
@angular-devkit/architect    0.2002.0
@angular-devkit/core         20.2.0
@angular-devkit/schematics   20.2.0
@angular/build               20.2.0
@angular/cli                 20.2.0
@schematics/angular          20.2.0
rxjs                         7.8.2
typescript                   5.9.2
Anything else relevant?

Explanation & Solution

If you run the dev server with Vite config logging (DEBUG=vite:config npx ng serve), you will see that the dev server was allowed to serve only the package-level node_modules folder:

  vite:config     server: {
  vite:config       ...
  vite:config       fs: {
  vite:config         allow: [
  vite:config           '/Users/mak13180/site/esri/angular-monorepo-asset-serve-error/app/.angular/cache/20.2.0/reproduction/vite',
  vite:config           '/Users/mak13180/site/esri/angular-monorepo-asset-serve-error/app/node_modules'
  vite:config         ]
  vite:config       }
  vite:config     },

By default, Vite correctly detects that it is being run in a monorepo and allows serving from any monorepo node_modules, but Angular incorrectly overrides this behavior here:

https://github.com/angular/angular-cli/blob/cc05242aa8354f3280b5a70eb1f9c0e9d85f1408/packages/angular/build/src/builders/dev-server/vite/server.ts#L80-L90

The code comment states These would be available by default but when the 'allow' option is explicitly configured, they must be included manually.. However, Angular does not include things manually correctly.

Fortunately, the Vite's default behavior is easy to get back:

https://github.com/vitejs/vite/blob/e899bc7c73a27cdf327875e5d696c50d396a7fc2/packages/vite/src/node/server/index.ts#L1126-L1127

Their default calls searchForWorkspaceRoot(), which is exposed by Vite and can be called manually as documented in https://vite.dev/config/server-options.html#server-fs-allow.

I confirmed that updating the Angular code to the following fixes the issue:

- join(serverOptions.workspaceRoot, 'node_modules'),
+ searchForWorkspaceRoot(serverOptions.workspaceRoot),
Dominant language
TypeScript
Stars
27k
Forks
11.8k
Avg merge
16h 35m
Merged PRs (30d)
176

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from angular/angular-cli

All issues in angular/angular-cli

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.