插件的环境

  • 插件没有像 loader 有独立的运行环境(loader-runner)
  • 只能在 webpack 里面运行

loader 是编译过程中,对文件内容进行转换、翻译。 插件则伴随整个 webpack 构建的生命周期,从初始化到文件生成。 loader 没法做的事情,可考虑用 插件 来做

image.png

插件使用简介

插件如何获取参数

通过插件的构造函数进行获取。
image.png

插件的错误处理

image.png

通过 Compilation 进行文件写入

Compilation 上的 assets 可以用于文件写入

  • 可以将 zip 资源包设置到 compilation.assets 对象上

文件写入需要使用 webpack-sources

插件扩展:编写插件的插件

image.png

开始自定义插件

开发一个压缩构建资源为 zip 包的插件

  • 生成的 zip 包文件名称可以通过插件传入
  • 需要使用 compiler 对象上的特定 hooks 进行资源生成

    使用 jszip

  1. const JSZip = require('jszip');
  2. const path = require('path');
  3. const { RawSource } = require('webpack-sources')
  4. const zip = new JSZip();
  5. class ZipPlugin {
  6. constructor(options) {
  7. this.options = options;
  8. }
  9. checkOptions() {
  10. if (!this.options.name) throw new Error("ZipPlugin's options need name")
  11. }
  12. apply(compiler) {
  13. this.checkOptions();
  14. compiler.hooks.emit.tapAsync('ZipPlugin', (compilation, callback) => {
  15. const folder = zip.folder(this.options.name);
  16. for (let filename in compilation.assets) {
  17. const source = compilation.assets[filename].source();
  18. folder.file(filename, source);
  19. }
  20. zip.generateAsync({ type: 'nodebuffer' })
  21. .then(content => {
  22. const outputPath = path.join(
  23. compilation.options.output.path,
  24. this.options.name + '.zip'
  25. );
  26. const outputRelativePath = path.relative(compilation.options.output.path, outputPath);
  27. compilation.assets[outputRelativePath] = new RawSource(content);
  28. callback();
  29. })
  30. })
  31. }
  32. }
  33. module.exports = ZipPlugin;