diff --git a/packages/compiler-core/src/transforms/vFor.ts b/packages/compiler-core/src/transforms/vFor.ts index 6e4f29ce0..c09a19f1e 100644 --- a/packages/compiler-core/src/transforms/vFor.ts +++ b/packages/compiler-core/src/transforms/vFor.ts @@ -16,7 +16,8 @@ import { createObjectProperty, ForCodegenNode, ElementCodegenNode, - SlotOutletCodegenNode + SlotOutletCodegenNode, + SlotOutletNode } from '../ast' import { createCompilerError, ErrorCodes } from '../errors' import { @@ -119,7 +120,7 @@ export const transformFor = createStructuralDirectiveTransform( : isTemplate && node.children.length === 1 && isSlotOutlet(node.children[0]) - ? node.children[0] + ? (node.children[0] as SlotOutletNode) // api-extractor somehow fails to infer this : null const keyProperty = keyProp ? createObjectProperty( diff --git a/packages/compiler-core/src/utils.ts b/packages/compiler-core/src/utils.ts index cb0b562cc..5b1a9ebc1 100644 --- a/packages/compiler-core/src/utils.ts +++ b/packages/compiler-core/src/utils.ts @@ -190,18 +190,23 @@ export function createBlockExpression( ]) } -export const isVSlot = (p: ElementNode['props'][0]): p is DirectiveNode => - p.type === NodeTypes.DIRECTIVE && p.name === 'slot' +export function isVSlot(p: ElementNode['props'][0]): p is DirectiveNode { + return p.type === NodeTypes.DIRECTIVE && p.name === 'slot' +} -export const isTemplateNode = ( +export function isTemplateNode( node: RootNode | TemplateChildNode -): node is TemplateNode => - node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.TEMPLATE +): node is TemplateNode { + return ( + node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.TEMPLATE + ) +} -export const isSlotOutlet = ( +export function isSlotOutlet( node: RootNode | TemplateChildNode -): node is SlotOutletNode => - node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.SLOT +): node is SlotOutletNode { + return node.type === NodeTypes.ELEMENT && node.tagType === ElementTypes.SLOT +} export function injectProp( node: ElementCodegenNode | ComponentCodegenNode | SlotOutletCodegenNode, diff --git a/packages/runtime-core/src/componentSlots.ts b/packages/runtime-core/src/componentSlots.ts index 8399bd352..52dd6f4f8 100644 --- a/packages/runtime-core/src/componentSlots.ts +++ b/packages/runtime-core/src/componentSlots.ts @@ -1,16 +1,10 @@ import { ComponentInternalInstance, currentInstance } from './component' -import { - VNode, - NormalizedChildren, - normalizeVNode, - VNodeChild, - VNodeChildren -} from './vnode' +import { VNode, NormalizedChildren, normalizeVNode, VNodeChild } from './vnode' import { isArray, isFunction } from '@vue/shared' import { ShapeFlags } from './shapeFlags' import { warn } from './warning' -export type Slot = (...args: any[]) => VNodeChildren +export type Slot = (...args: any[]) => VNode[] export type InternalSlots = { [name: string]: Slot diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 202e0a95c..959db695d 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -30,7 +30,7 @@ export { PublicPatchFlags as PatchFlags } from '@vue/shared' export { getCurrentInstance } from './component' // For custom renderers -export { createRenderer } from './createRenderer' +export { createRenderer, RootRenderFunction } from './createRenderer' export { warn } from './warning' export { handleError, diff --git a/packages/runtime-core/src/keepAlive.ts b/packages/runtime-core/src/keepAlive.ts index bdbff8a80..a1484af9f 100644 --- a/packages/runtime-core/src/keepAlive.ts +++ b/packages/runtime-core/src/keepAlive.ts @@ -135,7 +135,7 @@ export const KeepAlive = { return () => { if (!slots.default) { - return + return null } const children = slots.default() diff --git a/packages/runtime-core/src/vnode.ts b/packages/runtime-core/src/vnode.ts index fdb6443de..08407429e 100644 --- a/packages/runtime-core/src/vnode.ts +++ b/packages/runtime-core/src/vnode.ts @@ -25,9 +25,12 @@ export const Portal = Symbol(__DEV__ ? 'Portal' : undefined) export const Text = Symbol(__DEV__ ? 'Text' : undefined) export const Comment = Symbol(__DEV__ ? 'Comment' : undefined) -const Suspense = (__FEATURE_SUSPENSE__ - ? SuspenseImpl - : null) as typeof SuspenseImpl +// Export as {} to avoid circular type dependency between `suspense.ts` and +// `createRenderer.ts` in exported types. +// A circular type dependency causes tsc to generate d.ts with dynmaic import() +// calls using realtive paths, which works for separate d.ts files, but will +// fail after d.ts rollup with API Extractor. +const Suspense = (__FEATURE_SUSPENSE__ ? SuspenseImpl : null) as {} export { Suspense } export type VNodeTypes = diff --git a/packages/runtime-dom/package.json b/packages/runtime-dom/package.json index 8aaa39c80..948f2d550 100644 --- a/packages/runtime-dom/package.json +++ b/packages/runtime-dom/package.json @@ -13,7 +13,8 @@ "sideEffects": false, "buildOptions": { "name": "VueDOMRuntime", - "formats": ["esm", "cjs", "global", "esm-browser"] + "formats": ["esm", "cjs", "global", "esm-browser"], + "dts": ["jsx.d.ts"] }, "repository": { "type": "git", diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 7550cc6c2..3c66e9477 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -1,16 +1,24 @@ -import { createRenderer, warn } from '@vue/runtime-core' +import { + createRenderer, + warn, + App, + RootRenderFunction +} from '@vue/runtime-core' import { nodeOps } from './nodeOps' import { patchProp } from './patchProp' // Importing from the compiler, will be tree-shaken in prod import { isHTMLTag, isSVGTag } from '@vue/compiler-dom' import { isFunction, isString } from '@vue/shared' -const { render, createApp: baseCreateApp } = createRenderer({ +const { render: baseRender, createApp: baseCreateApp } = createRenderer({ patchProp, ...nodeOps }) -const createApp = () => { +// use explicit type casts here to avoid import() calls in rolled-up d.ts +export const render = baseRender as RootRenderFunction + +export const createApp = (): App => { const app = baseCreateApp() if (__DEV__) { @@ -48,8 +56,6 @@ const createApp = () => { return app } -export { render, createApp } - // DOM-only runtime helpers export { vModelText, diff --git a/scripts/build.js b/scripts/build.js index fbf1c9388..a224c3094 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -27,6 +27,7 @@ const targets = args._ const formats = args.formats || args.f const devOnly = args.devOnly || args.d const prodOnly = !devOnly && (args.prodOnly || args.p) +const buildTypes = args.t || args.types const buildAllMatching = args.all || args.a const lean = args.lean || args.l const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) @@ -68,7 +69,7 @@ async function build(target) { `NODE_ENV:${env}`, `TARGET:${target}`, formats ? `FORMATS:${formats}` : ``, - args.types ? `TYPES:true` : ``, + buildTypes ? `TYPES:true` : ``, prodOnly ? `PROD_ONLY:true` : ``, lean ? `LEAN:true` : `` ] @@ -78,7 +79,7 @@ async function build(target) { { stdio: 'inherit' } ) - if (args.types && pkg.types) { + if (buildTypes && pkg.types) { console.log() console.log( chalk.bold(chalk.yellow(`Rolling up type definitions for ${target}...`)) @@ -97,6 +98,17 @@ async function build(target) { }) if (result.succeeded) { + // concat additional d.ts to rolled-up dts (mostly for JSX) + if (pkg.buildOptions.dts) { + const dtsPath = path.resolve(pkgDir, pkg.types) + const existing = await fs.readFile(dtsPath, 'utf-8') + const toAdd = await Promise.all( + pkg.buildOptions.dts.map(file => { + return fs.readFile(path.resolve(pkgDir, file), 'utf-8') + }) + ) + await fs.writeFile(dtsPath, existing + '\n' + toAdd.join('\n')) + } console.log( chalk.bold(chalk.green(`API Extractor completed successfully.`)) )