vite打包时提示 "@charset" must be the first rule in the file 并且打包后的项目部分样式不生效

527 阅读2分钟

打包时发现控制台报了个warning:"@charset" must be the first rule in the file [invalid-@charset] 并且在运行打包好的项目时,发现大部分样式都未生效

在打包后的css文件中找到了如下代码

image.png image.png

仔细观察后可以发现,我们自己的css代码中间插入了elPlus的样式

由于涉及到的css代码量较少,将相关css代码注释之后,控制台仍在输出警告信息,但内容似乎有了一点变化

控制台输出

vite v3.2.2 building for production...
✓ 1427 modules transformed.
rendering chunks (6)...warnings when minifying css:

▲ [WARNING] "@charset" must be the first rule in the file [invalid-@charset]

    <stdin>:1:10418:
      1 │ ...ition:var(--el-transition-duration-fast);opacity:0}@charset "UTF-8"
        ╵                                                       ~~~~~~~~

  This rule cannot come before a "@charset" rule
      <stdin>:1:0:
      1 │ .fade-in-linear-enter-active,.fade-in-linear-leave-active{transitio...
        ╵ ^

▲ [WARNING] Expected "{" but found end of file [css-syntax-error]

    <stdin>:3:27:
      3/* -- 自定义属性 -- */
        │                  ^
        ╵                  {

再次查看打包后的css文件,由于删除了我们自己的代码,所以打包后的文件中只有elPlus的样式了,但在文件末尾,多了一个 @charset "UTF-8"

问题原因

  • postcss给含有中文的scss 加了个@charset:UTF-8;
  • element-plus的index.css文件包含@charset:UTF-8

在组合css时@charset的位置并不是在头部(或最前面),同时本地scss如果有中文也会自动添加@charset:UTF-8。因此build时就会warning提示错误了。

解决方案:在vite的配置项中加入css配置项

        // vite.config.js
        import { defineConfig } from "vite";
        
        // 为了避免误会,所以将整个代码结构都贴出来了。将此配置项按需复制到自己项目中即可
        export default defineConfig({
            // 禁止postcss和scss在打包后的文件中添加@charset utf-8
            css: {
              preprocessorOptions: {
                scss: {
                  charset: false,
                },
              },
              postcss: {
                plugins: [
                  {
                    postcssPlugin: "internal:charset-removal",
                    AtRule: {
                      charset: (atRule) => {
                        if (atRule.name === "charset") {
                          atRule.remove();
                        }
                      },
                    },
                  },
                ],
              },
            }
        })

相关文章