diff --git a/README.md b/README.md index f10a36af..bbfed5f2 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Currently supports: | [`transform`](https://rollupjs.org/guide/en/#transformers) | ✅ | ✅ | ✅ | ✅ | ✅ 3 | | [`enforce`](https://rollupjs.org/guide/en/#enforce) | ❌ 2 | ✅ | ✅ | ✅ | ❌ 2 | | [`resolveId`](https://rollupjs.org/guide/en/#resolveid) | ✅ | ✅ | ✅ | ✅ | ✅ | +| `loadInclude`1 | ✅ | ✅ | ✅ | ✅ | ✅ | | [`load`](https://rollupjs.org/guide/en/#load) | ✅ | ✅ | ✅ | ✅ | ✅ 3 | | [`watchChange`](https://rollupjs.org/guide/en/#watchchange) | ✅ | ✅ | ✅ | ✅ | ✅ | diff --git a/src/esbuild/index.ts b/src/esbuild/index.ts index 7180c2dd..ab97fd73 100644 --- a/src/esbuild/index.ts +++ b/src/esbuild/index.ts @@ -132,7 +132,7 @@ export function getEsbuildPlugin ( let code: string | undefined, map: SourceMap | null | undefined - if (plugin.load) { + if (plugin.load && (!plugin.loadInclude || plugin.loadInclude(id))) { const result = await plugin.load.call(Object.assign(context, pluginContext), id) if (typeof result === 'string') { code = result diff --git a/src/rollup/index.ts b/src/rollup/index.ts index c7a9cde0..d3539d41 100644 --- a/src/rollup/index.ts +++ b/src/rollup/index.ts @@ -23,6 +23,16 @@ export function toRollupPlugin (plugin: UnpluginOptions, containRollupOptions = } } + if (plugin.load && plugin.loadInclude) { + const _load = plugin.load + plugin.load = function (id) { + if (plugin.loadInclude && !plugin.loadInclude(id)) { + return null + } + return _load.call(this, id) + } + } + if (plugin.rollup && containRollupOptions) { Object.assign(plugin, plugin.rollup) } diff --git a/src/types.ts b/src/types.ts index fad19fb0..c9c617fc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,14 +27,25 @@ export interface UnpluginBuildContext { export interface UnpluginOptions { name: string; enforce?: 'post' | 'pre' | undefined; + buildStart?: (this: UnpluginBuildContext) => Promise | void; buildEnd?: (this: UnpluginBuildContext) => Promise | void; - transformInclude?: (id: string) => boolean | null | undefined; transform?: (this: UnpluginBuildContext & UnpluginContext, code: string, id: string) => Thenable; load?: (this: UnpluginBuildContext & UnpluginContext, id: string) => Thenable resolveId?: (id: string, importer: string | undefined, options: { isEntry: boolean }) => Thenable watchChange?: (this: UnpluginBuildContext, id: string, change: { event: 'create' | 'update' | 'delete' }) => void + /** + * Custom predicate function to filter modules to be loaded. + * When omitted, all modules will be included (might have potential perf impact on Webpack). + */ + loadInclude?: (id: string) => boolean | null | undefined; + /** + * Custom predicate function to filter modules to be transformed. + * When omitted, all modules will be included (might have potential perf impact on Webpack). + */ + transformInclude?: (id: string) => boolean | null | undefined; + // framework specify extends rollup?: Partial webpack?: (compiler: WebpackCompiler) => void diff --git a/src/webpack/index.ts b/src/webpack/index.ts index dd7fef1e..94c6c9aa 100644 --- a/src/webpack/index.ts +++ b/src/webpack/index.ts @@ -160,14 +160,18 @@ export function getWebpackPlugin ( // load hook if (plugin.load) { compiler.options.module.rules.push({ - include (id) { // Don't run load hook for external modules + include (id) { if (id.startsWith(plugin.__virtualModulePrefix)) { - // If module is a virtual one, we first need to strip its prefix and decode it - const decodedId = decodeURIComponent(id.slice(plugin.__virtualModulePrefix.length)) - return !externalModules.has(decodedId) - } else { - return !externalModules.has(id) + id = decodeURIComponent(id.slice(plugin.__virtualModulePrefix.length)) } + + // load include filter + if (plugin.loadInclude && !plugin.loadInclude(id)) { + return false + } + + // Don't run load hook for external modules + return !externalModules.has(id) }, enforce: plugin.enforce, use: [{ diff --git a/test/fixtures/virtual-module/unplugin.js b/test/fixtures/virtual-module/unplugin.js index f3cc22e7..8c66ad0a 100644 --- a/test/fixtures/virtual-module/unplugin.js +++ b/test/fixtures/virtual-module/unplugin.js @@ -6,14 +6,17 @@ module.exports = createUnplugin(() => { resolveId (id) { return id.startsWith('virtual/') ? id : null }, + loadInclude (id) { + return id.startsWith('virtual/') + }, load (id) { if (id === 'virtual/1') { return 'export default "VIRTUAL:ONE"' - } - if (id === 'virtual/2') { + } else if (id === 'virtual/2') { return 'export default "VIRTUAL:TWO"' + } else { + throw new Error(`Unexpected id: ${id}`) } - return null } } })