Skip to content

fix(vite): inline release bundle css with minified sentinel, in import order - #11477

Merged
NathanWalker merged 1 commit into
mainfrom
fix/vite-bundle-css-inlining
Sep 29, 2026
Merged

NathanWalker merged 1 commit into
mainfrom
fix/vite-bundle-css-inlining

Conversation

@NathanWalker

Copy link
Copy Markdown
Contributor

PR Checklist

What is the current behavior?

In release builds, CSS imported from JS/TS or SFC <style> blocks is inlined into the bundle by mainEntryPlugin's generateBundle, which replaces a __NS_BUNDLE_CSS_AST__ sentinel with the stylesheet AST. Two problems:

  1. The release minifier runs before generateBundle and prints the sentinel as a template literal (m(`__NS_BUNDLE_CSS_AST__`,`ns-bundle-css`)). The replacement regex only accepts ' and ", so it never matches and the stylesheet is silently dropped.
  2. CSS assets were concatenated in bundle order, which puts the entry's CSS ahead of vendor.css. Rules from node_modules stylesheets then win equal-specificity ties against the app's overrides, unlike in dev.

What is the new behavior?

The inlining logic moves to helpers/bundle-css.ts:

  • The sentinel regex also accepts backticks.
  • CSS assets are collected by walking the chunk graph from the entries: a chunk's static imports' CSS, then its own (viteMetadata.importedCss), then its dynamic imports, then any unclaimed assets. This matches import order, as in dev.

Verified with a release build (vite build --mode production -- --env.ios) of an app importing a node_modules stylesheet and then an app stylesheet. Before the fix, the sentinel was left in bundle.mjs and neither rule was present. After the fix, bundle CSS: 2 asset(s) … applied=true, no sentinel remains, and the vendor rule precedes the app rule in the inlined AST.

Tests: packages/vite/helpers/bundle-css.spec.ts covers the template-literal and quoted sentinels, import ordering (static before importer, dynamic after, unclaimed last), and keeping the assets when no chunk carries the sentinel.

Closes #11476.

…t order

The release minifier prints the bundle-CSS sentinel as a template literal,
which the quote-only regex missed, so JS-imported CSS was silently dropped.
CSS assets are now also concatenated in chunk import order so vendor.css
precedes the app's CSS, matching dev.

Closes #11476
@nx-cloud

nx-cloud Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit c57cf2f

Command Status Duration Result
nx test apps-automated -c=android ✅ Succeeded 3m 40s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-09-29 22:13:11 UTC

@pkg-pr-new

pkg-pr-new Bot commented Sep 29, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@nativescript/core@11477
npm i https://pkg.pr.new/@nativescript/vite@11477
npm i https://pkg.pr.new/@nativescript/webpack@11477

commit: c57cf2f

@NathanWalker
NathanWalker merged commit 6b38d20 into main Sep 29, 2026
9 of 10 checks passed
@NathanWalker
NathanWalker deleted the fix/vite-bundle-css-inlining branch September 29, 2026 22:22
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.

@nativescript/vite: release builds ship without app CSS (minified sentinel uses backticks) and vendor CSS overrides app CSS

1 participant