Is there a way to make a sass file universally accessible without having to import it into every file and causing an increase in bundle size?

Question
How can I efficiently import variables.scss globally without the need to duplicate them in every file and reference them in my build instead of importing?

Setup
I am using Vue2 with laravel-mix, where I have imported index.scss in my main.js

variables.scss

$--test: #ff0000;

index.scss

@import 'variables';

.dashboard-title {
    color: $--test;
}

The title is successfully colored red. However, attempting the same inside a component does not work:

<style scoped lang="scss">
    .dashboard-title {
       color: $--test;
    }
</style>

Even though index.scss is global, the same behavior is not seen with variables.scss when imported in a global index.scss.

To resolve this issue, importing the variables file in each component resolves the error but results in duplicating the entire content of variables.scss every time it is imported into a Vue component.

Analyzing my bundle using a webpack bundle analyzer revealed an increase in bundle size due to multiple imports of the variables file: webpack bundle analysis image (sections marked in blue show increased size as variables file is imported)

There is a potential 20% reduction in bundle size if the content duplication issue is addressed...


What I've tried:
https://css-tricks.com/how-to-import-a-sass-file-into-every-vue-component-in-an-app/ (unable to adapt for laravel-mix configuration)
Attempted to use purgeCss resulting in style issues but reducing bundle size by 50%

Added to the webpack.mix.js:

mix.webpackConfig({
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    {
                        loader:  'sass-loader',
                        options: {
                            //this might be "data" or "prependData" depening on your version
                            additionalData: `@import "./resources/js/styles/variables.scss";`
                        }
                    }
                ]
            }
        ]
    }
})

This approach makes the variables global but still duplicates them for every vue component, regardless of usage.

Edit: Issue arises when the imported file is large. In my case, the imported file included a theme scss file which caused duplication everywhere the variables were needed.
Resolved by defining custom variables in a separate file and utilizing them in an "overwriting-variables" file like:

custom-variables.scss
$red: #ff0000;

overwriting-variables.scss

import 'theme.scss'; 
import 'custom-variables';

$--theme-red: $red

Simply import custom-variables.scss instead of overwriting-variables.scss where necessary in vue components. This mitigates bloating, yet the issue persists with multiple instances of custom-variables.scss in the project, albeit being small so far. Seeking alternative solutions!

Answer №1

When you include all .scss files in your index.scss, all variables should function properly. Give this method a try within your vue.config file:

  css: {
        loaderOptions: {
            // The `sass` option typically applies to both syntaxes by default
            // Since `scss` syntax is processed by sass-loader internally as well
            // However, when setting the `data` option
            // `scss` syntax requires a semicolon at the end of each statement, while `sass` syntax doesn't
            // In such scenarios, we can specifically target the `scss` syntax using the `scss` option
            scss: {
                prependData: `@import "@/style/index.scss"`
            }
        }
    },

Answer №2

After some experimentation, I managed to make it work with laravel-mix in the following way:

mix.webpackConfig({
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    {
                        loader:  'sass-loader',
                        options: {
                            //Depending on your version, this could be "data" or "prependData"
                            additionalData: `@import "./resources/js/styles/variables.scss";`
                        }
                    }
                ]
            }
        ]
    }
})

However, I am still uncertain if this solution effectively prevents duplication.

Update: Unfortunately, this method does not prevent duplication. It actually enlarges the bundle size in every vue component. Consequently, my bundle is now 150% larger because the variables file is imported in each and every vue component, even when the variable isn't utilized.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to prevent the context menu from appearing when tapping on an image on a mobile phone?

When attempting to move an image on the screen with a touch event, a popup appears in Chrome when pressing and holding the image. This popup usually includes options to save the image. Is there a way to disable this popup so I can freely move the image w ...

What determines which code Nuxt3 will run on the server-side versus the client-side?

Looking to dive into the world of Nuxt3. As far as I know, it employs universal rendering, blending elements of CSR and SSR. But before embarking on this journey, a couple of queries are on my mind. How does Nuxt3 differentiate between client-side and s ...

Text remains constant until the mouse hovers over the image

Check out this Example Here is the HTML code: <ul class="img-list"> <li> <img src="http://s11.postimg.org/ynw9rnexf/Cetina_river.jpg" width="360px" height="280px" /> <span class="text-content"><span> Text To Dis ...

Changing the color of HTML text based on a variable in Vue JS can be achieved by altering the CSS styles dynamically

