If you have any thoughts on my blog or articles and you want to let me know, you can either post a comment below(public) or tell me via this i_kkkp@163.com

Webpack Custom Loader/Plugin

Introduction

A loader is a node module exported as a function. This function is called when transforming resources in the loader. The given function will utilize the Loader API and can be accessed through the this context.

Here is an official link on loader usage and examples, including local development and testing of custom loaders.

Simple Usage of Webpack Loader

When a loader is used in a resource, it can only take one parameter - a string containing the content of the resource file.

Synchronous loaders can return a single value representing the transformed module.

Loaders can return one or two values. The first value is a string or buffer containing JavaScript code. The optional second value is a SourceMap, which is a JavaScript object.

Here’s a simple example of using a loader. It matches all JavaScript files and processes them using loader.js:

// webpack.config.js
const path = require('path');
module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: path.resolve('path/to/loader.js'),
            options: {
              /* ... */
            },
          },
        ],
      },
    ],
  },
};

From the above, we can understand how loaders are used. But this only scratches the surface. What does a specific loader look like?

For example, a simple loader could be like this:

module.exports = function (content) {
	// content is the source content string passed in
  return content
}

A loader is just a node module exposing a function that can only receive one parameter: a string containing the content of the resource file. The function’s return value is the processed content.

Creating a Custom Webpack Loader

Guidelines for Using Custom Loaders

When writing loaders, you should follow these guidelines. They are listed in order of importance, and some apply only to specific scenarios. Please read the detailed sections below for more information.

  • Keep it simple.
  • Use chaining.
  • Output should be modular.
  • Ensure it’s stateless.
  • Use loader utilities.
  • Record loader dependencies.
  • Resolve module dependencies.
  • Extract common code.
  • Avoid absolute paths.
  • Use peer dependencies.

Step 1: Create Project Directory and Files

First, create the following files in a folder within your webpack project directory:

  • src/loader/custom-loader.js: The source file for your custom loader.
  • src/index.js: JavaScript entry file for testing the custom loader.

Step 2: Write the Custom Loader

In the custom-loader.js file, write your custom loader code. This loader adds a comment at the top of each loaded JavaScript file.

// src/loader/custom-loader.js
module.exports = function(source) {
    // Add a custom comment at the top of the source code
    const updatedSource = `/** Custom Comment added by Custom Loader */\n${source}`;
    return updatedSource;
};

Step 3: Configure Webpack

Create a Webpack configuration file webpack.config.js in the project root directory. Use the custom loader you just created in the configuration file.

// webpack.config.js
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['custom-loader'], // Use the custom loader to process .js files
                exclude: /node_modules/,
            },
        ],
    },
};

This configuration achieves a simple functionality. Now let’s discuss how to test the local loader. There are two ways to do this: one is through Npm link for testing, a convenient method where you can create a symbolic link for local testing. Here is a link to npm-link. Another way is to configure the path directly in the project:

Single Loader Configuration

// webpack.config.js
{
  test: /\.js$/
  use: [
    {
      loader: path.resolve('path/to/custom-loader.js'),
      options: {/* ... */}
    }
  ]
}

Multiple Loader Configuration

You can also configure it using an array:

// webpack.config.js
resolveLoader: {
  // Look for loaders first in the node_modules directory; if not found, search in the loaders directory
  modules: [
    'node_modules',
    path.resolve(__dirname, 'custom-loader')
  ]
}

Step 4: Test the Custom Loader

In the index.js file, write some JavaScript code, for example:

// src/index.js
console.log('Hello, Webpack Loader!');

Step 5: Run Webpack Build

Run the following command to build your project:

npx webpack --config webpack.config.js

After the build is complete, you will find the generated bundle.js file in the dist folder. In this file, you can see JavaScript code with a custom comment added at the top.



## Simple Usage of Webpack Plugin

Plugins provide complete control over the webpack engine for third-party developers. By introducing custom behaviors into the webpack build process through stage-based build callbacks, developers can customize webpack's behavior.

Here's the simplest example:

```javascript
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: __dirname + '/dist',
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html', // Specify the HTML template file
            filename: 'index.html', // Generated HTML file name
        }),
        // You can add more plugins here
    ],
};

In this example, the HtmlWebpackPlugin is used. It generates a new HTML file based on the specified HTML template and automatically adds the bundled JavaScript file to the generated HTML file.

A basic webpack plugin consists of the following components:

  • A JavaScript named function or JavaScript class.

  • Define an apply method on the plugin function’s prototype. The apply method is called when webpack loads the plugin and is passed the compiler object.

  • Specify an event hook bound to webpack itself.

  • Process specific data from webpack’s internal instances.

  • Call the callback provided by webpack after the functionality is completed.

A plugin structure looks like this:

class HelloWorldPlugin {
  apply(compiler) {
    compiler.hooks.done.tap(
      'Hello World Plugin',
      (
        stats /* After binding the done hook, stats is passed as a parameter. */
      ) => {
        console.log('Hello World!');
      }
    );
  }
}

module.exports = HelloWorldPlugin;

Compiler and Compilation

The two most important resources in plugin development are the compiler and compilation objects. Plugin development revolves around hooks on these objects.

The compiler object is essentially bound to the entire webpack environment. It contains all the environment configurations, including options, loaders, and plugins. When webpack starts, this object is instantiated and it is globally unique. The parameters passed into the apply method are properties of this object.

The compilation object is created each time resources are built. It represents the current module resources, compiled generated resources, changed files, and tracked dependency status. It also provides many hooks.

Creating a Custom Webpack Plugin

Step 1: Create Project Directory and Files

First, create the following file in a folder within your webpack project directory:

  • src/plugins/CustomPlugin.js: Source file for your custom plugin.

Step 2: Write the Custom Plugin

In the CustomPlugin.js file, write a plugin that outputs a message when the webpack build process is completed.

// src/plugins/CustomPlugin.js
class CustomPlugin {
    apply(compiler) {
        compiler.hooks.done.tap('CustomPlugin', () => {
            console.log('CustomPlugin: Webpack build process is done!');
        });
    }
}

module.exports = CustomPlugin;

Step 3: Configure Webpack

In the configuration file, use the custom plugin you just created.

// webpack.config.js
const CustomPlugin = require('./src/plugins/CustomPlugin');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: __dirname + '/dist',
    },
    plugins: [
        new CustomPlugin(),
        // You can add more plugins here
    ],
};

Step 4: Run Webpack Build

Now, run the webpack build:

npx webpack --config webpack.config.js

Note: This article is a translated version of the original post. For the most accurate and up-to-date information, please refer to the original source.
```

The Role and Implementation of Vue.js Reactive System 301/302 Redirection

Comments