Ahmed Elkoussy
Ahmed Elkoussy

Reputation: 8588

How to export a global scss variables file to be imported to all scss files in Rails 6 webpacker

We are migrating from asset pipeline to webpacker & I tried to look for a definite answer for this for hours but can't find the "official way" to avail a global scss variables file to all the scss files in my application

So for example: I have a file colors.scss

$gray: #000000;
$red: #EF6461;

& I want these scss variables to be available for all my webpacker scss files, currently I have imported that file in my application.scss but I got errors in each scss that it can't find these variables, because as I understood webpacker will convert the scss files independently from each other, therefore not seeing the variables file I imported in application.scss

So how to handle this, making the global config file available to all scss in webpack (or webpacker) configuration itself, instead of importing the configuration file in every scss manually?

Note: importing the config file in each scss solves the issue but is very repeatitive & fragile

Update

I had different compile errors with different trials to solve this:

1- if I am keeping stylesheets in the webpacker packs folder, I get many errors from all scss files that they don't know the scss variable I am using (core of this question)

Errors like this:

ERROR in ./app/javascript/packs/stylesheets/components/blog-pages/_blog-index.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable: "$green".
        on line 16 of xxxxxxx/app/javascript/packs/stylesheets/components/blog-pages/_blog-index.scss
>>      color: $green;

   ---------^

2- if I keep the stylesheets beside the packs folder, I get other 1 by 1 error for the scss like this:

    ERROR in ./app/javascript/stylesheets/application.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: File to import not found or unreadable: font-awesome.
        on line 10 of /Users/ahmed/projects/project-hotelhero/app/javascript/stylesheets/application.scss
>> @import "font-awesome";

   ^

ERROR in ./app/javascript/stylesheets/application.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: File to import not found or unreadable: font-awesome.
        on line 10 of XXXXXXXX/app/javascript/stylesheets/application.scss
>> @import "font-awesome";

   ^

    at XXXXXXXX/node_modules/webpack/lib/NormalModule.js:316:20
    at XXXXXXXX/node_modules/loader-runner/lib/LoaderRunner.js:367:11
    at XXXXXXXX/node_modules/loader-runner/lib/LoaderRunner.js:233:18
    at context.callback (XXXXXXXX/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at Object.callback (XXXXXXXX/node_modules/sass-loader/dist/index.js:73:7)
    at Object.done [as callback] (XXXXXXXX/node_modules/neo-async/async.js:8067:18)
    at options.error (XXXXXXXX/node_modules/node-sass/lib/index.js:294:32)
Child mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--7-1!node_modules/postcss-loader/src/index.js??ref--7-2!node_modules/sass-loader/dist/cjs.js??ref--7-3!app/javascript/stylesheets/application.scss:

    ERROR in ./app/javascript/stylesheets/application.scss (./node_modules/css-loader/dist/cjs.js??ref--7-1!./node_modules/postcss-loader/src??ref--7-2!./node_modules/sass-loader/dist/cjs.js??ref--7-3!./app/javascript/stylesheets/application.scss)
    Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
    SassError: File to import not found or unreadable: font-awesome.
            on line 10 of XXXXXXXX/app/javascript/stylesheets/application.scss
    >> @import "font-awesome";

       ^

Upvotes: 3

Views: 3187

Answers (2)

dkniffin
dkniffin

Reputation: 1383

I found this question when googling during a sprockets -> webpacker migration and figured I'd share what I figured out.

I ended up using sass-resources-loader, and here's my config:

// config/webpack/environment.js

// ...

// sass/scss loader config
const sassLoader = environment.loaders.get('sass')
const sassLoaderConfig = sassLoader.use.find(function (element) {
  return element.loader === 'sass-loader'
})

const options = sassLoaderConfig.options
options.implementation = require('sass') // Use Dart-implementation of Sass (default is node-sass)

const sassResourceLoader = require('./loaders/sass-resource-loader')
environment.loaders.prepend('sass', sassResourceLoader)

//...
// config/webpack/loaders/sass-resource-loader.js

module.exports = {
  test: /\.scss$/,
  use: [
    'style-loader',
    'css-loader',
    'sass-loader',
    {
      loader: 'sass-resources-loader',
      options: {
        resources: [
          './app/javascript/styles/abstract/*.scss' // I've got all my "global" stuff in this one abstracts folder
        ]
      }
    }
  ]
}

Upvotes: 1

Ahmed Elkoussy
Ahmed Elkoussy

Reputation: 8588

So the main issue I had was putting the stylesheets in the wrong directory, putting stylesheets in /app/javascript/packs, this caused the root issue of webpack transpiling each scss file alone

The proper way is to put the stylesheets folder beside the packs folder, that is putting it in app/javascript/stylesheets & then organizing your scss in an application.scss file which will call your scss files in order correctly.

Upvotes: 1

Related Questions