6

I'm currently trying to use Webpack to bundle all my files and I don't know how to proceed when dealing with multiple folders and .scss files.

I used to use grunt to do these tasks, and this is an example of my folder structure:

functions
    - _mixin.scss
    - _function.scss
    - [...]
variables
    - _colors.scss
    - _typo.scss
    - [...]
ui
    - _button.scss
    - _grid.scss
    - [...]
view
    - _home.scss
    - _about.scss
    - [...]

With Grunt I would run a task to generate a file called main.scss containing all the @import, for example:

@import 'function/_mixin.scss';
@import 'function/_function.scss';
@import 'variables/_colors.scss';
@import 'variables/_typo.scss';
[...]

Currently I'm specifying an import inside my .js file (used in conjunction with extract-text-webpack-plugin) to define the main.scss file, but each new import, or old one, needs to be added/removed manually. Is there a way to automate this task with WebPack?

celsomtrindade
  • 4,501
  • 18
  • 61
  • 116
  • if you're importing scss files into the component js, the resulting css will be required on demand by the user (i.e. via loaders). IF you want to compile the scss as one file without importing them as components into webpack, then remove the `@import scss` statements and compile them separately via npm scripts or otherwise (grunt/node-sass etc) – Denis Tsoi Apr 08 '17 at 14:38
  • @DenisTsoi I'm just importing the compiled css. What I meant to say is, for example, if I create a new file inside the folder `ui`, I need to manually add `@import 'ui/newfile'`; on the main.scss file. I used to do it automatically using `grunt sass-compile-imports`. – celsomtrindade Apr 08 '17 at 14:42
  • hmmm - i suppose that's a bit non-common practice (since it's assuming your workflow is ensuring styles are tied to the component js/html dependencies) - therefore adding all partials like that automatically might not be commonly supported. there's nothing stopping you from say, using grunt to auto compile the scss and require that `main.scss` into the entry file. – Denis Tsoi Apr 08 '17 at 14:50
  • you could use globbing and try that (there's also a node-sass-globbing package) https://www.npmjs.com/package/node-sass-globbing – Denis Tsoi Apr 08 '17 at 14:53
  • https://www.npmjs.com/package/import-glob-loader!!! - found it – Denis Tsoi Apr 08 '17 at 14:53
  • @DenisTsoi Nice! That's it! Would you mind turning it into an answer? So i can accept it? But anyway, really thanks for your help! – celsomtrindade Apr 08 '17 at 14:56
  • will do - Good luck! – Denis Tsoi Apr 08 '17 at 14:58

2 Answers2

12

When webpack 3 or 4

Use node-sass-glob-importer

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const globImporter = require('node-sass-glob-importer');

    ...
    test: /\.(scss|sass)$/,
    use: [
      MiniCssExtractPlugin.loader,
      "css-loader",
      {
        loader: "sass-loader",
        options: {
          sassOptions: {
            importer: globImporter()
          }
        }
      }
    ]

Use this way.

// Import all files inside the `scss` directory and subdirectories.
@import 'scss/**/*.scss';
@import 'scss/component-*';
junho
  • 3,603
  • 3
  • 18
  • 25
  • Can you suggest instructions for using with Webpack 4? I see `unknown property 'importer'`. – Mark Dec 15 '20 at 13:40
  • 1
    I dug further and learned that passing it as `options { sassOptions: importer: globIOmporter() }` passes option validation, but still fails to resolve any glob imports. – Mark Dec 15 '20 at 14:15
  • doesn't work for me, webpack 4.46.0, I tried to modify this config: gist.github.com/jez500/4f4295778e386ddbc96c2377e3415fc3 – mevsme Jun 15 '21 at 11:24
7

Note - only works with webpack 2 (requires update for webpack 3^)

You could use the plugin import-glob-loader github / npm

It supports globbing with

@import "foo/**/*";

which outputs to

@import "foo/1.scss";
@import "foo/bar/2.scss";
@import "foo/bar/3.scss";
Denis Tsoi
  • 9,428
  • 8
  • 37
  • 56