Skip to content

Commit abfa804

Browse files
luxaritassapphi-red
andauthoredFeb 23, 2023
feat: support rollup plugin this.load in plugin container context (#11469)
Co-authored-by: 翠 / green <green@sapphi.red>
1 parent cc3724f commit abfa804

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed
 

‎packages/vite/src/node/server/__tests__/pluginContainer.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,44 @@ describe('plugin container', () => {
147147
expect.assertions(2)
148148
})
149149
})
150+
151+
describe('load', () => {
152+
beforeEach(() => {
153+
moduleGraph = new ModuleGraph((id) => resolveId(id))
154+
})
155+
156+
it('can resolve a secondary module', async () => {
157+
const entryUrl = '/x.js'
158+
159+
const plugin: Plugin = {
160+
name: 'p1',
161+
resolveId(id) {
162+
return id
163+
},
164+
load(id) {
165+
if (id === entryUrl) return { code: '1', meta: { x: 1 } }
166+
else return { code: '2', meta: { x: 2 } }
167+
},
168+
async transform(code, id) {
169+
if (id === entryUrl)
170+
return {
171+
code: `${
172+
(await this.load({ id: '/secondary.js' })).meta.x || undefined
173+
}`,
174+
}
175+
return { code }
176+
},
177+
}
178+
179+
const container = await getPluginContainer({
180+
plugins: [plugin],
181+
})
182+
await moduleGraph.ensureEntryFromUrl(entryUrl, false)
183+
const loadResult: any = await container.load(entryUrl)
184+
const result: any = await container.transform(loadResult.code, entryUrl)
185+
expect(result.code).equals('2')
186+
})
187+
})
150188
})
151189

152190
async function getPluginContainer(

‎packages/vite/src/node/server/pluginContainer.ts

+28-2
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,11 @@ import type {
4242
LoadResult,
4343
MinimalPluginContext,
4444
ModuleInfo,
45+
ModuleOptions,
4546
NormalizedInputOptions,
4647
OutputOptions,
4748
ParallelPluginHooks,
49+
PartialNull,
4850
PartialResolvedId,
4951
ResolvedId,
5052
RollupError,
@@ -126,8 +128,6 @@ export interface PluginContainer {
126128

127129
type PluginContext = Omit<
128130
RollupPluginContext,
129-
// not supported
130-
| 'load'
131131
// not documented
132132
| 'cache'
133133
// deprecated
@@ -221,6 +221,10 @@ export async function createPluginContainer(
221221
if (key in info) {
222222
return info[key]
223223
}
224+
// Don't throw an error when returning from an async function
225+
if (key === 'then') {
226+
return undefined
227+
}
224228
throw Error(
225229
`[vite] The "${key}" property of ModuleInfo is not supported.`,
226230
)
@@ -306,6 +310,28 @@ export async function createPluginContainer(
306310
return out as ResolvedId | null
307311
}
308312

313+
async load(
314+
options: {
315+
id: string
316+
resolveDependencies?: boolean
317+
} & Partial<PartialNull<ModuleOptions>>,
318+
): Promise<ModuleInfo> {
319+
// We may not have added this to our module graph yet, so ensure it exists
320+
await moduleGraph?.ensureEntryFromUrl(options.id)
321+
// Not all options passed to this function make sense in the context of loading individual files,
322+
// but we can at least update the module info properties we support
323+
updateModuleInfo(options.id, options)
324+
325+
await container.load(options.id, { ssr: this.ssr })
326+
const moduleInfo = this.getModuleInfo(options.id)
327+
// This shouldn't happen due to calling ensureEntryFromUrl, but 1) our types can't ensure that
328+
// and 2) moduleGraph may not have been provided (though in the situations where that happens,
329+
// we should never have plugins calling this.load)
330+
if (!moduleInfo)
331+
throw Error(`Failed to load module with id ${options.id}`)
332+
return moduleInfo
333+
}
334+
309335
getModuleInfo(id: string) {
310336
return getModuleInfo(id)
311337
}

0 commit comments

Comments
 (0)