Skip to content

Commit

Permalink
feat: support rollup plugin this.load in plugin container context (#1…
Browse files Browse the repository at this point in the history
…1469)

Co-authored-by: 翠 / green <green@sapphi.red>
  • Loading branch information
luxaritas and sapphi-red authored Feb 23, 2023
1 parent cc3724f commit abfa804
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
38 changes: 38 additions & 0 deletions packages/vite/src/node/server/__tests__/pluginContainer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,44 @@ describe('plugin container', () => {
expect.assertions(2)
})
})

describe('load', () => {
beforeEach(() => {
moduleGraph = new ModuleGraph((id) => resolveId(id))
})

it('can resolve a secondary module', async () => {
const entryUrl = '/x.js'

const plugin: Plugin = {
name: 'p1',
resolveId(id) {
return id
},
load(id) {
if (id === entryUrl) return { code: '1', meta: { x: 1 } }
else return { code: '2', meta: { x: 2 } }
},
async transform(code, id) {
if (id === entryUrl)
return {
code: `${
(await this.load({ id: '/secondary.js' })).meta.x || undefined
}`,
}
return { code }
},
}

const container = await getPluginContainer({
plugins: [plugin],
})
await moduleGraph.ensureEntryFromUrl(entryUrl, false)
const loadResult: any = await container.load(entryUrl)
const result: any = await container.transform(loadResult.code, entryUrl)
expect(result.code).equals('2')
})
})
})

async function getPluginContainer(
Expand Down
30 changes: 28 additions & 2 deletions packages/vite/src/node/server/pluginContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,11 @@ import type {
LoadResult,
MinimalPluginContext,
ModuleInfo,
ModuleOptions,
NormalizedInputOptions,
OutputOptions,
ParallelPluginHooks,
PartialNull,
PartialResolvedId,
ResolvedId,
RollupError,
Expand Down Expand Up @@ -126,8 +128,6 @@ export interface PluginContainer {

type PluginContext = Omit<
RollupPluginContext,
// not supported
| 'load'
// not documented
| 'cache'
// deprecated
Expand Down Expand Up @@ -221,6 +221,10 @@ export async function createPluginContainer(
if (key in info) {
return info[key]
}
// Don't throw an error when returning from an async function
if (key === 'then') {
return undefined
}
throw Error(
`[vite] The "${key}" property of ModuleInfo is not supported.`,
)
Expand Down Expand Up @@ -306,6 +310,28 @@ export async function createPluginContainer(
return out as ResolvedId | null
}

async load(
options: {
id: string
resolveDependencies?: boolean
} & Partial<PartialNull<ModuleOptions>>,
): Promise<ModuleInfo> {
// We may not have added this to our module graph yet, so ensure it exists
await moduleGraph?.ensureEntryFromUrl(options.id)
// Not all options passed to this function make sense in the context of loading individual files,
// but we can at least update the module info properties we support
updateModuleInfo(options.id, options)

await container.load(options.id, { ssr: this.ssr })
const moduleInfo = this.getModuleInfo(options.id)
// This shouldn't happen due to calling ensureEntryFromUrl, but 1) our types can't ensure that
// and 2) moduleGraph may not have been provided (though in the situations where that happens,
// we should never have plugins calling this.load)
if (!moduleInfo)
throw Error(`Failed to load module with id ${options.id}`)
return moduleInfo
}

getModuleInfo(id: string) {
return getModuleInfo(id)
}
Expand Down

0 comments on commit abfa804

Please sign in to comment.