webpack-encore icon indicating copy to clipboard operation
webpack-encore copied to clipboard

Import global scss rules in vue components

Open jwillp opened this issue 5 years ago • 7 comments
trafficstars

Hi all, How can one import scss files globally for vue components: Similar to how it is done with vue-cli:

// vue.config.js
const path = require('path')

module.exports = {
    pluginOptions: {
        'style-resources-loader': {
            preProcessor: 'scss',
            patterns: [
                path.resolve(__dirname, './assets/css/_variables.scss'),
                path.resolve(__dirname, './assets/css/_responsive-utilities.mixins.scss'),
            ]
        }
    },
}

I looked everywhere I could, but did not manage to find a solution.

jwillp avatar Jul 17 '20 16:07 jwillp

You can use sass-loader's additionalData option.

This should work:

Encore.enableSassLoader(options => {
  options.additionalData = `
@import "${path.resolve(__dirname, './assets/css/_variables.scss')}";
@import "${path.resolve(__dirname, './assets/css/_responsive-utilities.mixins.scss')}";
`
});

Kocal avatar Jul 17 '20 17:07 Kocal

Thank you for your answer, unfortunately it does not work. Vue Components complain about the variables not being defined

jwillp avatar Jul 17 '20 18:07 jwillp

Surely because vue-style-loader is not used, see https://vue-loader.vuejs.org/guide/pre-processors.html#sharing-global-variables.

Encore use style-loader and not vue-style-loader, when CSS extraction is disabled, see https://github.com/symfony/webpack-encore/blob/a7d76ee0661ddeac35e241e1f48962dbf6123906/lib/loaders/css-extract.js#L32.

You can try to play with Encore.configureLoaderRule('css', option => {}) to use vue-style-loader instead, see https://symfony.com/doc/current/frontend/encore/advanced-config.html#having-the-full-control-on-loaders-rules and https://github.com/symfony/webpack-encore/blob/master/test/config-generator.js#L1169-L1370 for more information.

Kocal avatar Jul 17 '20 18:07 Kocal

Thank you again for this, however, I can't seem to wrap my head around what I am supposed to do. Given that I don't really know the internals of webpack-encore:

I tried the following:

    .configureLoaderRule('scss', (loaderRule) => {
        loaderRule.use = {
            loader: require.resolve('vue-style-loader'),
            options: {
                additionalData: `
                    @import "${path.resolve(__dirname, './assets/css/_variables.scss')}";
                    @import "${path.resolve(__dirname, './assets/css/_responsive-utilities.mixins.scss')}";
                `
            }
        }
    })

    .configureLoaderRule('css', (loaderRule) => {
        loaderRule.use = {
            loader: require.resolve('vue-style-loader'),
            options: {}
        }
    })

jwillp avatar Jul 17 '20 19:07 jwillp

I finally managed to do it using the sass-resources-loader with the following configuration:

    .configureLoaderRule('scss', (loaderRule) => {
        loaderRule.oneOf.forEach((rule) => {
            rule.use.push({
                loader: 'sass-resources-loader',
                options: {
                    // Provide path to the file with resources
                    // Or array of paths
                    resources: [
                        path.resolve(__dirname, './assets/css/_variables.scss'),
                        path.resolve(__dirname, './assets/css/_responsive-utilities.mixins.scss'),
                    ]
                },
            })
        })

However, I do think that an official configuration method could be a nice addition as this is, in my opinion, a pretty common use case when working with vue.js.

jwillp avatar Jul 18 '20 01:07 jwillp

I finally managed to do it using the sass-resources-loader with the following configuration:

    .configureLoaderRule('scss', (loaderRule) => {
        loaderRule.oneOf.forEach((rule) => {
            rule.use.push({
                loader: 'sass-resources-loader',
                options: {
                    // Provide path to the file with resources
                    // Or array of paths
                    resources: [
                        path.resolve(__dirname, './assets/css/_variables.scss'),
                        path.resolve(__dirname, './assets/css/_responsive-utilities.mixins.scss'),
                    ]
                },
            })
        })

However, I do think that an official configuration method could be a nice addition as this is, in my opinion, a pretty common use case when working with vue.js.

Does not work for me.

Default scss files - accept that shared variables But scss style in vue-component - not.

I need to customize vue-library https://github.com/JosephusPaye/Keen-UI/blob/master/Customization.md#customization But unable to it with configureLoaderRule

dimti avatar Sep 08 '20 13:09 dimti

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?

carsonbot avatar Jan 16 '25 12:01 carsonbot

Thank you for this issue. There has not been a lot of activity here for a while. Has this been resolved?

carsonbot avatar Jul 17 '25 12:07 carsonbot

Could I get a reply or should I close this?

carsonbot avatar Jul 31 '25 12:07 carsonbot

Hey,

I didn't hear anything so I'm going to close it. Feel free to comment if this is still relevant, I can always reopen!

carsonbot avatar Aug 14 '25 12:08 carsonbot