vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.78k stars 6.33k forks source link

PostCSS plugins run twice when building with css.extract = false #7298

Open MartinManev opened 1 year ago

MartinManev commented 1 year ago

Version

5.0.8

Environment info

System:
    OS: Linux 4.9 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
  Binaries:
    Node: 16.9.1 - ~/.config/nvm/versions/node/v16.9.1/bin/node
    Yarn: 1.22.15 - ~/.config/nvm/versions/node/v16.9.1/bin/yarn
    npm: 8.19.2 - ~/.config/nvm/versions/node/v16.9.1/bin/npm
  Browsers:
    Chrome: 105.0.5195.125
    Firefox: 91.11.0esr
  npmPackages:
    @vue/babel-helper-vue-jsx-merge-props:  1.2.1 
    @vue/babel-helper-vue-transform-on:  1.0.2 
    @vue/babel-plugin-jsx:  1.1.1 
    @vue/babel-plugin-transform-vue-jsx:  1.2.1 
    @vue/babel-preset-app:  5.0.8 
    @vue/babel-preset-jsx:  1.3.1 
    @vue/babel-sugar-composition-api-inject-h:  1.3.0 
    @vue/babel-sugar-composition-api-render-instance:  1.3.0 
    @vue/babel-sugar-functional-vue:  1.2.2 
    @vue/babel-sugar-inject-h:  1.2.2 
    @vue/babel-sugar-v-model:  1.3.0 
    @vue/babel-sugar-v-on:  1.3.0 
    @vue/cli-overlay:  5.0.8 
    @vue/cli-plugin-babel: ~5.0.8 => 5.0.8 
    @vue/cli-plugin-router:  5.0.8 
    @vue/cli-plugin-vuex:  5.0.8 
    @vue/cli-service: ~5.0.8 => 5.0.8 
    @vue/cli-shared-utils:  5.0.8 
    @vue/compiler-core:  3.2.37 
    @vue/compiler-dom:  3.2.37 
    @vue/compiler-sfc:  3.2.37 
    @vue/compiler-ssr:  3.2.37 
    @vue/component-compiler-utils:  3.3.0 
    @vue/reactivity:  3.2.37 
    @vue/reactivity-transform:  3.2.37 
    @vue/runtime-core:  3.2.37 
    @vue/runtime-dom:  3.2.37 
    @vue/server-renderer:  3.2.37 
    @vue/shared:  3.2.37 
    @vue/web-component-wrapper:  1.3.0 
    vue: ^3.2.37 => 3.2.37 
    vue-hot-reload-api:  2.3.4 
    vue-loader:  17.0.0 (15.10.0)
    vue-style-loader:  4.1.3 
    vue-template-es2015-compiler:  1.9.1 
  npmGlobalPackages:
    @vue/cli: 5.0.8

Steps to reproduce

  1. In vue.config.js add the following:

    module.exports = defineConfig({
    css: {
    extract: false,
    },
    });
  2. In postcss.config.js add the following:

    module.exports = {
    plugins: {
    'postcss-prefix-selector': {
      prefix: 'THE-PREFIX',
    },
    'autoprefixer': {},
    },
    }

    I've installed postcss-prefix-selector, but the issue is about postcss plugins in general.

  3. Build the project

  4. In the resulting dist/js/app.xxxxx.js you will see that the postcss plugins have run twice on the same CSS content.

For me I see the following:

Input:

::placeholder {
  color: gray;
}

Output:

THE-PREFIX ::-moz-placeholder,THE-PREFIX THE-PREFIX ::-moz-placeholder{color:gray}THE-PREFIX THE-PREFIX ::placeholder{color:gray}

Also, in the configuration for postcss-prefix-selector you can provide a transform function, where if you put a console.log, you will see that it is run twice on the same file and prefix.

What is expected?

PostCSS plugins are only run once.

What is actually happening?

PostCSS plugins are run two times on the same CSS content.

MartinManev commented 1 year ago

postcss-prefix-selector might be the one to blame. I'll do some more testing.

MartinManev commented 1 year ago

I tested with a custom PostCSS plugin that only prints a message in the console and the issue is still present. I saw that when css.extract = true, then Vue CLI uses MiniCssExtractPlugin and it is working as expected. But when css.extract = false it is doing something else - not sure what exactly. I'll take look at it again tomorrow.

MartinManev commented 1 year ago

All PostCSS plugins run twice when css.extract = false. What's different about autoprefixer is that it has some mechanism to avoid adding redundant selectors, but it also runs twice. I am having trouble debugging the Vue CLI itself - there are multiple dependency incompatibilities when I try to install. Could any of the maintainers take a look at this problem?