9

I'm using a Rails 5.2 app and have an application.scss file filled with individual imports

@import '../stylesheets/pages/home';
@import '../stylesheets/pages/product_details';
@import '../stylesheets/pages/cart';
@import '../stylesheets/pages/downloads';

This is laborious and error prone so I'd prefer to use globbing

@import '../stylesheets/components/*';

However, this fails. When I run bin/webpack I get the following error:

ERROR in ./app/webpacker/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/lib/loader.js??ref--7-3!./app/webpacker/stylesheets/application.scss)
Module build failed (from ./node_modules/sass-loader/lib/loader.js):

@import '../stylesheets/components/*';
^
File to import not found or unreadable: ../stylesheets/components/*.
ErvalhouS
  • 4,178
  • 1
  • 22
  • 38
Jack Kinsella
  • 4,491
  • 3
  • 38
  • 56
  • 1
    Have you found a solution yet? – Daniel Apr 04 '19 at 14:16
  • 1
    I ended up giving up and just having 25 lines of imports. Perhaps one way to do this automatically would be to change the `application.scss` file to `application.scss.erb` and then then use ruby to loop. – Jack Kinsella Apr 06 '19 at 11:48
  • Thanks for the update. Unfortunately I didn't find a solution either and also went with multiple lines of imports... Seems there is no other way then to embrace "best practices"... welp – Daniel Apr 09 '19 at 18:09

2 Answers2

5

As mentioned by ErvalhouS, you have to use an importer that will enable this functionality.

Install the importer:

yarn add node-sass-glob-importer

Then configure the sass loader (installed by default with Webpacker) to use this when parsing css files:

const globCssImporter = require('node-sass-glob-importer');

environment.loaders.get('sass')
  .use
  .find(item => item.loader === 'sass-loader')
  .options
  .sassOptions = {importer: globCssImporter()};

Then you can import directories in your application.scss file

@import '../stylesheets/components/**/*.scss';

If there are issues with load ordering, then loading the required files first in the correct ordering within application.scss should resolve that

@import '../stylesheets/components/defaults.scss'
@import '../stylesheets/components/**/*.scss';
Leepoff
  • 134
  • 2
  • 6
2

Unless you are using some plugin to enable glob importing, SASS or SCSS does not support glob importing.

In SASS or SCSS import order matters, you need to be explicit about it or end up with undefined variables or mixins.

There is no built-in feature to do what you want. You either transform your file into .erb and loop or do some JS magic to import all files.

ErvalhouS
  • 4,178
  • 1
  • 22
  • 38