Skip to content

Commit 1d1e064

Browse files
urbnjamesmi1sxzz
andauthored
feat: expose native build context (#404)
* Allow access to rspack and webpack LoaderContext in the UnpluginBuildContext that is available in the load and transform hooks * refactor * fix: no native context for vite and roll{up,down} --------- Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
1 parent 15c1882 commit 1d1e064

File tree

14 files changed

+77
-71
lines changed

14 files changed

+77
-71
lines changed

src/esbuild/index.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,15 @@ export function getEsbuildPlugin<UserOptions = Record<string, never>>(
141141

142142
function buildSetup(meta: UnpluginContextMeta & { framework: 'esbuild' }) {
143143
return (plugin: UnpluginOptions): EsbuildPlugin['setup'] => {
144-
return (build) => {
145-
meta.build = build as EsbuildPluginBuild
146-
const { onStart, onEnd, onResolve, onLoad, onTransform, initialOptions }
147-
= build as EsbuildPluginBuild
144+
return (_build) => {
145+
const build = meta.build = _build as EsbuildPluginBuild
146+
const context = createBuildContext(build)
147+
const { onStart, onEnd, onResolve, onLoad, onTransform, initialOptions } = build
148148

149149
const onResolveFilter = plugin.esbuild?.onResolveFilter ?? /.*/
150150
const onLoadFilter = plugin.esbuild?.onLoadFilter ?? /.*/
151151

152152
const loader = plugin.esbuild?.loader ?? guessLoader
153-
const context = createBuildContext(initialOptions)
154153

155154
if (plugin.esbuild?.config)
156155
plugin.esbuild.config.call(context, initialOptions)

src/esbuild/utils.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { Buffer } from 'buffer'
44
import remapping from '@ampproject/remapping'
55
import { Parser } from 'acorn'
66
import type { DecodedSourceMap, EncodedSourceMap } from '@ampproject/remapping'
7-
import type { BuildOptions, Loader, Location, Message, PartialMessage } from 'esbuild'
7+
import type { Loader, Location, Message, PartialMessage } from 'esbuild'
88
import type { SourceMap } from 'rollup'
99
import type { UnpluginBuildContext, UnpluginContext, UnpluginMessage } from '../types'
10+
import type { EsbuildPluginBuild } from '.'
1011

1112
export * from '../utils'
1213

@@ -111,9 +112,9 @@ export function combineSourcemaps(
111112
return map as EncodedSourceMap
112113
}
113114

114-
export function createBuildContext(initialOptions: BuildOptions): UnpluginBuildContext {
115+
export function createBuildContext(build: EsbuildPluginBuild): UnpluginBuildContext {
115116
const watchFiles: string[] = []
116-
117+
const { initialOptions } = build
117118
return {
118119
parse(code: string, opts: any = {}) {
119120
return Parser.parse(code, {
@@ -140,6 +141,9 @@ export function createBuildContext(initialOptions: BuildOptions): UnpluginBuildC
140141
getWatchFiles() {
141142
return watchFiles
142143
},
144+
getNativeBuildContext() {
145+
return { framework: 'esbuild', build }
146+
},
143147
}
144148
}
145149

src/farm/context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ export function createFarmContext(
3535
getWatchFiles() {
3636
return context.getWatchFiles()
3737
},
38+
getNativeBuildContext() {
39+
return { framework: 'farm', context }
40+
},
3841
}
3942
}
4043

src/farm/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import path from 'path'
2-
32
import type {
3+
CompilationContext,
4+
JsPlugin,
45
PluginLoadHookParam,
56
PluginLoadHookResult,
67
PluginResolveHookParam,
78
PluginTransformHookParam,
89
PluginTransformHookResult,
9-
} from '@farmfe/core/binding'
10-
import type { CompilationContext, JsPlugin } from '@farmfe/core'
10+
} from '@farmfe/core'
1111
import { toArray } from '../utils'
1212
import type {
1313
JsPluginExtended,

src/rspack/context.ts

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
import { resolve } from 'path'
22
import { Buffer } from 'buffer'
3-
import type { Compilation, LoaderContext } from '@rspack/core'
3+
import type { Compilation, Compiler, LoaderContext } from '@rspack/core'
44
import { Parser } from 'acorn'
55
import type { UnpluginBuildContext, UnpluginContext, UnpluginMessage } from '../types'
66

7-
interface ContextOptions {
8-
addWatchFile: (file: string) => void
9-
getWatchFiles: () => string[]
10-
}
11-
12-
export function contextOptionsFromCompilation(compilation: Compilation): ContextOptions {
7+
export function createBuildContext(compiler: Compiler, compilation: Compilation, loaderContext?: LoaderContext): UnpluginBuildContext {
138
return {
9+
getNativeBuildContext() {
10+
return {
11+
framework: 'rspack',
12+
compiler,
13+
compilation,
14+
loaderContext,
15+
}
16+
},
1417
addWatchFile(file) {
15-
compilation.fileDependencies.add(file)
18+
compilation.fileDependencies.add(resolve(process.cwd(), file))
1619
},
1720
getWatchFiles() {
1821
return Array.from(compilation.fileDependencies)
1922
},
20-
}
21-
}
22-
23-
export function createBuildContext(options: ContextOptions, compilation: Compilation): UnpluginBuildContext {
24-
return {
2523
parse(code: string, opts: any = {}) {
2624
return Parser.parse(code, {
2725
sourceType: 'module',
@@ -30,9 +28,6 @@ export function createBuildContext(options: ContextOptions, compilation: Compila
3028
...opts,
3129
})
3230
},
33-
addWatchFile(id) {
34-
options.addWatchFile(resolve(process.cwd(), id))
35-
},
3631
emitFile(emittedFile) {
3732
const outFileName = emittedFile.fileName || emittedFile.name
3833
if (emittedFile.source && outFileName) {
@@ -47,9 +42,6 @@ export function createBuildContext(options: ContextOptions, compilation: Compila
4742
)
4843
}
4944
},
50-
getWatchFiles() {
51-
return options.getWatchFiles()
52-
},
5345
}
5446
}
5547

src/rspack/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
UnpluginFactory,
1010
UnpluginInstance,
1111
} from '../types'
12-
import { contextOptionsFromCompilation, createBuildContext, normalizeMessage } from './context'
12+
import { createBuildContext, normalizeMessage } from './context'
1313
import { decodeVirtualModuleId, encodeVirtualModuleId } from './utils'
1414

1515
const TRANSFORM_LOADER = resolve(
@@ -74,7 +74,7 @@ export function getRspackPlugin<UserOptions = Record<string, never>>(
7474
const importer = requestContext.issuer !== '' ? requestContext.issuer : undefined
7575
const isEntry = requestContext.issuer === ''
7676

77-
const context = createBuildContext(contextOptionsFromCompilation(compilation), compilation)
77+
const context = createBuildContext(compiler, compilation)
7878
let error: Error | undefined
7979
const pluginContext: UnpluginContext = {
8080
error(msg) {
@@ -165,7 +165,7 @@ export function getRspackPlugin<UserOptions = Record<string, never>>(
165165

166166
if (plugin.watchChange || plugin.buildStart) {
167167
compiler.hooks.make.tapPromise(plugin.name, async (compilation) => {
168-
const context = createBuildContext(contextOptionsFromCompilation(compilation), compilation)
168+
const context = createBuildContext(compiler, compilation)
169169
if (plugin.watchChange && (compiler.modifiedFiles || compiler.removedFiles)) {
170170
const promises: Promise<void>[] = []
171171
if (compiler.modifiedFiles) {
@@ -188,7 +188,7 @@ export function getRspackPlugin<UserOptions = Record<string, never>>(
188188

189189
if (plugin.buildEnd) {
190190
compiler.hooks.emit.tapPromise(plugin.name, async (compilation) => {
191-
await plugin.buildEnd!.call(createBuildContext(contextOptionsFromCompilation(compilation), compilation))
191+
await plugin.buildEnd!.call(createBuildContext(compiler, compilation))
192192
})
193193
}
194194

src/rspack/loaders/load.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { LoaderContext } from '@rspack/core'
2-
import { contextOptionsFromCompilation, createBuildContext, createContext } from '../context'
2+
import { createBuildContext, createContext } from '../context'
33
import { normalizeAbsolutePath } from '../../utils'
44
import { decodeVirtualModuleId, isVirtualModuleId } from '../utils'
55

@@ -19,7 +19,7 @@ export default async function load(this: LoaderContext, source: string, map: any
1919
const res = await plugin.load.call(
2020
Object.assign(
2121
{},
22-
this._compilation && createBuildContext(contextOptionsFromCompilation(this._compilation), this._compilation),
22+
this._compilation && createBuildContext(this._compiler, this._compilation, this),
2323
context,
2424
),
2525
normalizeAbsolutePath(id),

src/rspack/loaders/transform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { LoaderContext } from '@rspack/core'
2-
import { contextOptionsFromCompilation, createBuildContext, createContext } from '../context'
2+
import { createBuildContext, createContext } from '../context'
33

44
export default async function transform(
55
this: LoaderContext,
@@ -27,7 +27,7 @@ export default async function transform(
2727
const res = await plugin.transform.call(
2828
Object.assign(
2929
{},
30-
this._compilation && createBuildContext(contextOptionsFromCompilation(this._compilation), this._compilation),
30+
this._compilation && createBuildContext(this._compiler, this._compilation, this),
3131
context,
3232
),
3333
source,

src/types.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { AstNode, EmittedAsset, PluginContextMeta as RollupContextMeta, Plugin as RollupPlugin, SourceMapInput } from 'rollup'
2-
import type { Compiler as WebpackCompiler, WebpackPluginInstance } from 'webpack'
2+
import type { Compilation as WebpackCompilation, Compiler as WebpackCompiler, LoaderContext as WebpackLoaderContext, WebpackPluginInstance } from 'webpack'
33
import type { Plugin as VitePlugin } from 'vite'
44
import type { Plugin as RolldownPlugin } from 'rolldown'
55
import type { BuildOptions, Plugin as EsbuildPlugin, Loader } from 'esbuild'
6-
import type { Compiler as RspackCompiler, RspackPluginInstance } from '@rspack/core'
6+
import type { Compilation as RspackCompilation, Compiler as RspackCompiler, LoaderContext as RspackLoaderContext, RspackPluginInstance } from '@rspack/core'
77
import type VirtualModulesPlugin from 'webpack-virtual-modules'
8-
import type { JsPlugin as FarmPlugin } from '@farmfe/core'
8+
import type { CompilationContext as FarmCompilationContext, JsPlugin as FarmPlugin } from '@farmfe/core'
99
import type { EsbuildPluginBuild } from './esbuild'
1010

1111
export {
@@ -40,11 +40,18 @@ export type TransformResult = string | { code: string, map?: SourceMapInput | So
4040

4141
export interface ExternalIdResult { id: string, external?: boolean }
4242

43+
export type NativeBuildContext =
44+
{ framework: 'webpack', compiler: WebpackCompiler, compilation?: WebpackCompilation, loaderContext?: WebpackLoaderContext<{ unpluginName: string }> } |
45+
{ framework: 'esbuild', build: EsbuildPluginBuild } |
46+
{ framework: 'rspack', compiler: RspackCompiler, compilation: RspackCompilation, loaderContext?: RspackLoaderContext } |
47+
{ framework: 'farm', context: FarmCompilationContext }
48+
4349
export interface UnpluginBuildContext {
4450
addWatchFile: (id: string) => void
4551
emitFile: (emittedFile: EmittedAsset) => void
4652
getWatchFiles: () => string[]
4753
parse: (input: string, options?: any) => AstNode
54+
getNativeBuildContext?: () => NativeBuildContext
4855
}
4956

5057
export interface UnpluginOptions {
@@ -117,24 +124,19 @@ export interface UnpluginInstance<UserOptions, Nested extends boolean = boolean>
117124
}
118125

119126
export type UnpluginContextMeta = Partial<RollupContextMeta> & ({
120-
framework: 'rollup' | 'vite' | 'rolldown'
127+
framework: 'rollup' | 'vite' | 'rolldown' | 'farm'
121128
} | {
122129
framework: 'webpack'
123-
webpack: {
124-
compiler: WebpackCompiler
125-
}
130+
webpack: { compiler: WebpackCompiler }
126131
} | {
127132
framework: 'esbuild'
133+
/** @deprecated {getNativeBuildContext} */
128134
build?: EsbuildPluginBuild
129135
/** Set the host plugin name of esbuild when returning multiple plugins */
130136
esbuildHostName?: string
131137
} | {
132138
framework: 'rspack'
133-
rspack: {
134-
compiler: RspackCompiler
135-
}
136-
} | {
137-
framework: 'farm'
139+
rspack: { compiler: RspackCompiler }
138140
})
139141

140142
export interface UnpluginMessage {

src/utils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,12 @@ export function transformUse(
6363
}
6464
return []
6565
}
66+
67+
export function resolveQuery(query: string | { unpluginName: string }) {
68+
if (typeof query === 'string') {
69+
return new URLSearchParams(query).get('unpluginName')!
70+
}
71+
else {
72+
return query.unpluginName
73+
}
74+
}

0 commit comments

Comments
 (0)