DEV Community

loading...
Cover image for Building your own Webpack Plugin

Building your own Webpack Plugin

jasmin profile image Jasmin Virdi Updated on ・3 min read

In the last post I discussed about the bundling and architecture of Webpack. In this post I would be focussing on building webpack plugins and how it can help you to solve your bundling problems. Webpack is built on plugin system which is used in webpack configurations and helps us in extending webpack's implementation which cannot be achieved by loaders and parsers.

I will be taking a simple example of a plugin which takes few arguments and prints them when webpack's lifecycle hooks are emitted. So let's begin building our own webpack plugin.

Steps

  • Create a project named my-first-webpack-plugin and install webpack in it.
mkdir my-first-webpack-plugin
npm init -y
npm install webpack webpack-cli --save-dev
Enter fullscreen mode Exit fullscreen mode
  • Create a file my-first-webpack-plugin.js and create a class defining your plugin properties. This will bind your plugin with the lifecycle hooks of webpack.
class MyFirstWebpackPlugin {
    constructor(options) {
        this.options = options;
    }
    apply(compiler) {
        console.log("My First webpack plugin");
    }
};

module.export = MyFirstWebpackPlugin;
Enter fullscreen mode Exit fullscreen mode

This plugin will print the statement when the webpack runs.

  • You can include this plugin in your webpack.config.js in the following way.
const myFirstWebpackPlugin = require("./my-first-webpack-plugin.js");

module.exports = {
    entry: resolve(__dirname, "src/index.js"),
    output: {
        filename: "bundle.js"
    },
    plugins: [new myFirstWebpackPlugin()]
};
Enter fullscreen mode Exit fullscreen mode
  • This is very basic plugin which logs the statement. We can customise this plugin by passing some options.
class MyFirstWebpackPlugin {
    constructor(options) {
        this.options = options || {
            env: "dev"
        };
    }
    apply(compiler) {
        console.log("My First webpack plugin");
    }
};
Enter fullscreen mode Exit fullscreen mode
  • The plugin in the webpack.config.js would be passed with arguments.
plugins: [
    new myFirstWebpackPlugin({
        env: "staging"
    })
]
Enter fullscreen mode Exit fullscreen mode
  • We have our plugin ready let's modify by printing the statement when the compiler.hooks.done is emitted.
apply(compiler) {
    compiler.hooks.done.tap("MyFirstWebpackPlugin", (stats) => {
        console.log(`My first webpack plugin is running on ${this.options.env}`)
        console.log("stats", stats);
    })
}
Enter fullscreen mode Exit fullscreen mode

Stats here will show a large object with every possible detail about the compilation and the file available for that hook.

The Tapable instance on which webpack is based has different parts and each part has different hooks associated with it.

Compiler Hooks

There are many other hooks like run, emit, beforeRun and many other with which we can bind our plugins. Hooks extends the Tapable class in order to register and call plugins. The compiler module is the main engine that creates compilation instance with all options passed to it, most of the user facing plugins are first registered on compiler.

Compilation Hooks

Compilation helps in loading, sealing, optimising, chunking, hashing and restoring the modules. The compilation also extends Tapable and provides lifecycle hooks. It can be used to change modules before the module is build, rebuild or after successful built of module etc

Javascript Parser Hooks

Similarly there is Javascript Parser Hooks which is used to parse each module processed by webpack. It extends Tapable and can be used by your custom plugin to enhance the parsing process. You can find more about the Parser hooks here

Yay!!!! 🎉
With this you have learnt how to create your custom webpack plugin.

I have created a custom plugin to solve one of the problems which I faced while working on chrome extension. I have to repeat series of manual process when I was trying to deploy my extension on web store for different environments. Every time I have to minify js files, create a zip file of source code and change the version in the manifest.json file. Creating webpack plugin helped me to automate the process and learn about the bundling process and working of webpack and its architecture.

You can have a look at the plugin on GitHub and can use it in your project by installing it using the following command.

npm i extension-build-webpack-plugin
Enter fullscreen mode Exit fullscreen mode

GitHub logo Jasmin2895 / extension-build-webpack-plugin

webpack plugin to automate extension deployment process

📦 Webpack plugin for extension build

License: MIT

This plugin helps to create a production ready build for chrome extension. This helps in updating the version of manifest.json file and create a zip folder of the source code.

Installation

npm i extension-build-webpack-plugin --save-dev

This extenion uses src directory to create a zip folder. In order to use the plugin make sure all the browser extension files are in src directory including the manifest.json file.

Usage

In your webpack.config.js file add the following code:

const BrowserExtensionPlugin = require("extension-build-webpack-plugin");
module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new BrowserExtensionPlugin({
Enter fullscreen mode Exit fullscreen mode

Happy Reading!

Discussion

pic
Editor guide