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
38 changes: 38 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1711,3 +1711,41 @@ describe('compileScript', () => {
expect(scriptAst).not.toBeDefined()
})
})

describe('vapor mode + ssr', () => {
test('rewrite defineVaporAsyncComponent import', () => {
const { content } = compile(
`
<script setup vapor>
import { defineVaporAsyncComponent } from 'vue'
</script>
`,
{
templateOptions: {
ssr: true,
},
},
)
expect(content).toContain(
`import { defineAsyncComponent as defineVaporAsyncComponent } from 'vue'`,
)
})

test('rewrite defineVaporAsyncComponent import with local name', () => {
const { content } = compile(
`
<script setup vapor>
import { defineVaporAsyncComponent as def } from 'vue'
</script>
`,
{
templateOptions: {
ssr: true,
},
},
)
expect(content).toContain(
`import { defineAsyncComponent as def } from 'vue'`,
)
})
})
17 changes: 17 additions & 0 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,23 @@ export function compileScript(
const local = specifier.local.name
const imported = getImportedName(specifier)
const source = node.source.value

// rewrite defineVaporAsyncComponent import to defineAsyncComponent
// in SSR + Vapor mode
if (
vapor &&
ssr &&
specifier.type === 'ImportSpecifier' &&
source === 'vue' &&
imported === 'defineVaporAsyncComponent'
) {
ctx.s.overwrite(
specifier.start! + startOffset,
specifier.end! + startOffset,
`defineAsyncComponent as ${local}`,
)
}

const existing = ctx.userImports[local]
if (source === 'vue' && MACROS.includes(imported)) {
if (local === imported) {
Expand Down
2 changes: 1 addition & 1 deletion packages/vue/src/index-with-vapor.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// for type generation only
export * from './indexBase'
export * from './index'
export * from '@vue/runtime-vapor'
109 changes: 107 additions & 2 deletions packages/vue/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,107 @@
export * from './indexBase'
export * from './vaporAliases'
// This entry is the "full-build" that includes both the runtime
// and the compiler, and supports on-the-fly compilation of the template option.
import { initDev } from './dev'
import {
type CompilerError,
type CompilerOptions,
compile,
} from '@vue/compiler-dom'
import {
type RenderFunction,
registerRuntimeCompiler,
warn,
} from '@vue/runtime-dom'
import * as runtimeDom from '@vue/runtime-dom'
import {
NOOP,
extend,
genCacheKey,
generateCodeFrame,
isString,
} from '@vue/shared'
import type { InternalRenderFunction } from 'packages/runtime-core/src/component'

if (__DEV__) {
initDev()
}

const compileCache: Record<string, RenderFunction> = Object.create(null)

function compileToFunction(
template: string | HTMLElement,
options?: CompilerOptions,
): RenderFunction {
if (!isString(template)) {
if (template.nodeType) {
template = template.innerHTML
} else {
__DEV__ && warn(`invalid template option: `, template)
return NOOP
}
}

const key = genCacheKey(template, options)
const cached = compileCache[key]
if (cached) {
return cached
}

if (template[0] === '#') {
const el = document.querySelector(template)
if (__DEV__ && !el) {
warn(`Template element not found or is empty: ${template}`)
}
// __UNSAFE__
// Reason: potential execution of JS expressions in in-DOM template.
// The user must make sure the in-DOM template is trusted. If it's rendered
// by the server, the template should not contain any user data.
template = el ? el.innerHTML : ``
}

const opts = extend(
{
hoistStatic: true,
onError: __DEV__ ? onError : undefined,
onWarn: __DEV__ ? e => onError(e, true) : NOOP,
} as CompilerOptions,
options,
)

if (!opts.isCustomElement && typeof customElements !== 'undefined') {
opts.isCustomElement = tag => !!customElements.get(tag)
}

const { code } = compile(template, opts)

function onError(err: CompilerError, asWarning = false) {
const message = asWarning
? err.message
: `Template compilation error: ${err.message}`
const codeFrame =
err.loc &&
generateCodeFrame(
template as string,
err.loc.start.offset,
err.loc.end.offset,
)
warn(codeFrame ? `${message}\n${codeFrame}` : message)
}

// The wildcard import results in a huge object with every export
// with keys that cannot be mangled, and can be quite heavy size-wise.
// In the global build we know `Vue` is available globally so we can avoid
// the wildcard object.
const render = (
__GLOBAL__ ? new Function(code)() : new Function('Vue', code)(runtimeDom)
) as RenderFunction

// mark the function as runtime compiled
;(render as InternalRenderFunction)._rc = true

return (compileCache[key] = render)
}

registerRuntimeCompiler(compileToFunction)

export { compileToFunction as compile }
export * from '@vue/runtime-dom'
107 changes: 0 additions & 107 deletions packages/vue/src/indexBase.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/vue/src/runtime-with-vapor.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './runtimeBase'
export * from './runtime'
export * from '@vue/runtime-vapor'
29 changes: 27 additions & 2 deletions packages/vue/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
export * from './runtimeBase'
export * from './vaporAliases'
// This entry exports the runtime only, and is built as
// `dist/vue.esm-bundler.js` which is used by default for bundlers.
import { NOOP } from '@vue/shared'
import { initDev } from './dev'
import { type RenderFunction, warn } from '@vue/runtime-dom'

if (__DEV__) {
initDev()
}

export * from '@vue/runtime-dom'

export const compile = (_template: string): RenderFunction => {
if (__DEV__) {
warn(
`Runtime compilation is not supported in this build of Vue.` +
(__ESM_BUNDLER__
? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
: __ESM_BROWSER__
? ` Use "vue.esm-browser.js" instead.`
: __GLOBAL__
? ` Use "vue.global.js" instead.`
: ``) /* should not happen */,
)
}
return NOOP
}
27 changes: 0 additions & 27 deletions packages/vue/src/runtimeBase.ts

This file was deleted.

7 changes: 0 additions & 7 deletions packages/vue/src/vaporAliases.ts

This file was deleted.

Loading