vuejs / vue-cli

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

vue.config.js: SCSS only works if vue component contains a non-empty style section. #5188

Open acarlstein opened 4 years ago

acarlstein commented 4 years ago

Version

4.1.1

Environment info

  System:
    OS: Windows 10 10.0.17763
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
  Binaries:
    Node: 12.14.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: 44.17763.831.0
  npmPackages:
    @fortawesome/vue-fontawesome: ^0.1.9 => 0.1.9
    @vue/babel-helper-vue-jsx-merge-props:  1.0.0
    @vue/babel-plugin-transform-vue-jsx:  1.1.2
    @vue/babel-preset-app:  4.1.2
    @vue/babel-preset-jsx:  1.1.2
    @vue/babel-sugar-functional-vue:  1.1.2
    @vue/babel-sugar-inject-h:  1.1.2
    @vue/babel-sugar-v-model:  1.1.2
    @vue/babel-sugar-v-on:  1.1.2
    @vue/cli-overlay:  4.1.2
    @vue/cli-plugin-babel: ^4.1.0 => 4.1.2
    @vue/cli-plugin-eslint: ^4.1.0 => 4.1.2
    @vue/cli-plugin-router:  4.1.2
    @vue/cli-plugin-unit-mocha: ^4.1.2 => 4.1.2
    @vue/cli-plugin-vuex:  4.1.2
    @vue/cli-service: ^4.1.0 => 4.1.2
    @vue/cli-shared-utils:  4.1.2
    @vue/component-compiler-utils:  3.1.1
    @vue/preload-webpack-plugin:  1.1.1
    @vue/test-utils: ^1.0.0-beta.30 => 1.0.0-beta.30
    @vue/web-component-wrapper:  1.2.0
    eslint-plugin-vue: ^6.1.2 => 6.1.2
    eslint-plugin-vue-scoped-css: ^0.3.4 => 0.3.4
    vue: ^2.6.10 => 2.6.11
    vue-cli-plugin-vuetify: ^2.0.3 => 2.0.3
    vue-cli-webpack:  1.0.0
    vue-eslint-parser:  7.0.0
    vue-fontawesome: 0.0.2 => 0.0.2
    vue-hot-reload-api:  2.3.4
    vue-loader:  15.8.3
    vue-router: ^3.1.3 => 3.1.3
    vue-style-loader:  4.1.2
    vue-template-compiler: ^2.6.10 => 2.6.11
    vue-template-es2015-compiler:  1.9.1
    vuetify: ^2.2.3 => 2.2.3
    vuetify-loader: ^1.3.0 => 1.4.3
    vuex: ^3.1.2 => 3.1.2
    vuex-persistedstate: ^2.7.1 => 2.7.1
  npmGlobalPackages:
    @vue/cli: Not Found

Steps to reproduce

Setup your vue.config.js to load the css:

'use strict'

module.exports = {
  transpileDependencies: [
    'vuetify'
  ],
  css: {
    loaderOptions: {
      scss: {
        prependData: '@import "@/scss/app.scss";'
      }
    }
  }
}

What is expected?

You would expect that the app.scss SCSS file would be loaded in every vue component, always.

What is actually happening?

The app.scss SCSS file is only loaded into the component if and only if the component has a non-empty style tag as shown below:

<style lang="scss" scoped>
 /* Cannot have an empty style scoped else app.scss is not imported */
</style>

If the component doesn't have this non-empty style tag, then the SCSS is not loaded.


When over the documentation and search online but I couldn't find a solution to this. While the problem is not critical, it would be nice to have an option that guarantee that the SCSS file would be loaded to every component regardless if the component has or not a non-empty style tag.

Thank you for you time.

LinusBorg commented 4 years ago

My question would be: Why?

  1. If your app.scss only contains variables and mixins, its not necessary to include it as there's not scss that uses these variables and mixins.
  2. If your app.scss includes actual (s)css that results in markup, you are duplicating styles across each and every one of your components, wether they actually need or use them nor not - leading to a possibly very, very, very large css file with loads of duplicate and unused styles.

So assuming you're trying to do (2.), my recommendation would be: don't.

and as a sidenote, even though from your perspective the problem originates with a Vue CLI config option, the part responsible for this is vue-loader & scss-loader, not the CLI itself.

acarlstein commented 4 years ago

My question would be: Why?

1. If your app.scss only contains variables and mixins, its not necessary to include it as there's not scss that uses these variables and mixins.

2. If your app.scss includes actual (s)css that results in markup, you are duplicating styles across each and every one of your components, wether they actually need or use them nor not - leading to a possibly **very, very, very** large css file with loads of duplicate and unused styles.

So assuming you're trying to do (2.), my recommendation would be: don't.

and as a sidenote, even though from your perspective the problem originates with a Vue CLI config option, the part responsible for this is vue-loader & scss-loader, not the CLI itself.

@LinusBorg, allow me to explain. At the moment I reported this issue, we were dealing with three things. First, we needed to break down the project into small Vue components. Second, we needed to ensure to follow a theme which was provided to use as multiple SCSS files. Third, it was required that we could modify the theme of the whole site by just adjusting these variables and mixins hold in these SCSS files.

These variables go beyond doing the simple thing of setting a palette of colors. These variables would affect the padding, margin, animation and many other properties across the application. It would affect multiple component.

The concept provided to us was to build a Vue project were the UI/UX could be changed from the SCSS. In this way, they could give it to someone who doesn't care about learning Vue but has knowledge on SCSS.

Anyways, thanks for your time. I hope I managed to clarify any misunderstandings.

LinusBorg commented 4 years ago

thanks for the feedback, but I'm not sure I understand the bottom line: do you still have an issue? and if so, what is it?

These variables go beyond doing the simple thing of setting a palette of colors. These variables would affect the padding, margin, animation and many other properties across the application. It would affect multiple component.

I'm not sure I get that, either. is the SCSS that you import just logic, or does it end up creating actual CSS for the component?

As I explained If it's the latter, it should not be included globally

acarlstein commented 4 years ago

thanks for the feedback, but I'm not sure I understand the bottom line: do you still have an issue? and if so, what is it?

These variables go beyond doing the simple thing of setting a palette of colors. These variables would affect the padding, margin, animation and many other properties across the application. It would affect multiple component.

I'm not sure I get that, either. is the SCSS that you import just logic, or does it end up creating actual CSS for the component?

As I explained If it's the latter, it should not be included globally

@LinusBorg, I apologize if I couldn't be clear.

The idea behind is to have a main folder with SCSS files that shape the UI/UX of all VueJS components created with Vuetify. We managed to do this successfully; however, we notices that for a component to obtain the CSS from the SCSS, must have a style element scoped in the file, even if its empty.

I understand your point that it shouldn't be included globally; however, this was a corporate mandate. Those in charge to decide what the UI would look like don't want to learn VueJS. They want to setup SCSS files in a single folder.

Now, there it isn't a problem. We just leave an empty scoped style element in the file and it works. It would be a nice to have, not having to leave empty elements but I guess it is what it is.

Thank you for your time.