Skip to content

fix(deps): update dependency @nestjs/serve-static to v12 - #193

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/nestjs-serve-static-12.x
Open

fix(deps): update dependency @nestjs/serve-static to v12#193
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/nestjs-serve-static-12.x

Conversation

@renovate

@renovate renovate Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Confidence
@nestjs/serve-static ^5.0.4^12.0.0 age confidence

Release Notes

nestjs/serve-static (@​nestjs/serve-static)

v12.0.0

Compare Source

What's Changed

@nestjs/serve-static is now a native ES module, and the major version is aligned with the Nest 12 release line (there is no 6.x–11.x — 5.0.5 goes straight to 12.0.0).

ESM migration

The package is published as pure ESM ("type": "module", compiled with NodeNext) behind a proper exports map. The legacy root index.js / index.d.ts shims are gone, and deep imports into build internals are no longer resolvable — import from the package root.

The runtime was migrated too, not just the build output: the optional express and @fastify/static loads now go through createRequire(import.meta.url) instead of a bare require(). Under a native ESM loader the old code threw ReferenceError, which loadPackage swallowed before calling process.exit(1) — taking the host application down at startup.

If you pass rootPath: join(__dirname, '..', 'client') from an ESM app, switch to import.meta.dirname:

ServeStaticModule.forRoot({
  rootPath: join(import.meta.dirname, '..', 'client')
})

require(esm) — CommonJS still works

You do not need to convert your app to ESM. Thanks to Node's require(esm) support, CommonJS applications can keep using require('@nestjs/serve-static') unchanged.

TypeScript projects that compile to CommonJS need "module": "nodenext" in their tsconfig.json. The older "node16" setting predates require(esm) and will report TS1479.

Node.js requirement

An engines floor is now declared so npm blocks installs on versions without require(esm):

^20.19.0 || ^22.12.0 || >=23.0.0

Peer dependencies

  • @nestjs/common and @nestjs/core^12.0.0
  • @fastify/static^10.0.0 (the ^8 || ^9 range is dropped; v10 carries a security fix)
  • express ^5.0.1 and fastify ^5.2.1 are unchanged

Features

  • exclude now accepts a RegExp in addition to an array of path strings, for cases where a single pattern is clearer than enumerating routes (#​1983):

    ServeStaticModule.forRoot({
      rootPath: join(import.meta.dirname, '..', 'client'),
      exclude: /^\/api(\/.*)?$/
    })

    Query strings are stripped before matching, same as with the string form.

Bug fixes

  • An aborted page load no longer crashes the process (#​2024, closes #​2023). The SPA fallback answered every res.sendFile error with a 404, including a client abort — by which point headers and part of the body were already on the wire, so res.status().send() threw ERR_HTTP_HEADERS_SENT. Express fires that callback from a setImmediate, so the throw landed outside the middleware chain and outside any exception filter. The fallback now bails out once res.headersSent is true. Errors raised before anything is sent, such as a missing index file, still produce the 404.

  • A read error mid-transfer no longer hangs the request. send destroys only the read stream, and stream.pipe(res) does not end the destination on error, so the client waited for a timeout. res.end() is not enough — send has already committed a Content-Length the truncated body cannot satisfy — so the response is destroyed instead. The failure is now logged, excluding ECONNABORTED so routine client aborts do not spam the logs.

  • Non-404 failures are no longer rewritten as Not Found (#​1728). A genuine fault from upstream middleware on an excluded path was reported as 404 Cannot GET /api instead of a 500, so it never reached an exception filter or tripped 5xx alerting. The error middleware now only acts on an actual missing file and lets everything else through untouched. An HttpException raised by the application is passed through as-is, so something like ConflictException('ENOENT: ...') keeps its own status instead of being turned into a 404.

  • A global or sticky exclude RegExp no longer alternates between matching and not. RegExp.prototype.test advances lastIndex, and the pattern is reused across requests, so /^\/api(\/.*)?$/g produced 404, 200, 404, 200 on consecutive calls — silently serving the SPA index HTML on every other API request. Matching now uses String.prototype.search, which leaves lastIndex untouched.

Internal

Toolchain moved to oxlint, Vitest, and TypeScript 7. The loaders now call loadPackageSync() from @nestjs/common, since loadPackage() became async in Nest 12 while register() remains synchronous.


Configuration

📅 Schedule: (in timezone Asia/Kolkata)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate
renovate Bot force-pushed the renovate/nestjs-serve-static-12.x branch from 7f623b2 to e5f75f0 Compare September 3, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants