[关闭]
@bornkiller 2017-07-21T17:09:26.000000Z 字数 2122 阅读 1707

开发webpack插件

webpack


前言

webpack作为前端开发利器,提供PluginLoader扩展机制。开发者可以充分利用Webpack插件机制,扩展需要的功能。Loader功能简单,实现容易,不做说明。

插件之“形”

插件的结构固定,代码如下:

  1. class CompressionPlugin {
  2. constructor(options) {
  3. this.options = _.assign({}, defaultOption, options);
  4. }
  5. apply(compiler) {
  6. compiler.plugin('compilation', (compilation) => {
  7. // Just boilerplate code
  8. compilation.plugin('module-asset', (module, file) => {
  9. noop(file);
  10. });
  11. });
  12. compiler.plugin('emit', (compilation, callback) => {
  13. const assets = compilation.assets;
  14. }
  15. }
  16. }

开发插件包含以下几步:

  1. 函数声明(ES6 class)
  2. 原型apply函数
  3. 挂载webpack lifecycle hook
  4. 操作webpack compiler, compilation对象
  5. 执行回调,任务结束

插件之“神”

插件的核心简而概之:正确的时间做正确的事。

webpack hook数量繁多,参考官方文档。第三方插件功能多集中在文件处理,典型案例html-webpack-plugin,笔者也将实现简单插件,实现自动清理非本次编译生成文件。

  1. class CleanupPlugin {
  2. constructor(options) {
  3. this.options = _.assign({}, defaultCleanupOptions, options);
  4. this.rules = this.options.exclude;
  5. const status = validateExcludeRules(this.rules);
  6. if (!status) {
  7. throw new Error('CleanupPlugin exclude array must consist of string or RegExp');
  8. }
  9. this.exclusion = matchExcludeRules(this.rules);
  10. }
  11. apply(compiler) {
  12. compiler.plugin('after-emit', (compilation, callback) => {
  13. const assets = Reflect.ownKeys(compilation.assets);
  14. const files = recursiveReadDir(compiler.options.output.path);
  15. const extraneous = files.filter((filename) => !assets.includes(filename)).filter((filename) => !this.exclusion(filename));
  16. extraneous.forEach((filename) => {
  17. fs.unlinkSync(path.resolve(compiler.options.output.path, filename));
  18. if (!this.options.quite) {
  19. // eslint-disable-next-line no-console
  20. console.log(`${filename} already deleted`);
  21. }
  22. });
  23. callback();
  24. });
  25. }
  26. }

compilation.assets表示webpack compilation生成文件,读取输出目录文件,交叉比对,就能得到冗余文件并清理。完整代码见https://github.com/bornkiller/webpack-plugin-strawberry

插件样例

笔者学习开发插件的过程,翻阅部分插件,挂载lifecycle hook如下:

插件模式

webpack hook挂载执行方式不同,存在以下几种:

Contact

Email: hjj491229492@hotmail.com

qrcode_for_gh_d8efb59259e2_344.jpg-8.7kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注