summer.breeze
summer.breeze

Reputation: 47

Rails 6.1 sass-loader without asset pipeline (webpacker)

Auto-including all nested SCSS files with Rails 6.1 and sass-loader

With Rails 6.0.3.4 it was possible to use Sass-loader to glob all SCSS files without including each and every one manually.

Problem - syntax v7

This fails in Rails 6.1 with the following webpacker error (with webpacker config, see below, .options = { importer: globImporter() }; // syntax for sass-loader v7)

ERROR in ./app/javascript/packs/application.scss (./node_modules/css-loader/dist/cjs.js??ref--6-1!./node_modules/postcss-loader/src??ref--6-2!./node_modules/sass-loader/dist/cjs.js??ref--6-3!./app/javascript/packs/application.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'importer'. These properties are valid:
   object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }
    at validate (/workspace/node_modules/sass-loader/node_modules/schema-utils/dist/validate.js:98:11)
    at Object.loader (/workspace/node_modules/sass-loader/dist/index.js:36:28)

Problem - syntax v8

If I change the config to sass-loader v8 syntax (.sassOptions = { importer: globImporter() };), I get different error:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.module.rules[2].use[3] has an unknown property 'sassOptions'. These properties are valid:
   object { ident?, loader?, options?, query? }

Question

How to configure it with Rails 6.1 and sass-loader v8?

Original pre 6.1 working config:

  1. yarn add node-sass-glob-importer, Rails 6.1 uses [email protected]
  2. Adjust webpack configuration to pass loader options:
# config/webpack/environment.js

const { environment } = require('@rails/webpacker')

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

environment
    .loaders
    .get('sass')
    .use
    .find(item => item.loader === 'sass-loader')
    .options = { importer: globImporter() }; // syntax for sass-loader v7
    // .sassOptions = { importer: globImporter() }; // for v8

module.exports = environment
  1. Then in
// app/javascript/packs/application.scss
import './application.scss';
  1. and finally in
// app/javascript/packs/application.scss
@import '../stylesheets/**/*.scss';

All nested SCSS stylesheets under app/javascript/packs would then be automatically globbed.

Upvotes: 0

Views: 2533

Answers (1)

summer.breeze
summer.breeze

Reputation: 47

Found a solution. For Rails 6.1 you need the following environment.js webpacker configuration:

const { environment } = require('@rails/webpacker')

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

environment
    .loaders
    .get('sass')
    .use
    .find(item => item.loader === 'sass-loader')
    .options = { sassOptions: { importer: globImporter() } }; // <-- this!

module.exports = environment

Upvotes: 2

Related Questions