Home > OS >  Why Webpack doesn't need us to import 'Loaders' but 'Plugins' does?
Why Webpack doesn't need us to import 'Loaders' but 'Plugins' does?

Time:05-26

My question is why importing the Loaders in Webpack doesn't behave like the ways that Plugins do, and why Webpack design these two imports in different ways.

const CssLoader = require('css-loader')
...
use:[new CssLoader()]

CodePudding user response:

In short loaders are just function exported by modules that receive the source of a specific type of file and returns it to the next loader or Webpack compiler. And all those loader functions are called by Webpack loader-runner, So loader-runner needs a path of the exported function. || Most plugins allow configure behavior to initialize constructor is the best place. Plugins can be added without new keywords


Before anything what are the loader and plugins for Webpack?

Webpack can understand JavaScript and JSON files only. To handle files other than that loaders can be used. As Webpack treats everything (JavaScript, images, CSS, HTML...) as a module, the loader transform modules. babel-loader transforms ES6 to browser-compatible JavaScript. There are other loaders to with specific job. Like file-loader, URL-loader, CSS-loader, style-loader, and many more.

You can create your loader in just simple steps

process-loader.js

module.exports  =  function  dummyLoader(source) {
    console.log(source);
    return  source;
}

And add it modules.rule to handle specific files.

module: {
    rules: [
        {
            test: /\.js$/,
            use: ['babel-loader', path.resolve(__dirname, './process-loader')]
        }
    ]
}

Here each .js file has to go through loaders. First, it will go through the babel-loader. babel-loader will transpile input source and return processed code. That processed code will be passed to the process-loader (exported module). It may process the source and return or return as it.

Loader is nothing but a function exported by JavaScript Module. And this function is called by Webpack loader-runner. Webpack loader-runner knows how to find loader from path, either it will look into node modules or other local file path. It receives source code as a parameter and returned it to the Webpack loader-runner. That returned code is passed down to the next loader. If you remove return source from process-loader.js you will end up with a white screen as the source is not returned and null passed to the next loader. The source from the last loader in the chain is passed down to the Webpack compiler for bundling. And due to this sequence of the loader is also essential.

In chained loaders Webpack calls loaders in reverse order i.e. from right to left.

For chained loader below

module: {
    rules: [
        {
            test: /\.s[ac]ss$/i,
            use: ["style-loader", "css-loader", "sass-loader",],
        }
    ]
}

can be visualised like,

enter image description here

Why and how reverse, check Webpack Pitching Loaders

There is much more interesting about loaders you can find here


Plugins are nothing but Javascript objects that expose apply method. Plugin contributes to Compiler and Compilation. Plugins can hook into various life cycle phases of Webpack. The plugin can manage output with compiler hooks like beforeRun, run, watchRun, compile and many more or compilation hooks like optimizeAssets, processAssets.

The standard way of creating a plugin

const PLUGIN_NAME  =  'DemoPlugin';
class DemoPlugin {
    constructor(options) {
        this.options =  options;
    }
    apply(compiler) {
    }
}
module.exports  =  DemoPlugin;

And add to webpack. plugins

const DemoPlugin = require('./DemoPlugin');
...
plugins:[
    new DemoPlugin({/*some config*/})
]

If you want to avoid new keywords, you can simply export the object with an apply method

module.exports  = {
    apply(compiler) {
        compiler.hooks.watchRun.tap('WatchRun', (comp) => {
            console.log('           
  • Related