webpackwebpack-4webpack-loader

How to add an image dependency from a custom loader in webpack?


I'm trying to create a loader which will just parse the content for this syntax:

{{ 'assets/someimage.png'|theme }}

every matches should be added as a webpack dependency from the root webpack directory without making any change in the final's content (this syntax is needed by the CMS template)

Here is where I've been:

let path = require('path'),
    themeRegex = /\{\{[\s?]*["|'|`](.*[\.[png|jpe?g|gif|ico])["|'|`][\s?]*\|[\s?]*theme[\s?]*\}\}/g;

module.exports = function (content, map, meta) {
    while ((themeFilterRequest = themeRegex.exec(content)) !== null) {
        var srcPath = path.join(this.rootContext, 'src')
        this.resolve(srcPath, './'+themeFilterRequest[1], (err, result) => {
            if (err) throw err
            console.log(result)
        })
    }

    return 'module.exports = [\n' +
        JSON.stringify(content) +
        '\n].join();'
};

but for now, the file isn't loaded, at the right place. It actually is created in my dist folder but only contain the text "assets/someimage.png" in the png extension file...

How to binary load the file?

Thanks!


Solution

  • When you require a file other then js, webpack applies a special loader per each file type (check your webpack config).

    From what you've described, file-loader got activated for the image import.

    You can use the webpack inline loaders syntax, and specify the exact loader that should handle your requires. !!file-loader!path/to/file.png (The !! at the beginning tells to webpack to run only specified loaders).

    const fs = require('fs');
    const path = require('path');
    
    module.exports = function (content, map, meta) {
        // parse your content to get a list of paths to files
        filePaths.forEach(fileToLoad => {
           const file = fs.readFileSync(fileToLoad);
           const fileName = path.basename(fileToLoad);
           this.emitFile(fileName, file)
        });
    
        return content;
    };