Your first webpack plugin ❤️

To start this exercise, be sure to be in ./packages/advanced/plugins folder. Be sure you have installed this repository first


You already saw and used many plugins with webpack. It gives user possibility to add features, optimize performance, etc...

An API is open to let you implement your own webpack plugin.


In your project you may need a plugin that already have been created by the community, don't hesitate to look at awesome-webpack.

You should also know that more than 70% of webpack core code is using it's own plugin API. webpack code is a great example of how to write a plugin ?

Hooks and tapable

Creating a Plugin A plugin for webpack consists of

  • A named JavaScript function.
  • Defines apply method in its prototype.
  • Specifies an event hook to tap into.
  • Manipulates webpack internal instance specific data.
  • Invokes webpack provided callback after functionality is complete.
class MyExampleWebpackPlugin {
  // Define `apply` as its prototype method which is supplied with compiler as its argument
  apply(compiler) {
    // Specify the event hook to attach to
      (compilation, callback) => {
        console.log("This is an example plugin!");
          "Here’s the `compilation` object which represents a single build of assets:",

        // Manipulate the build using the plugin API provided by webpack
        compilation.addModule(/* ... */);


Create a BuildTime

In order to learn to how to write a plugin. Try to define a plugin that take stats from done hooks and log build time in milliseconds.




const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const CompressionPlugin = require("compression-webpack-plugin");

class BuildTime {
  apply(compiler) {
    compiler.hooks.done.tapAsync("StatsFilePlugin", stats => {
        `Build took ${stats.endTime - stats.startTime} milliseconds!`

module.exports = {
  mode: "production",
  entry: "./src/main.js", // The source module of our dependency graph
  devServer: {
    contentBase: "./dist"
  output: {
    // Configuration of what we tell webpack to generate (here, a ./dist/main.js file)
    filename: "[name].bundle.[hash].js",
    path: path.resolve(__dirname, "dist")
  module: {
    rules: [
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader"
        test: /\.jpg$/,
        use: [
            loader: "file-loader",
            options: {
              outputPath: "assets",
              publicPath: "assets"
        test: /\.(sass|css)$/,
        use: ["style-loader", "css-loader", "sass-loader"]
        test: /\.vue$/,
        use: "vue-loader"
  plugins: [
    new VueLoaderPlugin(),
    new CleanWebpackPlugin("dist"),
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    new CompressionPlugin(),
    new BuildTime()