Skip to content

Commit

Permalink
feat: init webpack load support
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Jul 13, 2021
1 parent 0104790 commit d8a34b4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 12 deletions.
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./dist/webpack/loader": {
"require": "./dist/webpack/loader.cjs"
}
"./dist/webpack/loaders/transform": "./dist/webpack/loaders/transform.cjs",
"./dist/webpack/loaders/load": "./dist/webpack/loaders/load.cjs"
},
"main": "dist/index.cjs",
"module": "dist/index.mjs",
Expand Down
10 changes: 8 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Plugin as RollupPlugin } from 'rollup'

export type Thenable<T> = T | Promise<T>

export interface UnpluginHooks {
export interface UnpluginOptions {
name: string;
enforce?: 'post' | 'pre' | undefined;
transformInclude?: (id: string) => boolean;
Expand All @@ -11,9 +11,15 @@ export interface UnpluginHooks {
resolveId?: (id?:string) => Thenable<string | null | undefined>
}

export type UnpluginFactory<UserOptions> = (options?: UserOptions) => UnpluginHooks
export type UnpluginFactory<UserOptions> = (options?: UserOptions) => UnpluginOptions

export interface UnpluginInstance<UserOptions> {
rollup: (options?: UserOptions) => RollupPlugin;
webpack: (options?: UserOptions) => any;
}

declare module 'webpack' {
interface Compiler {
$unpluginContext: Record<string, UnpluginOptions>
}
}
21 changes: 17 additions & 4 deletions src/webpack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ export function getWebpackPlugin<UserOptions = {}> (
apply (compiler: Compiler) {
const rawPlugin = factory(this.userOptions)

// @ts-expect-error
if (!compiler.$unpluginContext) {
// @ts-expect-error
compiler.$unpluginContext = {}
}
// @ts-expect-error
compiler.$unpluginContext[rawPlugin.name] = rawPlugin

if (rawPlugin.transform) {
Expand All @@ -30,7 +27,23 @@ export function getWebpackPlugin<UserOptions = {}> (
},
enforce: rawPlugin.enforce,
use: [{
loader: resolve(__dirname, '..', 'dist/webpack/loader.cjs'),
loader: resolve(__dirname, '..', 'dist/webpack/loaders/transform.cjs'),
options: {
unpluginName: rawPlugin.name
}
}]
})
}

// TODO: not working for virtual module
if (rawPlugin.load) {
compiler.options.module.rules.push({
include () {
return true
},
enforce: rawPlugin.enforce,
use: [{
loader: resolve(__dirname, '..', 'dist/webpack/loaders/load.cjs'),
options: {
unpluginName: rawPlugin.name
}
Expand Down
25 changes: 25 additions & 0 deletions src/webpack/loaders/load.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { LoaderContext } from 'webpack'
import '../../types'

export default async function load (this: LoaderContext<any>, source: string) {
const callback = this.async()
const { unpluginName } = this.query
const plugin = this._compiler?.$unpluginContext[unpluginName]

if (!plugin?.resolveId || !plugin?.load) {
return callback(null, source)
}

const id = await plugin.resolveId(this.resource)
if (id == null) {
return callback(null, source)
}

const res = await plugin.load(id)

if (res == null) {
callback(null, source)
} else {
callback(null, res)
}
}
10 changes: 7 additions & 3 deletions src/webpack/loader.ts → src/webpack/loaders/transform.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import type { LoaderContext } from 'webpack'
import '../../types'

export default async function (this: LoaderContext<any>, source: string, map: any) {
export default async function transform (this: LoaderContext<any>, source: string, map: any) {
const callback = this.async()
const { unpluginName } = this.query
// @ts-expect-error
const plugin = this._compiler.$unpluginContext[unpluginName]
const plugin = this._compiler?.$unpluginContext[unpluginName]

if (!plugin?.transform) {
return callback(null, source, map)
}

const res = await plugin.transform(source, this.resource)

Expand Down

0 comments on commit d8a34b4

Please sign in to comment.