node-sass-magic-importer icon indicating copy to clipboard operation
node-sass-magic-importer copied to clipboard

Idea: Chain the modules

Open thomaswhite opened this issue 6 years ago • 6 comments

I am using these modules from the command line. I think it will be very useful to be able to chain some of the modules. An obvious choice to me is to combine node-sass-glob-importer and node-sass-once-importer. Thanks for your great work.

thomaswhite avatar Mar 12 '18 15:03 thomaswhite

Hey @thomaswhite,

you can use the node-sass-magic-importer package, to have all importers combined.

Furthermore, node-sass makes it possible to provide an array to the importer option. But I've not tested this extensively.

Thanks for your kind words :)

maoberlehner avatar Mar 12 '18 17:03 maoberlehner

Hi @maoberlehner. I'm using this from webpack and chaining seems to not work.

@import "~mypackage/es/scss/**/*.scss";
div{
  background: $red; //$red is defined in my package
}

I'm trying to get that working by chaining the package importer and the glob importer like this

    {
      loader: 'sass-loader',
      options: {
        sourceMaps,
        includePaths: [
          path.resolve(process.cwd(), './src'),
          // i was also thinking i could remove these extra 2 node module include paths with the package importer
          path.resolve(process.cwd(), './node_modules/'),
          path.resolve(process.cwd(), '../../node_modules/')
        ],
        importer: [globImporter(), packageImporter()] //i tried flipping them too
      }
    }

The 2 weird things are that the import itself does not error out (while it does without any importers). But it just says Undefined variable: "$red".

The other weird thing is that if i use the magic importer instead of these 2 individual ones, it does work. I was trying to avoid adding extra importers that I wasn't planning on using though. Any ideas why that might break? None of the other importers seem relevant for this so i figured I could use just those two.

Thanks!

bdwain avatar May 02 '18 00:05 bdwain

Hey @bdwain,

according to the documentation, using multiple importer functions, works differently than one would hope.

importer can be an array of functions, which will be called by LibSass in the order of their occurrence in array. This helps user specify special importer for particular kind of path (filesystem, http). If an importer does not want to handle a particular path, it should return null.

The first importer, which handles the import (not returning null) "wins". This means one import is always only handled by one importer function. So in your example, the import @import "~mypackage/es/scss/**/*.scss"; is already handled by the globImporter which means, that the packageImporter is ignored by node-sass. I don't know why you don't get an error but I assume because webpack can handle ~ paths itself.

In your case, wanting to use both, the globImporter and the packageImporter, I see no real drawback in using node-sass-magic-importer. The performance overhead of using the magic importer is very, very minor (not noticeable / measurable) if you're not using the filter functionality.

maoberlehner avatar May 02 '18 06:05 maoberlehner

Ah I see. That makes sense. Though I’m curious why I even need the package importer functionality at all. With the includepaths I specified I should not need it right? And just the glob importer should work. I tried that though and it didn’t work.

I’ll probably use the whole Magic importer, but I do think it’d be nice to somehow chain only the ones you want if possible. Either with some helper to chain individual ones into one or maybe An option on the magic importer to enable/disable individual features.

bdwain avatar May 02 '18 09:05 bdwain

webpack is able to resolve paths starting with ~, but it can't deal with glob paths. The glob importer can handle glob paths but not paths starting with ~.

So if you have only webpack and the glob importer activated it goes something like this:

  • webpack sees the ~ import path, but can't resolve it because of the glob pattern.
  • The glob importer sees the glob pattern, but can't resolve it because it can't handle ~ paths.

They don't work together in the sense of complementing each other. What "should" happen tough, is that an error is thrown. I'm not sure why this doesn't happen.

I think the suggested chaining feature is a great idea and I'll think about implementing it in the future. I'm also accepting pull requests if somebody wants to help out :)

maoberlehner avatar May 02 '18 10:05 maoberlehner

Sweet! I’ll look into a PR. Thanks!

bdwain avatar May 02 '18 14:05 bdwain