I have developed a website that shows values with a set threshold. I now want to change the color of the values when they exceed the threshold, but I am unsure of how to proceed. I want to display consultation.indicateurs.TRS in red when it exceeds the va ...

The jQuery scrollTop function seems to be malfunctioning following an ajax request

My ajax call is functioning properly, but I am experiencing an issue with the scrollTo plugin from JQuery. It is not positioning the content where I want it to be located below. //This function reveals the email body when a list item is clicked. jQue ...

Is there a way to incorporate a computed value into a table prop while working with Element UI?

In my frontend development, I am utilizing vuejs along with element ui. I am faced with the task of rendering a table that includes dates in unix format. To make these dates more user-friendly, I have incorporated moment.js to convert them into a readable ...

Unexpected behavior observed in component due to Vuex store

When attempting to access the store data in a component embedded directly in the HTML, you can use the following syntax: {{$store.state.notificationArea.cart.total;}} This method works properly. However, if trying to access the same data in the computed ...

Managing data in Vuex by updating it from a child component using $emit

I'm currently working on a Vue app that has the capability to randomize a title and subtitle or allow users to manually edit these values using a custom input component. The challenge I'm facing is updating the parent component and state to refle ...

increase the width of the side menu bar to accommodate more content on the Bootstrap

At the moment, the line that separates the content from the side menu stops at the side menu's content. However, the content is going to be longer than the side menu, causing the page to look uneven. I attempted to adjust the page-content d-flex but d ...

Issues with drawing on vue-signature-pad within a Vuetify dialog

I have encountered an issue when trying to use vue-signature-pad within my Vuetify UI. It works perfectly fine without the dialog, but as soon as I open a dialog and try to use the vue-signature-pad plugin, I am unable to draw on it. If anyone has any sug ...

Searching for a specific element using a CSS selector

Looking for a way to find an element using a CSS selector in Chrome, I followed these steps: Right-click on the object Select "inspect" Right-click on the highlighted area in Chrome developer tools Choose "copy" Click on "copy selector" This is the cod ...

Will asynchronous functions continue running when a route changes in a Vue.js application?

Just started using vuejs and I'm facing a challenge with data downloading within a Vue View. I need to run a function inside methods to download data from firestore, which involves large databases. My concern is: if I change the view (route), will the ...

An innovative approach to blurring or focusing a Vue.js component depending on the state of Vuex made possible

I'm encountering an issue with my Vue.js setup. Here's a snapshot of my current state: state: ()=>({ activeSide : "from", }), The goal is to have a component focused or blurred based on whether the activeSide property has the ...

Creating a new project in ASP Net Core Angular using Bootstrap 4 for the SideMenu layout instead of Bootstrap 3

I am currently working on developing a website using Angular6, where I aim to have a vertical navbar for large screens and a top navbar with dropdown functionality for mobile devices. While searching online, I came across several examples that seemed overl ...

The fusion of Vue.js and Git for seamless project build automation

When building my applications, I utilize vue.js along with vue-cli and webpack. During the development process, I run npm run dev to continuously watch my sources, compile everything, and reload the browser. For creating a production build, simply running ...

Switch the design and save it in the browser's cache

Exploring the possibility of having two themes, "dark" and "light," that toggle when a checkbox is clicked. To implement the theme change, I used the following JavaScript code: document.documentElement.setAttribute('data-theme', 'dark&apos ...

Alias route for `src` in Ionic 3

I have set up a custom webpack configuration for Ionic 3 in order to use src as a path alias (meaning I can import from src/module/file): resolve: { alias: { 'src': path.resolve('./src') } } However, after updating to Ionic ap ...

Adjust the top position of a div element at regular intervals

How can I make the top position of an absolutely positioned div with children change every x seconds using jQuery? I tried using setInterval but it only changes once. Here is my code: .com_prices { width: 100%; height: 100%; overflow: hidden; back ...

Error: TweenLite has not been recognized

/justincavery/pen/mPJadb - this is a link to CodePen After copying the code from CodePen and running it, I encountered an error: "Uncaught ReferenceError: TweenLite is not defined". The image only draws once and there is no animation unless I press "F5 ...

I am looking to split an array into smaller subarrays, each containing 5 elements, and assign a distinct class to the elements within each subarray. How can I

I have a group of "n" "li" elements that I would like to split into "x" subsets using jQuery. Each subset should contain 5 "li" elements, and I also want to assign a different class to each subset. <ul> <li>text1</li> <li>text2&l ...