Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect manifest entries for CSS entry points #14271

Closed
7 tasks done
si14 opened this issue Sep 3, 2023 · 5 comments · Fixed by #14909
Closed
7 tasks done

Incorrect manifest entries for CSS entry points #14271

si14 opened this issue Sep 3, 2023 · 5 comments · Fixed by #14909
Labels
documentation Improvements or additions to documentation feat: css

Comments

@si14
Copy link

si14 commented Sep 3, 2023

Describe the bug

When I include a CSS file as an entry point (for example, when building styles for pages that use server-side templating), I'd expect Vite to generate a corresponding CSS file entry in the manifest. Instead, it generates an empty JS file on the relevant path and a separate entry for the CSS file placed in the "root".

Here's a minimal vite.config.js:

import { resolve } from "path";
import { defineConfig } from "vite";

export default defineConfig({
  base: "/static/",
  build: {
    outDir: "build/web/",
    assetsDir: "static/vite/",
    cssCodeSplit: false,
    manifest: "vite-manifest.json",
    rollupOptions: {
      input: {
        page: resolve(__dirname, "web/src/pages/page.js"),
        style: resolve(__dirname, "web/src/style.css"),
      },
    },
  },
});

Here's the manifest Vite generates:

{
  "style.css": {
    "file": "static/vite/style-3ef20994.css",
    "src": "style.css"
  },
  "web/src/pages/page.js": {
    "file": "static/vite/page-9527d353.js",
    "isEntry": true,
    "src": "web/src/pages/page.js"
  },
  "web/src/style.css": {
    "file": "static/vite/style-4ed993c7.js",
    "isEntry": true,
    "src": "web/src/style.css"
  }
}

You can see that the key web/src/style.css (which, according to the docs, can be used as a key into the manifest to have dev/prod parity) maps to static/vite/style-4ed993c7.js, which is an empty JS file. There is an entry for just style.css that points to the correct file, but it seems inconsistent with the rest of the manifest.

This problem is very reminiscent of what @jessarcher observed in a related PR, but the PR makes it sound like it was fixed at the time, so maybe it's a regression.

Reproduction

https://stackblitz.com/edit/vitejs-vite-kx9tp7?file=build%2Fweb%2Fvite-manifest.json

Steps to reproduce

vite build in the stackblitz above

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.20.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.4.2 - /usr/local/bin/npm
    pnpm: 8.6.10 - /usr/local/bin/pnpm
  npmPackages:
    vite: ^4.4.9 => 4.4.9

Used Package Manager

npm

Logs

No response

Validations

@stackblitz
Copy link

stackblitz bot commented Sep 3, 2023

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

@bluwy bluwy added p3-minor-bug An edge case that only affects very specific usage (priority) feat: ssr and removed pending triage labels Sep 4, 2023
@sapphi-red
Copy link
Member

I'm not sure what the expected behavior is.
build.cssCodeSplit: false makes CSS into a single chunk separate from normal chunks (It behaves as if all CSS files are imported from style.css). But you are setting a CSS file in rollupOptions.input that creates an entry chunk.
What is the purpose of setting build.cssCodeSplit: false?

/cc @sun0day

@si14
Copy link
Author

si14 commented Sep 11, 2023

@sapphi-red I'd expect the number of .css files generated to exactly match the number of explicit .css entrypoints, without any consideration for the JS side of things or (if it ever happens as an optimisation) common CSS extraction similar to what happens with JS.

I see what you mean, and I guess rollupOptions.input clashes with build.cssCodeSplit option here, being mutually exclusive in a sense. I do think it's a bug and entrypoints should take priority, or at least the current behaviour should be documented.

@bluwy
Copy link
Member

bluwy commented Sep 15, 2023

I agree with @sapphi-red too. Even with the .css entrypoint added, the only corresponding output chunk is the empty static/vite/style-4ed993c7.js chunk, which also exists in the fs. The manifest shouldn't point to the single static/vite/style-3ef20994.css chunk. (This is clearer to see if you name the style: ... input to something like mystyle: ... and observe the chunk names)

I think it's best to document this instead. My bad for the mislabelling.

@bluwy bluwy added documentation Improvements or additions to documentation feat: css and removed p3-minor-bug An edge case that only affects very specific usage (priority) feat: ssr labels Sep 15, 2023
@silverwind
Copy link

silverwind commented Oct 5, 2023

What is the purpose of setting build.cssCodeSplit: false?

I had to set build.cssCodeSplit: true in my configs with CSS entry points because otherwise the name of the emitted files is not stable. E.g. if you have index.js and index.css as entry points without cssCodeSplit and the JS has CSS imports, index.css would receive the CSS imported from JS and vite emits a problematic index2.js for the CSS entry point.

Imho, all entry points should have priority on their filename over imports from other languages like JS because those JS imports will be dynamically loaded anyways while entry points absolutely must have stable output filenames.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
documentation Improvements or additions to documentation feat: css
Projects
None yet
4 participants