0

I use Webpack to load SVG icons. Most icons have some CSS associated with it. I would like to keep styles for each icon in separate file. So it's needed some convenient way to include it in CSS bundle if icon is imported. For example

import arrowIcon from 'icons/arrow.svg'

must:

1) load 'icons/arrow.svg' using my SVG loader

2) load 'icons/arrow.svg.css' using my CSS loader

My attempts

I could use multi-loader for that, but I don't know how to modify resource path arrow.svg => arrow.css to pass it to CSS loader. I could use NormalModuleReplacementPlugin for that, but it seems to modify path for both loaders. Also I could write my own loader which modifies path and invokes CSS loader, but don't know how to properly execute loader inside loader

shameleo
  • 344
  • 2
  • 13

1 Answers1

1

This answer helped me to write a plugin

const CommonJsRequireDependency = require("webpack/lib/dependencies/CommonJsRequireDependency");
const fs = require('fs');
const path = require('path');

function LinkedModulePlugin(options) {
    this.options = options;
}

LinkedModulePlugin.prototype.apply = function(compiler) {
    compiler.hooks.compilation.tap('LinkedModulePlugin', compilation => {
        compilation.hooks.succeedModule.tap('LinkedModulePlugin', module => {
            const { resource } = module;
            const { test, linkedModule } = this.options;
            if (test instanceof RegExp && test.test(resource) ||
                typeof test === 'function' && test(resource)) {
                const linkedModulePath = linkedModule(resource);

                if (fs.existsSync(linkedModulePath)) {
                    const relPath = path.relative(module.context, linkedModulePath);
                    module.dependencies.push(new CommonJsRequireDependency('./' + relPath, null))
                }
            }
        });
    });
};

module.exports = LinkedModulePlugin;

Usage example:

// Webpack config
const LinkedModuleWebpackPlugin = require('./path/to/linked-module-webpack-plugin');

// ...

plugins: [
    new LinkedModuleWebpackPlugin({
        test: /\.svg$/,
        linkedModule: (resource) => resource + '.css'
    })
]

Anyway, It would be nice to be able to do it using loader.

shameleo
  • 344
  • 2
  • 13