Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 49 additions & 2 deletions packages/vite/src/node/server/mixedModuleGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import type {
* We are going to deprecate these types and we can try to use them back in the future.
*/

// same default value of "moduleInfo.meta" as in Rollup
const EMPTY_OBJECT = Object.freeze({})

export class ModuleNode {
_moduleGraph: ModuleGraph
_clientModule: EnvironmentModuleNode | undefined
Expand Down Expand Up @@ -76,6 +79,48 @@ export class ModuleNode {
}
return importedModules
}
_getModuleInfoUnion(prop: 'info'): ModuleInfo | undefined {
const _clientValue = this._clientModule?.[prop]
const _ssrValue = this._ssrModule?.[prop]

if (_clientValue == null && _ssrValue == null) return undefined

return new Proxy({} as any, {
get: (_, key: string) => {
// `meta` refers to `ModuleInfo.meta` so we refer to `this.meta` to
// handle the object union between client and ssr
if (key === 'meta') {
return this.meta || EMPTY_OBJECT
}
if (_clientValue) {
if (key in _clientValue) {
return _clientValue[key as keyof ModuleInfo]
}
}
if (_ssrValue) {
if (key in _ssrValue) {
return _ssrValue[key as keyof ModuleInfo]
}
}
},
})
}
_getModuleObjectUnion(prop: 'meta'): Record<string, any> | undefined {
const _clientValue = this._clientModule?.[prop]
const _ssrValue = this._ssrModule?.[prop]

if (_clientValue == null && _ssrValue == null) return undefined

const info: Record<string, any> = {}
if (_ssrValue) {
Object.assign(info, _ssrValue)
}
if (_clientValue) {
Object.assign(info, _clientValue)
}
return info
}

get url(): string {
return this._get('url')
}
Expand All @@ -97,11 +142,13 @@ export class ModuleNode {
get type(): 'js' | 'css' {
return this._get('type')
}
// `info` needs special care as it's defined as a proxy in `pluginContainer`,
// so we also merge it as a proxy too
get info(): ModuleInfo | undefined {
return this._get('info')
return this._getModuleInfoUnion('info')
}
get meta(): Record<string, any> | undefined {
return this._get('meta')
return this._getModuleObjectUnion('meta')
}
get importers(): Set<ModuleNode> {
return this._getModuleSetUnion('importers')
Expand Down
43 changes: 35 additions & 8 deletions packages/vite/src/node/server/pluginContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -960,14 +960,41 @@ class PluginContainer {
}

getModuleInfo(id: string): ModuleInfo | null {
return (
(
this.environments.client as DevEnvironment
).pluginContainer.getModuleInfo(id) ||
(this.environments.ssr as DevEnvironment).pluginContainer.getModuleInfo(
id,
)
)
const clientModuleInfo = (
this.environments.client as DevEnvironment
).pluginContainer.getModuleInfo(id)
const ssrModuleInfo = (
this.environments.ssr as DevEnvironment
).pluginContainer.getModuleInfo(id)

if (clientModuleInfo == null && ssrModuleInfo == null) return null

return new Proxy({} as any, {
Comment on lines +963 to +972
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code here and below looks similar to the change in mixedModuleGraph. I initially also tried to refactor so we pass the mixed module graph to the plugin container so we can share the code, but it turns out a little fragile I think especially type-wise.

We also need to explicitly call the getModuleInfo here to trigger lazily creating module.info in EnvironmentPluginContainer.

get: (_, key: string) => {
// `meta` refers to `ModuleInfo.meta` of both environments, so we also
// need to merge it here
if (key === 'meta') {
const meta: Record<string, any> = {}
if (ssrModuleInfo) {
Object.assign(meta, ssrModuleInfo.meta)
}
if (clientModuleInfo) {
Object.assign(meta, clientModuleInfo.meta)
}
return meta
}
if (clientModuleInfo) {
if (key in clientModuleInfo) {
return clientModuleInfo[key as keyof ModuleInfo]
}
}
if (ssrModuleInfo) {
if (key in ssrModuleInfo) {
return ssrModuleInfo[key as keyof ModuleInfo]
}
}
},
})
}

get options(): InputOptions {
Expand Down