寫一個webpack插件

用問題去學習,用測試來驗證。css

一個webpack插件簡單的例子(來自webpack官方文檔)

1, 寫一個class 類
2, 寫一個apply方法
3, 寫一個監聽方法
2, 寫一個處理邏輯
html

// A JavaScript class.
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
    compiler.hooks.emit.tapAsync(
      'MyExampleWebpackPlugin',
      (compilation, callback) => {
        console.log('This is an example plugin!');
        console.log('Here’s the `compilation` object which represents a single build of assets:', compilation);

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

        callback();
      }
    );
  }
}
複製代碼

compile?

看插件的時候,我就一直有個疑問,什麼是compile?webpack

什麼是compile?

compile就是一個webpack實例化的對象,包括webpack打包的全部的信息,全部的上下文,包括內置的函數和webpack配置的信息,總之webpack執行過程的全部的信息。web

當咱們定義的一個plugin,好比是名字是A的插件的時候,首先是定義了一個類,這個類有一個apply方法,而後方法裏邊監聽了webpack的打包過程當中的事件。 使用A的時候,把A的實例傳入webpack.config.js的pulugins裏邊。bash

當執行webpack的時候,webpack就會執行app

A.apply(compile)
複製代碼

把compile對象傳給A的apply方法。ide

什麼是compilation?

compilation 是每次編譯的時候建立的全局變量,包含全部的上下文,同時能夠取到compile對象函數

寫一個插件

上面說了這麼多,還不如一次實戰,下面就開始寫一個插件。學習

背景描述

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  
  <srcipt src="1.js"> </script>
  <srcipt src="2.js"> </script>
</body>
</html>
複製代碼

上面是咱們的模板html文件,如今有個問題,當經過dllPlugin和html-webpack-plugin進行打包後,會變成這樣,測試

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  
  <srcipt src="1.js"> </script>
  <srcipt src="2.js"> </script>
  <srcipt src="dll.js"> </script>
  <srcipt src="main.js"> </script>
</body>
</html>
複製代碼

其實上面咱們的1.js和2.js通常都是代碼統計js文件,如今想寫個webpack插件,讓打包後的文件,插入到代碼統計文件的前面,也就是以下這樣:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  
  <srcipt src="dll.js"> </script>
  <srcipt src="main.js"> </script>
  <srcipt src="1.js"> </script>
  <srcipt src="2.js"> </script>
</body>
</html>
複製代碼

分析

這裏應該很簡單,由於html-webpack-plugin確定是拿到咱們的js文件,而後直接插入到咱們的模板文件中去的,因此咱們要作的就是在html-webpack-plugin插入以前,咱們把html-webpack-plugin想要插入的內容給改變,把咱們想添加的給添加進去,而後再讓html-webpack-plugin工做。

代碼

  • 1 定義咱們的插件,代碼很簡單,沒什麼好說的。
const HtmlWebpackPlugin = require("html-webpack-plugin");

class MyPlugin {
  constructor(options) {
    this.options = options;
  }
  apply(compiler) {
    compiler.hooks.compilation.tap("MyPlugin", compilation => {
      console.log("The compiler is starting a new compilation...");
      HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
        "MyPlugin",
        (data, cb) => {
          const paths = this.options.arr1;
          console.log(111111);
          console.log(data.assets);
          for (let i = paths.length - 1; i >= 0; i--) {
            data.assets.js.push(paths[i]);
          }
          cb(null, data);
        }
      );
    });
  }
}
module.exports = MyPlugin;

複製代碼
  • 2 使用
new MyPlugin({
      arr1: [
        "https://g.alicdn.com/de/prismplayer/2.5.1/aliplayer-min.js",
        "https://hm.baidu.com/hm.js?1ea7b7fd0d7259a472147a1ffd544938"
      ]
    }),
    new HtmlWebpackPlugin({
      template: "./index.ejs",
      filename: "../index.html",
      inlineSource: "manifest",
      inject: "body"
    }),
複製代碼

遇到的問題

  • 1  html-webpack-plugin的版本剛開始過低,由於之前安裝的是3.2.0的版本,致使報 HtmlWebpackPlugin.getHooks 不存在的錯誤

解決辦法: 卸載html-webpack-plugin舊版本,安裝最新的html-webpack-plugin版本

  • 2  "dependency" is not a valid chunk sort mode
new HtmlWebpackPlugin({
            chunksSortMode: 'dependency'
        }),
複製代碼

解決辦法: 去掉chunksSortMode: 'dependency'

  • 3  Please ensure that html-webpack-plugin was placed before html-replace-webpack-plugin in your Webpack config if you were working with Webpack 4.x!

解決辦法:明明已經放在前面了,不知道爲何一直報這個錯誤。後來一想,可能和版本有關係,由於升級了html-webpack-plugin,因此html-replace-webpack-plugin也得升級,因此把html-replace-webpack-plugin升級到2.5.6,就解決了。

new HtmlWebpackPlugin({
      template: "./index.ejs",
      filename: "../index.html",
      inlineSource: "manifest",
      inject: "body"
    }),

    new HtmlReplaceWebpackPlugin([
      {
        pattern: '<link rel="stylesheet" href="/load.css" />',
        replacement: `<style type="text/css">1111</style>`
      }
    ]),
複製代碼
相關文章
相關標籤/搜索