Webpack hooks to dynamically alter SCSS imports

Viewed 447

Question

EDIT: Custom Importers for sass-loader seem the most likely?

Is there a webpack pipeline I can hook into, that will allow me to programatically update an scss import from:

@import 'bootstrap/scss/function';

To

@import '~bootstrap/scss/function';

I've been attempting with the resolve pipeline to no avail:

plugins: [
    {
        apply: resolver => {
            resolver.hooks.parsedResolve.tap('resolve', (request, resolveContext, callback) => {
                webpackUtils.handleLegacyImports(request, resolveContext, resolver, callback);
            });
        },
    },
],

But also was wondering whether I can hook into sass-loader as well, documentation is slim.

Context

So this is an unfortunate work scenario, which has me importing SCSS files from a git submodule so that I can make overrides, it is structured as such:

-Project
--MyApp
---scss
----global.scss
--SubmoduleApp
---scss
----global.scss

The issue is that the Submodule is poorly designed, and doesn't use Tilde's on any of the imports, instead it has a custom build script to figure out the imports. As expected webpack freaks out when it reached them

ERROR in ./MyApp/scss/global.scss
Module build failed ...
SassError: File to import not found or unreadable: bootstrap/scss/functions.
        on line 1 of ...
>> @import "bootstrap/scss/functions";

Adding a tilde in the Submodule fixes the problem, but is not a solution because the submodule is third party and unable to be updated. This is why I need to hook in before attempting the import to add a tilde or something else to make this work... Any thoughts would be appreciated!

1 Answers

Custom importer on Sass-Loader was the answer after all!

Here's an quick example of handling the edge case:

{
    loader: 'sass-loader',
    options: {
        sourceMap: process.env.NODE_ENV !== 'production',
        sassOptions: {
            importer: url => {
                if (url.startsWith('bootstrap/')) {
                    return {
                        file: path.resolve(`./node_modules/${url}`),
                    };
                }
                return null;
            },
        },
    },
},
Related