Напишите свой собственный WebPack Plug Plugin

Webpack

Дело не в том, что у них нет меня, и дело не в том, что я ничего не беру. - Чжуанцзы

Введение


webpackwebpackОдинаковая конфигурация системы подключаемых в вышеупомянутых! Plug Preions, чтобы решитьloaderдругие вещи, которые не могут быть достигнуты. Если вы хотите написать хороший плагин, вам нужно знатьWebpackДва из наиболее центральных понятий вcompiler,compilation,tapable. существуетпроцесс компиляции вебпакаВсе должны быть записаны.Webpackпройти черезPlugin机制让其更加灵活,以适应各种应用场景。 существуетWebpackМногие события транслируются в течение жизненного цикла бега,PluginВы можете слушать эти события и проходить их в нужное времяWebpackкоторый предоставилAPIИзменения в выводе.


  1. Функция или класс JavaScript
  2. Определить инъекцию в прототипе функции (prototype)compilerобъектapplyметод.
  3. applyчерез функциюcompilerВставьте указанный хук события и получите его в обратном вызове хукаcompilationобъект
  4. использоватьcompilationмодификация манипуляцииwebapackДанные внутреннего экземпляра.
  5. Асинхронный плагин, используемый после обработки данныхcallbackПерезвоните

Наконец, простойclean-webpack-plugin.

простой плагин

class WebpackCleanupPlugin {
  // 构造函数
  constructor(options) {
    console.log("WebpackCleanupPlugin", options);
  }
  // 应用函数
  apply(compiler) {
    console.log(compiler);
    // 绑定钩子事件
    compiler.plugin("done", compilation => {
      console.log(compilation);
    });
  }
}

Как использовать Введите и используйте в webpack.config.js следующим образом:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// 引入自己的插件
const WebpackCleanupPlugin = require("./WebpackCleanupPlugin");
module.exports = {
  devtool: "source-map",
  mode: "production",
  entry: {
    index: "./src/index.js",
    chunk1: "./src/chunk1.js"
  },
  output: {
    filename: "[name].[chunkhash].js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"]
      }
    ]
  },
  plugins: [
    // 提取css插件
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].[contenthash].css"
    }),
    // 使用自己的插件
    new WebpackCleanupPlugin()
  ]
};

Плагин, написанный мной, выполняется следующим образом:

  • webpackПосле запуска он будет выполняться первым в процессе чтения конфигурацииnew WebpackCleanupPlugin()Инициализируйте WebpackCleanupPlugin, чтобы получить его экземпляр.
  • в инициализацииcompilerобъект, затем позвонитеWebpackCleanupPlugin.apply(compiler)Примеры плагинов к входящимcompilerобъект.
  • compilercompiler.pluginWebpackтрансляции событий.
  • и может пройтиcompilerобъект для работыwebpack.

компилятор, компиляция

  • Объект Compiler содержит всю информацию о конфигурации среды Webpack.,Включатьoptions,hook,loaders,pluginsЭта информация, этот объект находится вWebpackсоздается при запуске, этоглобально уникальный, что можно просто понимать какWebpackПримеры;CompilerВключены следующие:

webpacl-plugin

  • Объект Compilation содержит текущие ресурсы модуля, скомпилированные ресурсы, измененные файлы и т. д.. когдаWebpackЧтобы разрабатывать режим работы, когда обнаружено изменение файла, новыйCompilationОн будет создан.CompilationОбъект также предоставляет многие события обратных вызовов для плагинов. пройти черезCompilationМожет читатьCompilerобъект.

CompilationВключены следующие:

webpacl-plugin

Разница между Компилятором и Компиляцией в том, что:Compilerпредставляет весьWebpackCompilationПросто представляет новую компиляцию.

Хуки компилятораа такжекрючок компиляции

Простой плагин для очистки файлов


Каждый раз, когда пакет упаковывается, если файл модифицируется, будет создан новый файл.hashОн также изменится, то этот измененный файл, его предыдущий файл недействителен, чтобы очистить предыдущий файл, мы используем больше isclean-webpack-plugin, здесь реализовать простую очистку файлов. если ты не знаешьхеш, контентхэш, чанкхэшРазницу можно увидеть в этой статье.

Он примерно разделен на следующие шаги:

  • ПолучатьoutputПуть, то есть путь выхода, как правило,dist
  • Событие привязки хукаcompiler.plugin('done', (stats) => {})

Код реализован следующим образом

const recursiveReadSync = require("recursive-readdir-sync");
const minimatch = require("minimatch");
const path = require("path");
const fs = require("fs");
const union = require("lodash.union");

// 匹配文件
function getFiles(fromPath, exclude = []) {
  const files = recursiveReadSync(fromPath).filter(file =>
    exclude.every(
      excluded =>
        !minimatch(path.relative(fromPath, file), path.join(excluded), {
          dot: true
        })
    )
  );
  // console.log(files);
  return files;
}

class WebpackCleanupPlugin {
  constructor(options = {}) {
    // 配置文件
    this.options = options;
  }
  apply(compiler) {
    // 获取output路径
    const outputPath = compiler.options.output.path;
    // 绑定钩子事件
    compiler.plugin("done", stats => {
      if (
        compiler.outputFileSystem.constructor.name !== "NodeOutputFileSystem"
      ) {
        return;
      }
      // 获取编译完成 文件名
      const assets = stats.toJson().assets.map(asset => asset.name);
      console.log(assets);
      // 多数组合并并且去重
      const exclude = union(this.options.exclude, assets);
      console.log(exclude);
      // console.log('outputPath', outputPath);
      // 获取未匹配文件
      const files = getFiles(outputPath, exclude);
      // const files = [];
      console.log("files", files);
      if (this.options.preview) {
        // console.log('%s file(s) would be deleted:', files.length);
        // 输出文件
        files.forEach(file => console.log("    %s", file));
        // console.log();
      } else {
        // 删除未匹配文件
        files.forEach(fs.unlinkSync);
      }
      if (!this.options.quiet) {
        // console.log('\nWebpackCleanupPlugin: %s file(s) deleted.', files.length);
      }
    });
  }
}
module.exports = WebpackCleanupPlugin;

Приведенный выше плагин реализует эффект очистки скомпилированных файлов. Я не буду проводить эксперимент здесь, если вам интересно, вы можете скопировать код на локальный и запустить его, чтобы увидеть результаты.

Суммировать

Я примерно знаю, как написать простой чистый файл выше.webpackизплагин, на самом деле вы можете делать больше вещей следующим образом:

  • Чтение выходного ресурса, блоков кода, модулей и зависимостей (вemitмероприятие)
  • Отслеживание изменений файловwatch-run
  • Изменить выходной ресурсcompilation.assets

Конкретная реализация может взглянуть навебпак простым языком

Ссылаться на

Сухой товар! Создайте плагин веб-пакета (включая подробное объяснение + процесс веб-пакета)

Посмотреть настоящий плагин Webpack