-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
/
ssrModuleLoader.ts
103 lines (90 loc) · 2.63 KB
/
ssrModuleLoader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import colors from 'picocolors'
import type { EvaluatedModuleNode } from 'vite/module-runner'
import { ESModulesEvaluator, ModuleRunner } from 'vite/module-runner'
import type { ViteDevServer } from '../server'
import { unwrapId } from '../../shared/utils'
import type { DevEnvironment } from '../server/environment'
import type { NormalizedServerHotChannel } from '../server/hmr'
import { ssrFixStacktrace } from './ssrStacktrace'
import { createServerModuleRunnerTransport } from './runtime/serverModuleRunner'
type SSRModule = Record<string, any>
export async function ssrLoadModule(
url: string,
server: ViteDevServer,
fixStacktrace?: boolean,
): Promise<SSRModule> {
const environment = server.environments.ssr
server._ssrCompatModuleRunner ||= new SSRCompatModuleRunner(environment)
url = unwrapId(url)
return instantiateModule(
url,
server._ssrCompatModuleRunner,
environment,
fixStacktrace,
)
}
async function instantiateModule(
url: string,
runner: ModuleRunner,
environment: DevEnvironment,
fixStacktrace?: boolean,
): Promise<SSRModule> {
const mod = await environment.moduleGraph.ensureEntryFromUrl(url)
if (mod.ssrError) {
throw mod.ssrError
}
try {
return await runner.import(url)
} catch (e: any) {
if (e.stack && fixStacktrace) {
ssrFixStacktrace(e, environment.moduleGraph)
}
environment.logger.error(
colors.red(`Error when evaluating SSR module ${url}:\n|- ${e.stack}\n`),
{
timestamp: true,
clear: environment.config.clearScreen,
error: e,
},
)
throw e
}
}
class SSRCompatModuleRunner extends ModuleRunner {
constructor(private environment: DevEnvironment) {
super(
{
root: environment.config.root,
transport: createServerModuleRunnerTransport({
channel: environment.hot as NormalizedServerHotChannel,
}),
sourcemapInterceptor: false,
hmr: false,
},
new ESModulesEvaluator(),
)
}
protected override async directRequest(
url: string,
mod: EvaluatedModuleNode,
callstack: string[],
): Promise<any> {
const id = mod.meta && 'id' in mod.meta && mod.meta.id
// serverId doesn't exist for external modules
if (!id) {
return super.directRequest(url, mod, callstack)
}
const viteMod = this.environment.moduleGraph.getModuleById(id)
if (!viteMod) {
return super.directRequest(id, mod, callstack)
}
try {
const exports = await super.directRequest(id, mod, callstack)
viteMod.ssrModule = exports
return exports
} catch (err) {
viteMod.ssrError = err
throw err
}
}
}