mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
74 lines
1.6 KiB
JavaScript
74 lines
1.6 KiB
JavaScript
|
|
||
|
export default class DetachPlugin {
|
||
|
apply (compiler) {
|
||
|
compiler.pluginDetachFns = new Map()
|
||
|
compiler.plugin = plugin(compiler.plugin)
|
||
|
compiler.apply = apply
|
||
|
compiler.detach = detach
|
||
|
compiler.getDetachablePlugins = getDetachablePlugins
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export function detachable (Plugin) {
|
||
|
const { apply } = Plugin.prototype
|
||
|
|
||
|
Plugin.prototype.apply = function (compiler) {
|
||
|
const fns = []
|
||
|
|
||
|
const { plugin } = compiler
|
||
|
compiler.plugin = function (name, fn) {
|
||
|
fns.push(plugin.call(this, name, fn))
|
||
|
}
|
||
|
|
||
|
// collect the result of `plugin` call in `apply`
|
||
|
apply.call(this, compiler)
|
||
|
|
||
|
compiler.plugin = plugin
|
||
|
|
||
|
return fns
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function plugin (original) {
|
||
|
return function (name, fn) {
|
||
|
original.call(this, name, fn)
|
||
|
|
||
|
return () => {
|
||
|
const names = Array.isArray(name) ? name : [name]
|
||
|
for (const n of names) {
|
||
|
const plugins = this._plugins[n] || []
|
||
|
const i = plugins.indexOf(fn)
|
||
|
if (i >= 0) plugins.splice(i, 1)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function apply (...plugins) {
|
||
|
for (const p of plugins) {
|
||
|
const fn = p.apply(this)
|
||
|
if (!fn) continue
|
||
|
|
||
|
const fns = this.pluginDetachFns.get(p) || new Set()
|
||
|
|
||
|
const _fns = Array.isArray(fn) ? fn : [fn]
|
||
|
for (const f of _fns) fns.add(f)
|
||
|
|
||
|
this.pluginDetachFns.set(p, fns)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function detach (...plugins) {
|
||
|
for (const p of plugins) {
|
||
|
const fns = this.pluginDetachFns.get(p) || new Set()
|
||
|
for (const fn of fns) {
|
||
|
if (typeof fn === 'function') fn()
|
||
|
}
|
||
|
this.pluginDetachFns.delete(p)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function getDetachablePlugins () {
|
||
|
return new Set(this.pluginDetachFns.keys())
|
||
|
}
|