0

I'm using webpack 3.10.0 in a React project started with create-react-app. I'm trying to adjust my Webpack configuration so that I can import scss files without relative paths.

For example @import ../../scss_variables/vars.scss works perfectly fine in myComponent.module.scss but I'd like to be able to simply use @import scss_variables/vars.scss. I thought the following configuration would do the trick but after many attempts I haven't been able to get the @import to work. I'm getting the following error:

Module build failed:
@import "scss_variables/vars.scss";
^
File to import not found or unreadable: scss_variables/vars.scss.
in /path/to/app/src/components/myComponent/myComponent.module.scss (line 1, column 1)

File Structure:

app
-- config
---- webpack.config.dev.js
---- paths.js
-- src
---- components
------ myComponent
-------- myComponent.jsx
-------- myComponent.module.scss
---- scss_variables
------ vars.scss

webpack.config.dev.js:

  const paths = require('./paths');

  {
      test: /\.module\.scss/,
      use: [
          require.resolve('style-loader'),
          {
              loader: require.resolve('css-loader'),
              options: {
                  importLoaders: 1,
                  modules: true,
                  localIdentName: '[name]__[local]__[hash:base64:5]',
                  includePaths: [paths.appSrc]
              },
          },
          'sass-loader'
      ]
  },
  {
      test: /^((?!\.module).)*\.scss/,
      use: [
          require.resolve('style-loader'),
          {
              loader: require.resolve('css-loader'),
              options: {
                  importLoaders: 1,
                  includePaths: [paths.appSrc]
              },
          },
          'sass-loader'
      ]
  },

paths.js:

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
module.exports = { appSrc: resolveApp('src') };
charleszardo
  • 179
  • 12

1 Answers1

0

Use Webpack's resolve.alias configuration property to define a shortcut location for importing.

module.exports = {
  //...
  resolve: {
    alias: {
      scss_variables: path.resolve(__dirname, '../scss_variables/')
    }
  }
};

Now @import ../../scss_variables/vars.scss can be written as @import scss_variables/vars.scss.


Edit

Use this in your config in place of what you have:

{
  test: /\.module\.scss/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        importLoaders: 1,
        modules: true,
        localIdentName: '[name]__[local]__[hash:base64:5]',
        includePaths: [paths.appSrc]
      },
    },
    'sass-loader'
  ]
},
{
  test: /(?<!\.module)\.scss$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        importLoaders: 1,
        includePaths: [paths.appSrc]
      },
    },
    'sass-loader'
  ]
}

It looks like the regex test you had for .scss files without the preceding .module part was incorrect.

Adam
  • 3,829
  • 1
  • 21
  • 31
  • Still getting the same `Module build failed` error. Any thoughts on what could be going on? NOTE: the file structure I had originally written out was slightly off. `scss_variables` lives under `src`. I've corrected it above. – charleszardo Sep 13 '18 at 18:19
  • I'm assuming you corrected the paths and it still didn't work? – Adam Sep 13 '18 at 18:21
  • It may be that your webpack.config.js is invalid. For your second `.scss` rule, what files are you trying to test for? Files ending in `.scss` but not `.module.scss`? – Adam Sep 13 '18 at 18:41
  • I believe that's what that means. This webpack config comes straight out of `create-react-app`. I'm not very well versed with webpack. Should `resolve.alias` work with scss files/sass-loader? All the examples in the documentation deal with JavaScript. – charleszardo Sep 13 '18 at 18:48
  • Yes, `resolve.alias` works with Sass. I updated my answer with more info. – Adam Sep 13 '18 at 18:58
  • Thanks @Adam, much appreciated. I'm guessing I can remove `includePaths: [paths.appSrc]` now since that was from my initial attempt. – charleszardo Sep 13 '18 at 19:29
  • Try removing all `options` from both rules. – Adam Sep 13 '18 at 19:36