Webpacker: Best Practices for overriding loader options

Created on 5 Sep 2017  路  5Comments  路  Source: rails/webpacker

I did this to override css-loader with new options. Is this the way it's meant to be done?

// config/webpack/environment.js
const { environment } = require('@rails/webpacker')

const myCssLoaderOptions = {
  modules: true,
  sourceMap: true,
  localIdentName: '[name]__[local]___[hash:base64:5]'
}
const CSSLoader = environment.loaders.get('style').use.find(function(el){
  return el.loader === 'css-loader'
})

CSSLoader.options = myCssLoaderOptions

module.exports = environment

Most helpful comment

@anithri Yes, for now 馃憤

Perhaps you wanna consider merging options first so you don't override existing options.

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

const myCssLoaderOptions = {
  modules: true,
  sourceMap: true,
  localIdentName: '[name]__[local]___[hash:base64:5]'
}

const CSSLoader = environment.loaders.get('style').use.find(el => el.loader === 'css-loader')

CSSLoader.options = merge(CSSLoader.options, myCssLoaderOptions)

module.exports = environment

//cc @javan ^^

All 5 comments

@anithri Yes, for now 馃憤

Perhaps you wanna consider merging options first so you don't override existing options.

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

const myCssLoaderOptions = {
  modules: true,
  sourceMap: true,
  localIdentName: '[name]__[local]___[hash:base64:5]'
}

const CSSLoader = environment.loaders.get('style').use.find(el => el.loader === 'css-loader')

CSSLoader.options = merge(CSSLoader.options, myCssLoaderOptions)

module.exports = environment

//cc @javan ^^

I can see why you'd question updating this loader's options since it requires scanning the use array. The rest of the loaders don't have as much nested configuration.

I overrided SCSS Modules like mentioned above. But it not works. My class looks like https://prnt.sc/jcbnke I use react on rails and webpacker.

@AntonBerez I ran into this issue as well.. in the end I set it up like this:

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

let sassLoader = environment.loaders.get('moduleSass');
let index = environment.loaders.get('moduleSass').use.findIndex(el => el.loader === 'css-loader');

sassLoader.use[index].options = {
  modules: true,
  sourceMap: true,
  localIdentName: '[name]__[local]___[hash:base64:5]'
};

module.exports = environment;

Notice how I used environment.loaders.get('moduleSass'). I think this is needed because this is the loader that generates the class name (although it probably depends on whether you use style.css, style.scss, style.module.scss, .. and so on. (In my case it was the latter).

let keys = ['css', 'sass', 'moduleCss','moduleSass']

keys.map(function(key) {
  let thing = environment.loaders.get(key)
  let index = environment.loaders.get(key).use.findIndex(el => el.loader === 'postcss-loader');

  thing.use[index].options = {
    plugins: (loader) => [
      require('postcss-cssnext')({
        features: {
          customProperties: {
            warnings: false
          }
        }
      })
    ],
    modules: true,
    sourceMap: true,
    localIdentName: '[name]__[local]___[hash:base64:5]',
  }

})

I'm brute forcing here because neither moduleSass or moduleCss worked, and by why should I spend time isolating the "right" one? (they all use postcss-loader). 馃槶

This is mainly because bulma + postcss-cssnext don't play nice.

By the way, why can't webpacker use webpack.config.js ?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pioz picture pioz  路  3Comments

suhomlineugene picture suhomlineugene  路  3Comments

towry picture towry  路  3Comments

iChip picture iChip  路  3Comments

inopinatus picture inopinatus  路  3Comments