webpack插件demo编写

webpack插件demo编写

场景:项目仓库是小部件编码管理,需要将生成的dist内单个小部件文件夹手动打包成zip,再上传至项目平台。
因为每次打包完之后都要手动压缩,略微有些繁琐(每次手动压缩十几个文件,一天N次,要疯,果然偷懒是第一生产力),正好也要试一下怎么写webpack插件,就实现了一个很小的插件demo。

1. webpack怎么写插件

webpack官网原文:
插件是 webpack 生态系统的重要组成部分,为社区用户提供了一种强大方式来直接触及 webpack 的编译过程(compilation process)。插件能够 钩入(hook) 到在每个编译(compilation)中触发的所有关键事件。在编译的每一步,插件都具备完全访问 compiler 对象的能力,如果情况合适,还可以访问当前 compilation 对象。

我的理解就是插件可以在webpack编译的某些步骤执行插件中的方法(类似vue中不同生命周期执行不同的方法)

1.1 hooks+触发时机

webpack拥有的钩子:compilercompilation
各自抛出的生命周期函数
Tapable:webpack的核心工具,暴露tap(同步), tapAsync(异步) 和 tapPromise (延迟的异步)方法
eq.

// 钩子.hooks.钩子的生命周期函数.触发机制('pluginName', 函数抛出的参数 => { 执行代码 })
compiler.hooks.someHook.tap('', params => {...})

1.2 怎么调用插件

了解了执行时机之后,需要知道怎么让我们的插件和webpack发生关联,并拿到compiler钩子,才能使用钩子对象。
webpack会调用插件的apply属性,类似vue会调用install属性一样
webpack在配置时是new的实例,并且可以传参

  plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
}

综上:一个插件的结构就出来了

function BuildAddZip (options) {
	this.options = options
}
BuildAddZip.prototype.apply = function (compiler) {
	compiler.hooks.done.tap('BuildAddZip', stats => {
		...
	}
}

2. 小demo实现步骤

2.1 需求

打包后dist内的文件夹自动生成zip包

2.2 代码分析

  1. 插件在哪个钩子函数中执行:dist是在打包完成之后,所以compiler钩子中的done(编译完成) 可以拿到最新的打包资源
  2. 如何获取最新的打包文件:done抛出的参数stats中可以获取stats.toJson().assets
  3. 如何新增zip包:adm-zip(百度的包,这个包据说解压有点问题,这里只用到压缩)

2.3 代码实现

const AdmZip = require('adm-zip')
function BuildAddZip (options) {
	// 获取参数,这边没有使用到,假装获取下
	this.options = options
}
BuildAddZip.prototype.apply = function (compiler) {
	// 获取打包输出文件路径
	const output = compiler.options.output.path
	compiler.hooks.done.tap('BuildAddZip', stats => {
		// ['draw/index.js', 'draw/asstes/img/a.png', 'home/index.js', 'home/index.html'...]
		// 获取打包文件中的文件路径, 并获取第一层文件名
		// ['draw', 'draw', 'home', 'home']
		const allFilesName = states.toJson().assets.map(asset => asset.name.split('/')[0])
		// 去重,['draw', 'home']
		const allFiles = [...new Set(allFilesName)]
		allFiles && allFiles.length && allFiles.forEach(filename => {
			// 打包
			const zip = new AdmZip()
			// 这一行是为了层级,比如对整个draw打包,没有则是对draw内部文件打包,包了一层draw
			zip.addLocalFolder(`${output}/${filename}`)
			zip.writeZip(`${output}/${filename}.zip`)
		})
	})
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值