wip(ssr): render real components
This commit is contained in:
parent
da25517377
commit
cee36ad028
@ -7,6 +7,7 @@ module.exports = {
|
||||
__BROWSER__: false,
|
||||
__BUNDLER__: true,
|
||||
__RUNTIME_COMPILE__: true,
|
||||
__SSR__: false,
|
||||
__FEATURE_OPTIONS__: true,
|
||||
__FEATURE_SUSPENSE__: true
|
||||
},
|
||||
|
1
packages/global.d.ts
vendored
1
packages/global.d.ts
vendored
@ -4,6 +4,7 @@ declare var __TEST__: boolean
|
||||
declare var __BROWSER__: boolean
|
||||
declare var __BUNDLER__: boolean
|
||||
declare var __RUNTIME_COMPILE__: boolean
|
||||
declare var __SSR__: boolean
|
||||
declare var __COMMIT__: string
|
||||
declare var __VERSION__: string
|
||||
|
||||
|
@ -5,8 +5,8 @@ import {
|
||||
ComponentPublicInstance,
|
||||
runtimeCompiledRenderProxyHandlers
|
||||
} from './componentProxy'
|
||||
import { ComponentPropsOptions } from './componentProps'
|
||||
import { Slots } from './componentSlots'
|
||||
import { ComponentPropsOptions, resolveProps } from './componentProps'
|
||||
import { Slots, resolveSlots } from './componentSlots'
|
||||
import { warn } from './warning'
|
||||
import {
|
||||
ErrorCodes,
|
||||
@ -34,6 +34,7 @@ import {
|
||||
currentRenderingInstance,
|
||||
markAttrsAccessed
|
||||
} from './componentRenderUtils'
|
||||
import { ShapeFlags } from '.'
|
||||
|
||||
export type Data = { [key: string]: unknown }
|
||||
|
||||
@ -268,10 +269,26 @@ export function validateComponentName(name: string, config: AppConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
export function setupStatefulComponent(
|
||||
export function setupComponent(
|
||||
instance: ComponentInternalInstance,
|
||||
parentSuspense: SuspenseBoundary | null
|
||||
) {
|
||||
const propsOptions = instance.type.props
|
||||
const { props, children, shapeFlag } = instance.vnode
|
||||
resolveProps(instance, props, propsOptions)
|
||||
resolveSlots(instance, children)
|
||||
|
||||
// setup stateful logic
|
||||
if (shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
|
||||
return setupStatefulComponent(instance, parentSuspense)
|
||||
}
|
||||
}
|
||||
|
||||
function setupStatefulComponent(
|
||||
instance: ComponentInternalInstance,
|
||||
parentSuspense: SuspenseBoundary | null
|
||||
) {
|
||||
let setupResult
|
||||
const Component = instance.type as ComponentOptions
|
||||
|
||||
if (__DEV__) {
|
||||
@ -307,7 +324,7 @@ export function setupStatefulComponent(
|
||||
|
||||
currentInstance = instance
|
||||
currentSuspense = parentSuspense
|
||||
const setupResult = callWithErrorHandling(
|
||||
setupResult = callWithErrorHandling(
|
||||
setup,
|
||||
instance,
|
||||
ErrorCodes.SETUP_FUNCTION,
|
||||
@ -333,6 +350,8 @@ export function setupStatefulComponent(
|
||||
} else {
|
||||
finishComponentSetup(instance, parentSuspense)
|
||||
}
|
||||
|
||||
return setupResult
|
||||
}
|
||||
|
||||
export function handleSetupResult(
|
||||
@ -398,7 +417,7 @@ function finishComponentSetup(
|
||||
`does not support runtime template compilation. Either use the ` +
|
||||
`full build or pre-compile the template using Vue CLI.`
|
||||
)
|
||||
} else {
|
||||
} else if (!__SSR__ || !Component.ssrRender) {
|
||||
warn(
|
||||
`Component is missing${
|
||||
__RUNTIME_COMPILE__ ? ` template or` : ``
|
||||
|
@ -97,6 +97,9 @@ export const camelize = _camelize as (s: string) => string
|
||||
// For integration with runtime compiler
|
||||
export { registerRuntimeCompiler } from './component'
|
||||
|
||||
// For server-renderer
|
||||
export { createComponentInstance, setupComponent } from './component'
|
||||
|
||||
// Types -----------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
|
@ -13,9 +13,9 @@ import {
|
||||
import {
|
||||
ComponentInternalInstance,
|
||||
createComponentInstance,
|
||||
setupStatefulComponent,
|
||||
Component,
|
||||
Data
|
||||
Data,
|
||||
setupComponent
|
||||
} from './component'
|
||||
import {
|
||||
renderComponentRoot,
|
||||
@ -940,8 +940,6 @@ export function createRenderer<
|
||||
pushWarningContext(initialVNode)
|
||||
}
|
||||
|
||||
const Comp = initialVNode.type as Component
|
||||
|
||||
// inject renderer internals for keepAlive
|
||||
if (isKeepAlive(initialVNode)) {
|
||||
const sink = instance.sink as KeepAliveSink
|
||||
@ -950,14 +948,7 @@ export function createRenderer<
|
||||
}
|
||||
|
||||
// resolve props and slots for setup context
|
||||
const propsOptions = Comp.props
|
||||
resolveProps(instance, initialVNode.props, propsOptions)
|
||||
resolveSlots(instance, initialVNode.children)
|
||||
|
||||
// setup stateful logic
|
||||
if (initialVNode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
|
||||
setupStatefulComponent(instance, parentSuspense)
|
||||
}
|
||||
setupComponent(instance, parentSuspense)
|
||||
|
||||
// setup() is async. This component relies on async logic to be resolved
|
||||
// before proceeding
|
||||
|
@ -27,6 +27,6 @@
|
||||
},
|
||||
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/server-renderer#readme",
|
||||
"peerDependencies": {
|
||||
"@vue/runtime-dom": "3.0.0-alpha.3"
|
||||
"vue": "3.0.0-alpha.3"
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,11 @@ import {
|
||||
App,
|
||||
Component,
|
||||
ComponentInternalInstance,
|
||||
SuspenseBoundary
|
||||
} from '@vue/runtime-dom'
|
||||
createComponentInstance,
|
||||
setupComponent,
|
||||
VNode,
|
||||
createVNode
|
||||
} from 'vue'
|
||||
import { isString } from '@vue/shared'
|
||||
|
||||
type SSRBuffer = SSRBufferItem[]
|
||||
@ -30,9 +33,7 @@ function createSSRBuffer() {
|
||||
export async function renderToString(app: App): Promise<string> {
|
||||
const resolvedBuffer = (await renderComponent(
|
||||
app._component,
|
||||
app._props,
|
||||
null,
|
||||
null
|
||||
app._props
|
||||
)) as ResolvedSSRBuffer
|
||||
return unrollBuffer(resolvedBuffer)
|
||||
}
|
||||
@ -52,19 +53,17 @@ function unrollBuffer(buffer: ResolvedSSRBuffer): string {
|
||||
|
||||
export async function renderComponent(
|
||||
comp: Component,
|
||||
props: Record<string, any> | null,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
parentSuspense: SuspenseBoundary | null
|
||||
props: Record<string, any> | null = null,
|
||||
children: VNode['children'] = null,
|
||||
parentComponent: ComponentInternalInstance | null = null
|
||||
): Promise<SSRBuffer> {
|
||||
// 1. create component buffer
|
||||
const { buffer, push } = createSSRBuffer()
|
||||
|
||||
// 2. TODO create actual instance
|
||||
const instance = {
|
||||
proxy: {
|
||||
msg: 'hello'
|
||||
}
|
||||
}
|
||||
// 2. create actual instance
|
||||
const vnode = createVNode(comp, props, children)
|
||||
const instance = createComponentInstance(vnode, parentComponent)
|
||||
await setupComponent(instance, null)
|
||||
|
||||
if (typeof comp === 'function') {
|
||||
// TODO FunctionalComponent
|
||||
|
@ -79,6 +79,7 @@ function createConfig(format, output, plugins = []) {
|
||||
process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
|
||||
const isGlobalBuild = format === 'global'
|
||||
const isRawESMBuild = format === 'esm'
|
||||
const isNodeBuild = format === 'cjs'
|
||||
const isBundlerESMBuild = /esm-bundler/.test(format)
|
||||
const isRuntimeCompileBuild = /vue\./.test(output.file)
|
||||
|
||||
@ -111,14 +112,16 @@ function createConfig(format, output, plugins = []) {
|
||||
const entryFile =
|
||||
format === 'esm-bundler-runtime' ? `src/runtime.ts` : `src/index.ts`
|
||||
|
||||
const external =
|
||||
isGlobalBuild || isRawESMBuild
|
||||
? []
|
||||
: knownExternals.concat(Object.keys(pkg.dependencies || []))
|
||||
|
||||
return {
|
||||
input: resolve(entryFile),
|
||||
// Global and Browser ESM builds inlines everything so that they can be
|
||||
// used alone.
|
||||
external:
|
||||
isGlobalBuild || isRawESMBuild
|
||||
? []
|
||||
: knownExternals.concat(Object.keys(pkg.dependencies || [])),
|
||||
external,
|
||||
plugins: [
|
||||
json({
|
||||
namedExports: false
|
||||
@ -127,9 +130,11 @@ function createConfig(format, output, plugins = []) {
|
||||
createReplacePlugin(
|
||||
isProductionBuild,
|
||||
isBundlerESMBuild,
|
||||
// isBrowserBuild?
|
||||
(isGlobalBuild || isRawESMBuild || isBundlerESMBuild) &&
|
||||
!packageOptions.enableNonBrowserBranches,
|
||||
isRuntimeCompileBuild
|
||||
isRuntimeCompileBuild,
|
||||
isNodeBuild
|
||||
),
|
||||
...plugins
|
||||
],
|
||||
@ -146,7 +151,8 @@ function createReplacePlugin(
|
||||
isProduction,
|
||||
isBundlerESMBuild,
|
||||
isBrowserBuild,
|
||||
isRuntimeCompileBuild
|
||||
isRuntimeCompileBuild,
|
||||
isNodeBuild
|
||||
) {
|
||||
const replacements = {
|
||||
__COMMIT__: `"${process.env.COMMIT}"`,
|
||||
@ -164,6 +170,8 @@ function createReplacePlugin(
|
||||
__BUNDLER__: isBundlerESMBuild,
|
||||
// support compile in browser?
|
||||
__RUNTIME_COMPILE__: isRuntimeCompileBuild,
|
||||
// is targeting Node (SSR)?
|
||||
__SSR__: isNodeBuild,
|
||||
// support options?
|
||||
// the lean build drops options related code with buildOptions.lean: true
|
||||
__FEATURE_OPTIONS__: !packageOptions.lean && !process.env.LEAN,
|
||||
|
Loading…
Reference in New Issue
Block a user