Skip to content

Commit a93ab23

Browse files
committed
feat(plugin-vue): support for vite core new ssr impl
1 parent 7a15ada commit a93ab23

File tree

5 files changed

+54
-40
lines changed

5 files changed

+54
-40
lines changed

packages/plugin-vue/src/handleHotUpdate.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,11 @@ export async function handleHotUpdate({
5555
// metadata will not be available since the script part isn't loaded.
5656
// in this case, reuse the compiled script from previous descriptor.
5757
if (mainModule && !affectedModules.has(mainModule)) {
58-
setResolvedScript(descriptor, getResolvedScript(prevDescriptor)!)
58+
setResolvedScript(
59+
descriptor,
60+
getResolvedScript(prevDescriptor, false)!,
61+
false
62+
)
5963
}
6064
affectedModules.add(templateModule)
6165
needRerender = true

packages/plugin-vue/src/index.ts

+11-12
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export interface Options {
3737
include?: string | RegExp | (string | RegExp)[]
3838
exclude?: string | RegExp | (string | RegExp)[]
3939

40-
ssr?: boolean
4140
isProduction?: boolean
4241

4342
// options to pass on to @vue/compiler-sfc
@@ -53,7 +52,6 @@ export interface ResolvedOptions extends Options {
5352

5453
export default function vuePlugin(rawOptions: Options = {}): Plugin {
5554
let options: ResolvedOptions = {
56-
ssr: false,
5755
isProduction: process.env.NODE_ENV === 'production',
5856
...rawOptions,
5957
root: process.cwd()
@@ -75,11 +73,12 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
7573
},
7674

7775
config(config) {
78-
// provide default values for vue runtime esm defines
79-
config.define = {
80-
__VUE_OPTIONS_API__: true,
81-
__VUE_PROD_DEVTOOLS__: false,
82-
...config.define
76+
return {
77+
define: {
78+
__VUE_OPTIONS_API__: true,
79+
__VUE_PROD_DEVTOOLS__: false
80+
},
81+
ssrExternal: ['vue', '@vue/server-renderer']
8382
}
8483
},
8584

@@ -102,7 +101,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
102101
}
103102
},
104103

105-
load(id) {
104+
load(id, ssr = false) {
106105
const { filename, query } = parseVueRequest(id)
107106
// select corresponding block for subpart virtual modules
108107
if (query.vue) {
@@ -113,7 +112,7 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
113112
let block: SFCBlock | null | undefined
114113
if (query.type === 'script') {
115114
// handle <scrip> + <script setup> merge via compileScript()
116-
block = getResolvedScript(descriptor, options.ssr)
115+
block = getResolvedScript(descriptor, ssr)
117116
} else if (query.type === 'template') {
118117
block = descriptor.template!
119118
} else if (query.type === 'style') {
@@ -130,20 +129,20 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
130129
}
131130
},
132131

133-
transform(code, id) {
132+
transform(code, id, ssr = false) {
134133
const { filename, query } = parseVueRequest(id)
135134
if (!query.vue && !filter(filename)) {
136135
return
137136
}
138137

139138
if (!query.vue) {
140139
// main request
141-
return transformMain(code, filename, options, this)
140+
return transformMain(code, filename, options, this, ssr)
142141
} else {
143142
// sub block request
144143
const descriptor = getDescriptor(filename)!
145144
if (query.type === 'template') {
146-
return transformTemplateAsModule(code, descriptor, options, this)
145+
return transformTemplateAsModule(code, descriptor, options, this, ssr)
147146
} else if (query.type === 'style') {
148147
return transformStyle(
149148
code,

packages/plugin-vue/src/main.ts

+16-10
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ export async function transformMain(
1818
code: string,
1919
filename: string,
2020
options: ResolvedOptions,
21-
pluginContext: TransformPluginContext
21+
pluginContext: TransformPluginContext,
22+
ssr: boolean
2223
) {
23-
const { root, devServer, isProduction, ssr } = options
24+
const { root, devServer, isProduction } = options
2425

2526
// prev descriptor is only set and used for hmr
2627
const prevDescriptor = getPrevDescriptor(filename)
@@ -45,7 +46,8 @@ export async function transformMain(
4546
const { code: scriptCode, map } = await genScriptCode(
4647
descriptor,
4748
options,
48-
pluginContext
49+
pluginContext,
50+
ssr
4951
)
5052

5153
// template
@@ -64,7 +66,8 @@ export async function transformMain(
6466
;({ code: templateCode, map: templateMap } = await genTemplateCode(
6567
descriptor,
6668
options,
67-
pluginContext
69+
pluginContext,
70+
ssr
6871
))
6972
}
7073

@@ -99,7 +102,7 @@ export async function transformMain(
99102
output.push('export default _sfc_main')
100103

101104
// HMR
102-
if (devServer && !isProduction) {
105+
if (devServer && !ssr && !isProduction) {
103106
output.push(`_sfc_main.__hmrId = ${JSON.stringify(descriptor.id)}`)
104107
output.push(
105108
`__VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main)`
@@ -155,7 +158,8 @@ export async function transformMain(
155158
async function genTemplateCode(
156159
descriptor: SFCDescriptor,
157160
options: ResolvedOptions,
158-
pluginContext: PluginContext
161+
pluginContext: PluginContext,
162+
ssr: boolean
159163
) {
160164
const template = descriptor.template!
161165

@@ -167,7 +171,8 @@ async function genTemplateCode(
167171
template.content,
168172
descriptor,
169173
options,
170-
pluginContext
174+
pluginContext,
175+
ssr
171176
)
172177
} else {
173178
if (template.src) {
@@ -178,7 +183,7 @@ async function genTemplateCode(
178183
const attrsQuery = attrsToQuery(template.attrs, 'js', true)
179184
const query = `?vue&type=template${srcQuery}${attrsQuery}`
180185
const request = JSON.stringify(src + query)
181-
const renderFnName = options.ssr ? 'ssrRender' : 'render'
186+
const renderFnName = ssr ? 'ssrRender' : 'render'
182187
return {
183188
code: `import { ${renderFnName} as _sfc_${renderFnName} } from ${request}`,
184189
map: undefined
@@ -189,14 +194,15 @@ async function genTemplateCode(
189194
async function genScriptCode(
190195
descriptor: SFCDescriptor,
191196
options: ResolvedOptions,
192-
pluginContext: PluginContext
197+
pluginContext: PluginContext,
198+
ssr: boolean
193199
): Promise<{
194200
code: string
195201
map: RawSourceMap
196202
}> {
197203
let scriptCode = `const _sfc_main = {}`
198204
let map
199-
const script = resolveScript(descriptor, options)
205+
const script = resolveScript(descriptor, options, ssr)
200206
if (script) {
201207
// If the script is js/ts and has no external src, it can be directly placed
202208
// in the main module.

packages/plugin-vue/src/script.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,29 @@ const ssrCache = new WeakMap<SFCDescriptor, SFCScriptBlock | null>()
88

99
export function getResolvedScript(
1010
descriptor: SFCDescriptor,
11-
isServer = false
11+
ssr: boolean
1212
): SFCScriptBlock | null | undefined {
13-
return (isServer ? ssrCache : clientCache).get(descriptor)
13+
return (ssr ? ssrCache : clientCache).get(descriptor)
1414
}
1515

1616
export function setResolvedScript(
1717
descriptor: SFCDescriptor,
1818
script: SFCScriptBlock,
19-
isServer = false
19+
ssr: boolean
2020
) {
21-
;(isServer ? ssrCache : clientCache).set(descriptor, script)
21+
;(ssr ? ssrCache : clientCache).set(descriptor, script)
2222
}
2323

2424
export function resolveScript(
2525
descriptor: SFCDescriptor,
26-
options: ResolvedOptions
26+
options: ResolvedOptions,
27+
ssr: boolean
2728
) {
2829
if (!descriptor.script && !descriptor.scriptSetup) {
2930
return null
3031
}
3132

32-
const cacheToUse = options.ssr ? ssrCache : clientCache
33+
const cacheToUse = ssr ? ssrCache : clientCache
3334
const cached = cacheToUse.get(descriptor)
3435
if (cached) {
3536
return cached
@@ -42,7 +43,7 @@ export function resolveScript(
4243
id: descriptor.id,
4344
isProd: options.isProduction,
4445
inlineTemplate: !options.devServer,
45-
templateOptions: resolveTemplateCompilerOptions(descriptor, options)
46+
templateOptions: resolveTemplateCompilerOptions(descriptor, options, ssr)
4647
})
4748

4849
cacheToUse.set(descriptor, resolved)

packages/plugin-vue/src/template.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ export function transformTemplateAsModule(
1414
code: string,
1515
descriptor: SFCDescriptor,
1616
options: ResolvedOptions,
17-
pluginContext: TransformPluginContext
17+
pluginContext: TransformPluginContext,
18+
ssr: boolean
1819
) {
19-
const result = compile(code, descriptor, options, pluginContext)
20+
const result = compile(code, descriptor, options, pluginContext, ssr)
2021

2122
let returnCode = result.code
22-
if (options.devServer && !options.isProduction) {
23+
if (options.devServer && !ssr && !options.isProduction) {
2324
returnCode += `\nimport.meta.hot.accept(({ render }) => {
2425
__VUE_HMR_RUNTIME__.rerender(${JSON.stringify(descriptor.id)}, render)
2526
})`
@@ -38,9 +39,10 @@ export function transformTemplateInMain(
3839
code: string,
3940
descriptor: SFCDescriptor,
4041
options: ResolvedOptions,
41-
pluginContext: PluginContext
42+
pluginContext: PluginContext,
43+
ssr: boolean
4244
) {
43-
const result = compile(code, descriptor, options, pluginContext)
45+
const result = compile(code, descriptor, options, pluginContext, ssr)
4446
return {
4547
...result,
4648
code: result.code.replace(
@@ -54,11 +56,12 @@ export function compile(
5456
code: string,
5557
descriptor: SFCDescriptor,
5658
options: ResolvedOptions,
57-
pluginContext: PluginContext
59+
pluginContext: PluginContext,
60+
ssr: boolean
5861
) {
5962
const filename = descriptor.filename
6063
const result = compileTemplate({
61-
...resolveTemplateCompilerOptions(descriptor, options)!,
64+
...resolveTemplateCompilerOptions(descriptor, options, ssr)!,
6265
source: code
6366
})
6467

@@ -86,13 +89,14 @@ export function compile(
8689

8790
export function resolveTemplateCompilerOptions(
8891
descriptor: SFCDescriptor,
89-
options: ResolvedOptions
92+
options: ResolvedOptions,
93+
ssr: boolean
9094
): Omit<SFCTemplateCompileOptions, 'source'> | undefined {
9195
const block = descriptor.template
9296
if (!block) {
9397
return
9498
}
95-
const resolvedScript = getResolvedScript(descriptor, options.ssr)
99+
const resolvedScript = getResolvedScript(descriptor, ssr)
96100
const hasScoped = descriptor.styles.some((s) => s.scoped)
97101
const { id, filename, cssVars } = descriptor
98102

@@ -148,7 +152,7 @@ export function resolveTemplateCompilerOptions(
148152
scoped: hasScoped,
149153
isProd: options.isProduction,
150154
inMap: block.src ? undefined : block.map,
151-
ssr: options.ssr,
155+
ssr,
152156
ssrCssVars: cssVars,
153157
transformAssetUrls,
154158
preprocessLang: block.lang,

0 commit comments

Comments
 (0)