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

warning: "@charset" must be the first rule in the file (2.6.x regression ?) #6333

Closed
7 tasks done
mariusa opened this issue Dec 30, 2021 · 13 comments · Fixed by #7678
Closed
7 tasks done

warning: "@charset" must be the first rule in the file (2.6.x regression ?) #6333

mariusa opened this issue Dec 30, 2021 · 13 comments · Fixed by #7678

Comments

@mariusa
Copy link

mariusa commented Dec 30, 2021

Describe the bug

npm run build shows 100 warnings with

 > <stdin>:15:7495: warning: "@charset" must be the first rule in the file
    15 │ ...transform:rotate(0)}to{transform:rotate(2turn)}}@charset "UTF-8";/*!
       ╵                                                    ~~~~~~~~
   <stdin>:15:6767: note: This rule cannot come before a "@charset" rule
    15 │ ...t:attr(data-deselect);color:#fff}.multiselect-enter-active,.multi...

Appears to be a regression in 2.6.x

To reproduce:

npm init vite@latest my-vue-app -- --template vue

then add just 3 libraries to package.json and main.js

Minimal repo: https://github.com/mariusa/vite-warn

npm install
npm run build

FYI Also tried adding this to vite.config.js, which is not a solution (hiding the warnings instead of fixing the cause)

css: { preprocessorOptions: { scss: { charset: false } } }

but has no effect on warnings.

Previous reports, closed: #5519

Could this be caused by https://github.com/postcss/postcss-import ?
FYI sass/dart-sass#567 (comment)

Reproduction

https://github.com/mariusa/vite-warn

System Info

to proceed? (y) y

  System:
    OS: Linux 5.14 Fedora Linux 35 (Workstation Edition Prerelease)
    CPU: (8) x64 AMD Ryzen 7 4700U with Radeon Graphics
    Memory: 1.58 GB / 15.00 GB
    Container: Yes
    Shell: 5.1.8 - /bin/bash
  Binaries:
    Node: 16.10.0 - /usr/bin/node
    npm: 7.24.0 - /usr/bin/npm
  Browsers:
    Chrome: 96.0.4664.110
    Firefox: 93.0
  npmPackages:
    @vitejs/plugin-vue: ^2.0.0 => 2.0.1 
    vite: ^2.7.2 => 2.7.10

Used Package Manager

npm

Logs

vite v2.7.10 building for production...
✓ 78 modules transformed.
rendering chunks (1)...warnings when minifying css:
 > <stdin>:15:7495: warning: "@charset" must be the first rule in the file
    15 │ ...transform:rotate(0)}to{transform:rotate(2turn)}}@charset "UTF-8";/*!~~~~~~~~
   <stdin>:2:0: note: This rule cannot come before a "@charset" rule
     2 │ a[data-v-3d3c9e2e] {
       ╵ ^


 > <stdin>:15:7495: warning: "@charset" must be the first rule in the file
    15 │ ...transform:rotate(0)}to{transform:rotate(2turn)}}@charset "UTF-8";/*!~~~~~~~~
   <stdin>:6:0: note: This rule cannot come before a "@charset" rule
     6 │ #app {
       ╵ ^
...

Validations

@agileago
Copy link

vite.config.ts

css: {
    postcss: {
      plugins: [
        {
          postcssPlugin: 'internal:charset-removal',
          AtRule: {
            charset: (atRule) => {
              if (atRule.name === 'charset') {
                atRule.remove();
              }
            }
          }
        }
      ]
    }
}

@mariusa
Copy link
Author

mariusa commented Dec 31, 2021

Would be great to identify the root cause and fix that. (also, to avoid every vite user adding this workaround)
Is it postcss not merging properly multiple CSS files? Is there an issue reported at postcss?

@gluck
Copy link
Contributor

gluck commented Jan 3, 2022

Note that esbuild css minification is the one triggering the warnings, and they fixed it in 0.14.6 that only 1 warning is generated (instead of 1 warning per rule before @charset): evanw/esbuild#1862

(But I agree that proper css bundling shouldn't have the @charset rule at all)

@mariusa
Copy link
Author

mariusa commented Jan 3, 2022

How to ensure proper css bundling? Is there a postcss option that vite could pass to remove @charset ?

@Shinigami92
Copy link
Member

I'm affected by this, but #6333 (comment) works 👍

@simenbrekken
Copy link

It should be noted that the charset option was added to sass in v1.39.0 so you might have to go with the plugin approach if your project uses an older version of sass.

@bluwy
Copy link
Member

bluwy commented Feb 22, 2022

According to the esbuild warning, it seems like esbuild has a hard stance that that's how @charset would work (likely by a spec). So I doubt esbuild will be fixing that soon. So I think the correct solution is to disable the charset through preprocessorOptions.

I didn't need a postcss plugin to fix it though, but specifying the config for both sass and scss worked for me:

css: {
  preprocessorOptions: {
   sass: { charset: false },
   scss: { charset: false },
  },
},

@imrim12
Copy link

imrim12 commented Mar 8, 2022

vite.config.ts

css: {
    postcss: {
      plugins: [
        {
          postcssPlugin: 'internal:charset-removal',
          AtRule: {
            charset: (atRule) => {
              if (atRule.name === 'charset') {
                atRule.remove();
              }
            }
          }
        }
      ]
    }
}

works for me, thanks

@claranceliberi
Copy link

vite.config.ts

css: {
    postcss: {
      plugins: [
        {
          postcssPlugin: 'internal:charset-removal',
          AtRule: {
            charset: (atRule) => {
              if (atRule.name === 'charset') {
                atRule.remove();
              }
            }
          }
        }
      ]
    }
}

Using this with tailwind 3.0.23 fixes the problem but invalidates my styles from this
image
to this
image

@bluwy
Copy link
Member

bluwy commented Apr 1, 2022

I'm not sure if there's anything else Vite can fix here. esbuild is reporting a real issue IMO, and it's helpful to remove the unwanted @charset. Perhaps this can be closed with the workaround as the solutions? Unless Vite should apply the workarounds as defaults.

@mariusa
Copy link
Author

mariusa commented Apr 1, 2022

I'm not sure if there's anything else Vite can fix here

Agreed. Not closing as as it would be great to identify the root cause and fix that. (also, to avoid every vite user adding this workaround). I'm not knowledgeable enough to identify the root cause.
Is it postcss not merging properly multiple CSS files? Is there an issue reported at postcss?
This issue could be closed with a link to Postcss issue.

@bluwy
Copy link
Member

bluwy commented Apr 3, 2022

The root issue is that some libraries export CSS or SCSS files with the @charset identifier in the code. When Vite merges them, multiple @charset appears around the CSS code, which is invalid. Looking at the docs, merging them in the first place seems to be potentially breaking, but I've never see this being an issue in practice. Maybe it does make sense for Vite to apply the postcss plugin by default.

@mariusa
Copy link
Author

mariusa commented Apr 4, 2022

Thanks!

Looks like libraries are right to have this @charset, eg

This at-rule is useful when using non-ASCII characters in some CSS properties, like content.

Since we can't request libraries to remove the rule, vite should deal with it when building the bundle. The alternative is having every user having to search for this warning, discover & implement the solution.

@bluwy bluwy mentioned this issue Apr 11, 2022
9 tasks
@github-actions github-actions bot locked and limited conversation to collaborators Apr 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants