diff --git a/package.json b/package.json index 99bbce748..5b5cc49bc 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "@babel/types": "^7.12.0", "@esbuild-plugins/node-modules-polyfill": "^0.1.4", "@microsoft/api-extractor": "~7.20.0", + "@rollup/plugin-alias": "^4.0.3", "@rollup/plugin-commonjs": "^23.0.2", "@rollup/plugin-json": "^5.0.1", "@rollup/plugin-node-resolve": "^15.0.1", @@ -88,6 +89,7 @@ "pug": "^3.0.1", "puppeteer": "^19.2.2", "rollup": "~3.10.0", + "rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-node-builtins": "^2.1.2", "rollup-plugin-node-globals": "^1.4.0", "rollup-plugin-polyfill-node": "^0.11.0", diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index 6a1f8b63b..4898a181d 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -2,31 +2,31 @@ export { baseCompile } from './compile' // Also expose lower level APIs & types export { - CompilerOptions, - ParserOptions, - TransformOptions, - CodegenOptions, - HoistTransform, - BindingMetadata, + type CompilerOptions, + type ParserOptions, + type TransformOptions, + type CodegenOptions, + type HoistTransform, + type BindingMetadata, BindingTypes } from './options' export { baseParse, TextModes } from './parse' export { transform, - TransformContext, + type TransformContext, createTransformContext, traverseNode, createStructuralDirectiveTransform, - NodeTransform, - StructuralDirectiveTransform, - DirectiveTransform + type NodeTransform, + type StructuralDirectiveTransform, + type DirectiveTransform } from './transform' -export { generate, CodegenContext, CodegenResult } from './codegen' +export { generate, type CodegenContext, type CodegenResult } from './codegen' export { ErrorCodes, - CoreCompilerError, - CompilerError, - createCompilerError + createCompilerError, + type CoreCompilerError, + type CompilerError } from './errors' export * from './ast' @@ -34,7 +34,7 @@ export * from './utils' export * from './babelUtils' export * from './runtimeHelpers' -export { getBaseTransformPreset, TransformPreset } from './compile' +export { getBaseTransformPreset, type TransformPreset } from './compile' export { transformModel } from './transforms/vModel' export { transformOn } from './transforms/vOn' export { transformBind } from './transforms/vBind' @@ -48,7 +48,7 @@ export { } from './transforms/transformExpression' export { buildSlots, - SlotFnBuilder, + type SlotFnBuilder, trackVForSlotScopes, trackSlotScopes } from './transforms/vSlot' @@ -57,7 +57,7 @@ export { resolveComponentType, buildProps, buildDirectiveArgs, - PropsExpression + type PropsExpression } from './transforms/transformElement' export { processSlotOutlet } from './transforms/transformSlotOutlet' export { getConstantType } from './transforms/hoistStatic' diff --git a/packages/compiler-sfc/src/index.ts b/packages/compiler-sfc/src/index.ts index b99aeafbb..c56b12662 100644 --- a/packages/compiler-sfc/src/index.ts +++ b/packages/compiler-sfc/src/index.ts @@ -27,7 +27,7 @@ export { } from '@vue/compiler-core' // Types -export { +export type { SFCParseOptions, SFCParseResult, SFCDescriptor, @@ -36,19 +36,22 @@ export { SFCScriptBlock, SFCStyleBlock } from './parse' -export { +export type { TemplateCompiler, SFCTemplateCompileOptions, SFCTemplateCompileResults } from './compileTemplate' -export { +export type { SFCStyleCompileOptions, SFCAsyncStyleCompileOptions, SFCStyleCompileResults } from './compileStyle' -export { SFCScriptCompileOptions } from './compileScript' -export { AssetURLOptions, AssetURLTagConfig } from './templateTransformAssetUrl' -export { +export type { SFCScriptCompileOptions } from './compileScript' +export type { + AssetURLOptions, + AssetURLTagConfig +} from './templateTransformAssetUrl' +export type { CompilerOptions, CompilerError, BindingMetadata diff --git a/packages/reactivity/src/index.ts b/packages/reactivity/src/index.ts index 5c65cd52a..cbba32d31 100644 --- a/packages/reactivity/src/index.ts +++ b/packages/reactivity/src/index.ts @@ -8,14 +8,14 @@ export { proxyRefs, customRef, triggerRef, - Ref, - ToRef, - ToRefs, - UnwrapRef, - ShallowRef, - ShallowUnwrapRef, - RefUnwrapBailTypes, - CustomRefFactory + type Ref, + type ToRef, + type ToRefs, + type UnwrapRef, + type ShallowRef, + type ShallowUnwrapRef, + type RefUnwrapBailTypes, + type CustomRefFactory } from './ref' export { reactive, @@ -28,19 +28,19 @@ export { shallowReadonly, markRaw, toRaw, - Raw, ReactiveFlags, - DeepReadonly, - ShallowReactive, - UnwrapNestedRefs + type Raw, + type DeepReadonly, + type ShallowReactive, + type UnwrapNestedRefs } from './reactive' export { computed, - ComputedRef, - WritableComputedRef, - WritableComputedOptions, - ComputedGetter, - ComputedSetter + type ComputedRef, + type WritableComputedRef, + type WritableComputedOptions, + type ComputedGetter, + type ComputedSetter } from './computed' export { deferredComputed } from './deferredComputed' export { @@ -53,12 +53,12 @@ export { resetTracking, ITERATE_KEY, ReactiveEffect, - ReactiveEffectRunner, - ReactiveEffectOptions, - EffectScheduler, - DebuggerOptions, - DebuggerEvent, - DebuggerEventExtraInfo + type ReactiveEffectRunner, + type ReactiveEffectOptions, + type EffectScheduler, + type DebuggerOptions, + type DebuggerEvent, + type DebuggerEventExtraInfo } from './effect' export { effectScope, diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index b04ae6e51..768a47d9b 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -162,7 +162,7 @@ export type Component< | ConcreteComponent | ComponentPublicInstanceConstructor -export { ComponentOptions } +export type { ComponentOptions } type LifecycleHook = TFn[] | null diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 3101ed06c..fd3415e33 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -86,11 +86,11 @@ export { h } from './h' // Advanced render function utilities export { createVNode, cloneVNode, mergeProps, isVNode } from './vnode' // VNode types -export { Fragment, Text, Comment, Static, VNodeRef } from './vnode' +export { Fragment, Text, Comment, Static, type VNodeRef } from './vnode' // Built-in components -export { Teleport, TeleportProps } from './components/Teleport' -export { Suspense, SuspenseProps } from './components/Suspense' -export { KeepAlive, KeepAliveProps } from './components/KeepAlive' +export { Teleport, type TeleportProps } from './components/Teleport' +export { Suspense, type SuspenseProps } from './components/Suspense' +export { KeepAlive, type KeepAliveProps } from './components/KeepAlive' export { BaseTransition, BaseTransitionPropsValidators, @@ -148,8 +148,8 @@ declare module '@vue/reactivity' { } } } - -export { +export { TrackOpTypes, TriggerOpTypes } from '@vue/reactivity' +export type { Ref, ToRef, ToRefs, @@ -172,11 +172,9 @@ export { DebuggerOptions, DebuggerEvent, DebuggerEventExtraInfo, - TrackOpTypes, - TriggerOpTypes, Raw } from '@vue/reactivity' -export { +export type { WatchEffect, WatchOptions, WatchOptionsBase, @@ -184,8 +182,8 @@ export { WatchSource, WatchStopHandle } from './apiWatch' -export { InjectionKey } from './apiInject' -export { +export type { InjectionKey } from './apiInject' +export type { App, AppConfig, AppContext, @@ -193,7 +191,7 @@ export { CreateAppFunction, OptionMergeFunction } from './apiCreateApp' -export { +export type { VNode, VNodeChild, VNodeTypes, @@ -201,7 +199,7 @@ export { VNodeArrayChildren, VNodeNormalizedChildren } from './vnode' -export { +export type { Component, ConcreteComponent, FunctionalComponent, @@ -210,8 +208,8 @@ export { ComponentCustomProps, AllowedComponentProps } from './component' -export { DefineComponent } from './apiDefineComponent' -export { +export type { DefineComponent } from './apiDefineComponent' +export type { ComponentOptions, ComponentOptionsMixin, ComponentOptionsWithoutProps, @@ -226,13 +224,13 @@ export { RuntimeCompilerOptions, ComponentInjectOptions } from './componentOptions' -export { EmitsOptions, ObjectEmitsOptions } from './componentEmits' -export { +export type { EmitsOptions, ObjectEmitsOptions } from './componentEmits' +export type { ComponentPublicInstance, ComponentCustomProperties, CreateComponentPublicInstance } from './componentPublicInstance' -export { +export type { Renderer, RendererNode, RendererElement, @@ -240,9 +238,9 @@ export { RendererOptions, RootRenderFunction } from './renderer' -export { RootHydrateFunction } from './hydration' -export { Slot, Slots } from './componentSlots' -export { +export type { RootHydrateFunction } from './hydration' +export type { Slot, Slots } from './componentSlots' +export type { Prop, PropType, ComponentPropsOptions, @@ -250,7 +248,7 @@ export { ExtractPropTypes, ExtractDefaultPropTypes } from './componentProps' -export { +export type { Directive, DirectiveBinding, DirectiveHook, @@ -258,13 +256,16 @@ export { FunctionDirective, DirectiveArguments } from './directives' -export { SuspenseBoundary } from './components/Suspense' -export { TransitionState, TransitionHooks } from './components/BaseTransition' -export { +export type { SuspenseBoundary } from './components/Suspense' +export type { + TransitionState, + TransitionHooks +} from './components/BaseTransition' +export type { AsyncComponentOptions, AsyncComponentLoader } from './apiAsyncComponent' -export { HMRRuntime } from './hmr' +export type { HMRRuntime } from './hmr' // Internal API ---------------------------------------------------------------- @@ -336,8 +337,8 @@ export const ssrUtils = (__SSR__ ? _ssrUtils : null) as typeof _ssrUtils // 2.x COMPAT ------------------------------------------------------------------ export { DeprecationTypes } from './compat/compatConfig' -export { CompatVue } from './compat/global' -export { LegacyConfig } from './compat/globalConfig' +export type { CompatVue } from './compat/global' +export type { LegacyConfig } from './compat/globalConfig' import { warnDeprecation } from './compat/compatConfig' import { createCompatVue } from './compat/global' diff --git a/packages/runtime-dom/src/index.ts b/packages/runtime-dom/src/index.ts index 405acc089..a980f1dd6 100644 --- a/packages/runtime-dom/src/index.ts +++ b/packages/runtime-dom/src/index.ts @@ -207,7 +207,7 @@ export { defineCustomElement, defineSSRCustomElement, VueElement, - VueElementConstructor + type VueElementConstructor } from './apiCustomElement' // SFC CSS utilities @@ -215,10 +215,10 @@ export { useCssModule } from './helpers/useCssModule' export { useCssVars } from './helpers/useCssVars' // DOM-only components -export { Transition, TransitionProps } from './components/Transition' +export { Transition, type TransitionProps } from './components/Transition' export { TransitionGroup, - TransitionGroupProps + type TransitionGroupProps } from './components/TransitionGroup' // **Internal** DOM-only runtime directive helpers diff --git a/packages/runtime-dom/src/modules/events.ts b/packages/runtime-dom/src/modules/events.ts index 8dbccadef..272cededc 100644 --- a/packages/runtime-dom/src/modules/events.ts +++ b/packages/runtime-dom/src/modules/events.ts @@ -1,9 +1,9 @@ import { hyphenate, isArray } from '@vue/shared' import { + ErrorCodes, ComponentInternalInstance, callWithAsyncErrorHandling } from '@vue/runtime-core' -import { ErrorCodes } from 'packages/runtime-core/src/errorHandling' interface Invoker extends EventListener { value: EventValue diff --git a/packages/server-renderer/src/index.ts b/packages/server-renderer/src/index.ts index 81946fac8..1e453c913 100644 --- a/packages/server-renderer/src/index.ts +++ b/packages/server-renderer/src/index.ts @@ -2,7 +2,7 @@ import { initDirectivesForSSR } from 'vue' initDirectivesForSSR() // public -export { SSRContext } from './render' +export type { SSRContext } from './render' export { renderToString } from './renderToString' export { renderToSimpleStream, @@ -10,7 +10,7 @@ export { pipeToNodeWritable, renderToWebStream, pipeToWebWritable, - SimpleReadable, + type SimpleReadable, // deprecated renderToStream } from './renderToStream' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6df7b8778..26d700396 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ importers: '@babel/types': ^7.12.0 '@esbuild-plugins/node-modules-polyfill': ^0.1.4 '@microsoft/api-extractor': ~7.20.0 + '@rollup/plugin-alias': ^4.0.3 '@rollup/plugin-commonjs': ^23.0.2 '@rollup/plugin-json': ^5.0.1 '@rollup/plugin-node-resolve': ^15.0.1 @@ -39,6 +40,7 @@ importers: pug: ^3.0.1 puppeteer: ^19.2.2 rollup: ~3.10.0 + rollup-plugin-esbuild: ^5.0.0 rollup-plugin-node-builtins: ^2.1.2 rollup-plugin-node-globals: ^1.4.0 rollup-plugin-polyfill-node: ^0.11.0 @@ -57,6 +59,7 @@ importers: '@babel/types': 7.16.0 '@esbuild-plugins/node-modules-polyfill': 0.1.4_esbuild@0.17.4 '@microsoft/api-extractor': 7.20.1 + '@rollup/plugin-alias': 4.0.3_rollup@3.10.0 '@rollup/plugin-commonjs': 23.0.2_rollup@3.10.0 '@rollup/plugin-json': 5.0.1_rollup@3.10.0 '@rollup/plugin-node-resolve': 15.0.1_rollup@3.10.0 @@ -89,6 +92,7 @@ importers: pug: 3.0.2 puppeteer: 19.2.2 rollup: 3.10.0 + rollup-plugin-esbuild: 5.0.0_ejjt5bxqy7rglzzuwkobwucgry rollup-plugin-node-builtins: 2.1.2 rollup-plugin-node-globals: 1.4.0 rollup-plugin-polyfill-node: 0.11.0_rollup@3.10.0 @@ -337,7 +341,7 @@ packages: '@babel/traverse': 7.16.3 '@babel/types': 7.16.0 convert-source-map: 1.8.0 - debug: 4.3.3 + debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.0 semver: 6.3.0 @@ -524,7 +528,7 @@ packages: '@babel/helper-split-export-declaration': 7.16.0 '@babel/parser': 7.16.4 '@babel/types': 7.16.0 - debug: 4.3.3 + debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -1082,6 +1086,19 @@ packages: fastq: 1.13.0 dev: true + /@rollup/plugin-alias/4.0.3_rollup@3.10.0: + resolution: {integrity: sha512-ZuDWE1q4PQDhvm/zc5Prun8sBpLJy41DMptYrS6MhAy9s9kL/doN1613BWfEchGVfKxzliJ3BjbOPizXX38DbQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + rollup: 3.10.0 + slash: 4.0.0 + dev: true + /@rollup/plugin-commonjs/23.0.2_rollup@3.10.0: resolution: {integrity: sha512-e9ThuiRf93YlVxc4qNIurvv+Hp9dnD+4PjOqQs5vAYfcZ3+AXSrcdzXnVjWxcGQOa6KGJFcRZyUI3ktWLavFjg==} engines: {node: '>=14.0.0'} @@ -2750,6 +2767,10 @@ packages: unbox-primitive: 1.0.1 dev: true + /es-module-lexer/1.1.0: + resolution: {integrity: sha512-fJg+1tiyEeS8figV+fPcPpm8WqJEflG3yPU0NOm5xMvrNkuiy7HzX/Ljng4Y0hAoiw4/3hQTCFYw+ub8+a2pRA==} + dev: true + /es-to-primitive/1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} @@ -3933,6 +3954,11 @@ packages: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} dev: true + /joycon/3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + /js-stringify/1.0.2: resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} dev: true @@ -5490,6 +5516,24 @@ packages: inherits: 2.0.4 dev: true + /rollup-plugin-esbuild/5.0.0_ejjt5bxqy7rglzzuwkobwucgry: + resolution: {integrity: sha512-1cRIOHAPh8WQgdQQyyvFdeOdxuiyk+zB5zJ5+YOwrZP4cJ0MT3Fs48pQxrZeyZHcn+klFherytILVfE4aYrneg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + peerDependencies: + esbuild: '>=0.10.1' + rollup: ^1.20.0 || ^2.0.0 || ^3.0.0 + dependencies: + '@rollup/pluginutils': 5.0.2_rollup@3.10.0 + debug: 4.3.4 + es-module-lexer: 1.1.0 + esbuild: 0.17.4 + joycon: 3.1.1 + jsonc-parser: 3.2.0 + rollup: 3.10.0 + transitivePeerDependencies: + - supports-color + dev: true + /rollup-plugin-inject/3.0.2: resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. @@ -5736,6 +5780,11 @@ packages: engines: {node: '>=8'} dev: true + /slash/4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + /slice-ansi/3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} diff --git a/rollup.config.mjs b/rollup.config.mjs index e5c3b6388..9d0d8fe8c 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,8 +1,8 @@ // @ts-check -import { createRequire } from 'module' -import { fileURLToPath } from 'url' -import path from 'path' -import ts from 'rollup-plugin-typescript2' +import { createRequire } from 'node:module' +import { fileURLToPath } from 'node:url' +import path from 'node:path' +import { readdirSync } from 'node:fs' import replace from '@rollup/plugin-replace' import json from '@rollup/plugin-json' import chalk from 'chalk' @@ -10,6 +10,8 @@ import commonJS from '@rollup/plugin-commonjs' import polyfillNode from 'rollup-plugin-polyfill-node' import { nodeResolve } from '@rollup/plugin-node-resolve' import terser from '@rollup/plugin-terser' +import esbuild from 'rollup-plugin-esbuild' +import alias from '@rollup/plugin-alias' if (!process.env.TARGET) { throw new Error('TARGET package must be specified via --environment flag.') @@ -114,23 +116,37 @@ function createConfig(format, output, plugins = []) { output.name = packageOptions.name } - const shouldEmitDeclarations = - pkg.types && process.env.TYPES != null && !hasTSChecked - - const tsPlugin = ts({ - check: process.env.NODE_ENV === 'production' && !hasTSChecked, - tsconfig: path.resolve(__dirname, 'tsconfig.json'), - cacheRoot: path.resolve(__dirname, 'node_modules/.rts2_cache'), - tsconfigOverride: { - compilerOptions: { - target: isServerRenderer || isNodeBuild ? 'es2019' : 'es2015', - sourceMap: output.sourcemap, - declaration: shouldEmitDeclarations, - declarationMap: shouldEmitDeclarations - }, - exclude: ['**/__tests__', 'test-dts'] + // package aliases + // TODO reuse between rollup and vitest + const resolveEntryForPkg = p => + path.resolve( + fileURLToPath(import.meta.url), + `../packages/${p}/src/index.ts` + ) + const dirs = readdirSync(new URL('./packages', import.meta.url)) + const entries = { + vue: resolveEntryForPkg('vue'), + 'vue/compiler-sfc': resolveEntryForPkg('compiler-sfc'), + 'vue/server-renderer': resolveEntryForPkg('server-renderer'), + '@vue/compat': resolveEntryForPkg('vue-compat') + } + for (const dir of dirs) { + const key = `@vue/${dir}` + if (dir !== 'vue' && !(key in entries)) { + entries[key] = resolveEntryForPkg(dir) } + } + const aliasPlugin = alias({ + entries }) + + const tsPlugin = esbuild({ + tsconfig: path.resolve(__dirname, 'tsconfig.json'), + sourceMap: output.sourcemap, + minify: false, + target: isServerRenderer || isNodeBuild ? 'es2019' : 'es2015' + }) + // we only need to check TS and generate declarations once for each build. // it also seems to run into weird issues when checking multiple times // during a single build. @@ -211,6 +227,7 @@ function createConfig(format, output, plugins = []) { json({ namedExports: false }), + aliasPlugin, tsPlugin, createReplacePlugin( isProductionBuild, @@ -239,7 +256,15 @@ function createConfig(format, output, plugins = []) { } } -function createReplacePlugin( +function createReplacePlugin(...args) { + return replace({ + // @ts-ignore + values: createReplacements(...args), + preventAssignment: true + }) +} + +function createReplacements( isProduction, isBundlerESMBuild, isBrowserESMBuild, @@ -256,9 +281,9 @@ function createReplacePlugin( ? // preserve to be handled by bundlers `(process.env.NODE_ENV !== 'production')` : // hard coded dev/prod builds - !isProduction, + String(!isProduction), // this is only used during Vue's internal tests - __TEST__: false, + __TEST__: `false`, // If the build is expected to run directly in the browser (global / esm builds) __BROWSER__: isBrowserBuild, __GLOBAL__: isGlobalBuild, @@ -282,11 +307,11 @@ function createReplacePlugin( __COMPAT__: isCompatBuild, // feature flags - __FEATURE_SUSPENSE__: true, - __FEATURE_OPTIONS_API__: isBundlerESMBuild ? `__VUE_OPTIONS_API__` : true, + __FEATURE_SUSPENSE__: `true`, + __FEATURE_OPTIONS_API__: isBundlerESMBuild ? `__VUE_OPTIONS_API__` : `true`, __FEATURE_PROD_DEVTOOLS__: isBundlerESMBuild ? `__VUE_PROD_DEVTOOLS__` - : false, + : `false`, ...(isProduction && isBrowserBuild ? { 'context.onError(': `/*#__PURE__*/ context.onError(`, @@ -297,17 +322,13 @@ function createReplacePlugin( : {}) } // allow inline overrides like - //__RUNTIME_COMPILE__=true yarn build runtime-core + //__RUNTIME_COMPILE__=true pnpm build runtime-core Object.keys(replacements).forEach(key => { if (key in process.env) { replacements[key] = process.env[key] } }) - return replace({ - // @ts-ignore - values: replacements, - preventAssignment: true - }) + return replacements } function createProductionConfig(format) { diff --git a/rollup.original.config.mjs b/rollup.original.config.mjs new file mode 100644 index 000000000..e9a6e3420 --- /dev/null +++ b/rollup.original.config.mjs @@ -0,0 +1,379 @@ +// @ts-check +import { createRequire } from 'module' +import { fileURLToPath } from 'url' +import path from 'path' +import ts from 'rollup-plugin-typescript2' +import replace from '@rollup/plugin-replace' +import json from '@rollup/plugin-json' +import chalk from 'chalk' +import commonJS from '@rollup/plugin-commonjs' +import polyfillNode from 'rollup-plugin-polyfill-node' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import terser from '@rollup/plugin-terser' + +if (!process.env.TARGET) { + throw new Error('TARGET package must be specified via --environment flag.') +} + +const require = createRequire(import.meta.url) +const __dirname = fileURLToPath(new URL('.', import.meta.url)) + +const masterVersion = require('./package.json').version +const consolidatePkg = require('@vue/consolidate/package.json') + +const packagesDir = path.resolve(__dirname, 'packages') +const packageDir = path.resolve(packagesDir, process.env.TARGET) + +const resolve = p => path.resolve(packageDir, p) +const pkg = require(resolve(`package.json`)) +const packageOptions = pkg.buildOptions || {} +const name = packageOptions.filename || path.basename(packageDir) + +// ensure TS checks only once for each build +let hasTSChecked = false + +const outputConfigs = { + 'esm-bundler': { + file: resolve(`dist/${name}.esm-bundler.js`), + format: `es` + }, + 'esm-browser': { + file: resolve(`dist/${name}.esm-browser.js`), + format: `es` + }, + cjs: { + file: resolve(`dist/${name}.cjs.js`), + format: `cjs` + }, + global: { + file: resolve(`dist/${name}.global.js`), + format: `iife` + }, + // runtime-only builds, for main "vue" package only + 'esm-bundler-runtime': { + file: resolve(`dist/${name}.runtime.esm-bundler.js`), + format: `es` + }, + 'esm-browser-runtime': { + file: resolve(`dist/${name}.runtime.esm-browser.js`), + format: 'es' + }, + 'global-runtime': { + file: resolve(`dist/${name}.runtime.global.js`), + format: 'iife' + } +} + +const defaultFormats = ['esm-bundler', 'cjs'] +const inlineFormats = process.env.FORMATS && process.env.FORMATS.split(',') +const packageFormats = inlineFormats || packageOptions.formats || defaultFormats +const packageConfigs = process.env.PROD_ONLY + ? [] + : packageFormats.map(format => createConfig(format, outputConfigs[format])) + +if (process.env.NODE_ENV === 'production') { + packageFormats.forEach(format => { + if (packageOptions.prod === false) { + return + } + if (format === 'cjs') { + packageConfigs.push(createProductionConfig(format)) + } + if (/^(global|esm-browser)(-runtime)?/.test(format)) { + packageConfigs.push(createMinifiedConfig(format)) + } + }) +} + +export default packageConfigs + +function createConfig(format, output, plugins = []) { + if (!output) { + console.log(chalk.yellow(`invalid format: "${format}"`)) + process.exit(1) + } + + const isProductionBuild = + process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file) + const isBundlerESMBuild = /esm-bundler/.test(format) + const isBrowserESMBuild = /esm-browser/.test(format) + const isServerRenderer = name === 'server-renderer' + const isNodeBuild = format === 'cjs' + const isGlobalBuild = /global/.test(format) + const isCompatPackage = pkg.name === '@vue/compat' + const isCompatBuild = !!packageOptions.compat + + output.exports = isCompatPackage ? 'auto' : 'named' + output.esModule = true + output.sourcemap = !!process.env.SOURCE_MAP + output.externalLiveBindings = false + + if (isGlobalBuild) { + output.name = packageOptions.name + } + + const shouldEmitDeclarations = + pkg.types && process.env.TYPES != null && !hasTSChecked + + const tsPlugin = ts({ + check: process.env.NODE_ENV === 'production' && !hasTSChecked, + tsconfig: path.resolve(__dirname, 'tsconfig.json'), + cacheRoot: path.resolve(__dirname, 'node_modules/.rts2_cache'), + tsconfigOverride: { + compilerOptions: { + target: isServerRenderer || isNodeBuild ? 'es2019' : 'es2015', + sourceMap: output.sourcemap, + declaration: shouldEmitDeclarations, + declarationMap: shouldEmitDeclarations + }, + exclude: ['**/__tests__', 'test-dts'] + } + }) + // we only need to check TS and generate declarations once for each build. + // it also seems to run into weird issues when checking multiple times + // during a single build. + hasTSChecked = true + + let entryFile = /runtime$/.test(format) ? `src/runtime.ts` : `src/index.ts` + + // the compat build needs both default AND named exports. This will cause + // Rollup to complain for non-ESM targets, so we use separate entries for + // esm vs. non-esm builds. + if (isCompatPackage && (isBrowserESMBuild || isBundlerESMBuild)) { + entryFile = /runtime$/.test(format) + ? `src/esm-runtime.ts` + : `src/esm-index.ts` + } + + let external = [] + const treeShakenDeps = ['source-map', '@babel/parser', 'estree-walker'] + + if (isGlobalBuild || isBrowserESMBuild || isCompatPackage) { + if (!packageOptions.enableNonBrowserBranches) { + // normal browser builds - non-browser only imports are tree-shaken, + // they are only listed here to suppress warnings. + external = treeShakenDeps + } + } else { + // Node / esm-bundler builds. + // externalize all direct deps unless it's the compat build. + external = [ + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), + // for @vue/compiler-sfc / server-renderer + ...['path', 'url', 'stream'], + // somehow these throw warnings for runtime-* package builds + ...treeShakenDeps + ] + } + + // we are bundling forked consolidate.js in compiler-sfc which dynamically + // requires a ton of template engines which should be ignored. + let cjsIgnores = [] + if (pkg.name === '@vue/compiler-sfc') { + cjsIgnores = [ + ...Object.keys(consolidatePkg.devDependencies), + 'vm', + 'crypto', + 'react-dom/server', + 'teacup/lib/express', + 'arc-templates/dist/es5', + 'then-pug', + 'then-jade' + ] + } + + const nodePlugins = + (format === 'cjs' && Object.keys(pkg.devDependencies || {}).length) || + packageOptions.enableNonBrowserBranches + ? [ + commonJS({ + sourceMap: false, + ignore: cjsIgnores + }), + ...(format === 'cjs' ? [] : [polyfillNode()]), + nodeResolve() + ] + : [] + + if (format === 'cjs') { + nodePlugins.push(cjsReExportsPatchPlugin()) + } + + return { + input: resolve(entryFile), + // Global and Browser ESM builds inlines everything so that they can be + // used alone. + external, + plugins: [ + json({ + namedExports: false + }), + tsPlugin, + createReplacePlugin( + isProductionBuild, + isBundlerESMBuild, + isBrowserESMBuild, + // isBrowserBuild? + (isGlobalBuild || isBrowserESMBuild || isBundlerESMBuild) && + !packageOptions.enableNonBrowserBranches, + isGlobalBuild, + isNodeBuild, + isCompatBuild, + isServerRenderer + ), + ...nodePlugins, + ...plugins + ], + output, + onwarn: (msg, warn) => { + if (!/Circular/.test(msg)) { + warn(msg) + } + }, + treeshake: { + moduleSideEffects: false + } + } +} + +function createReplacePlugin( + isProduction, + isBundlerESMBuild, + isBrowserESMBuild, + isBrowserBuild, + isGlobalBuild, + isNodeBuild, + isCompatBuild, + isServerRenderer +) { + const replacements = { + __COMMIT__: `"${process.env.COMMIT}"`, + __VERSION__: `"${masterVersion}"`, + __DEV__: isBundlerESMBuild + ? // preserve to be handled by bundlers + `(process.env.NODE_ENV !== 'production')` + : // hard coded dev/prod builds + !isProduction, + // this is only used during Vue's internal tests + __TEST__: false, + // If the build is expected to run directly in the browser (global / esm builds) + __BROWSER__: isBrowserBuild, + __GLOBAL__: isGlobalBuild, + __ESM_BUNDLER__: isBundlerESMBuild, + __ESM_BROWSER__: isBrowserESMBuild, + // is targeting Node (SSR)? + __NODE_JS__: isNodeBuild, + // need SSR-specific branches? + __SSR__: isNodeBuild || isBundlerESMBuild || isServerRenderer, + + // for compiler-sfc browser build inlined deps + ...(isBrowserESMBuild + ? { + 'process.env': '({})', + 'process.platform': '""', + 'process.stdout': 'null' + } + : {}), + + // 2.x compat build + __COMPAT__: isCompatBuild, + + // feature flags + __FEATURE_SUSPENSE__: true, + __FEATURE_OPTIONS_API__: isBundlerESMBuild ? `__VUE_OPTIONS_API__` : true, + __FEATURE_PROD_DEVTOOLS__: isBundlerESMBuild + ? `__VUE_PROD_DEVTOOLS__` + : false, + ...(isProduction && isBrowserBuild + ? { + 'context.onError(': `/*#__PURE__*/ context.onError(`, + 'emitError(': `/*#__PURE__*/ emitError(`, + 'createCompilerError(': `/*#__PURE__*/ createCompilerError(`, + 'createDOMCompilerError(': `/*#__PURE__*/ createDOMCompilerError(` + } + : {}) + } + // allow inline overrides like + //__RUNTIME_COMPILE__=true yarn build runtime-core + Object.keys(replacements).forEach(key => { + if (key in process.env) { + replacements[key] = process.env[key] + } + }) + return replace({ + // @ts-ignore + values: replacements, + preventAssignment: true + }) +} + +function createProductionConfig(format) { + return createConfig(format, { + file: resolve(`dist/${name}.${format}.prod.js`), + format: outputConfigs[format].format + }) +} + +function createMinifiedConfig(format) { + return createConfig( + format, + { + file: outputConfigs[format].file.replace(/\.js$/, '.prod.js'), + format: outputConfigs[format].format + }, + [ + terser({ + module: /^esm/.test(format), + compress: { + ecma: 2015, + pure_getters: true + }, + safari10: true + }) + ] + ) +} + +// temporary patch for https://github.com/nodejs/cjs-module-lexer/issues/79 +// +// When importing a cjs module from esm, Node.js uses cjs-module-lexer to +// detect * re-exports from other packages. However, the detection logic is +// fragile and breaks when Rollup generates different code for the re-exports. +// We were locked on an old version of Rollup because of this. +// +// The latest versions of Node ships an updated version of cjs-module-lexer that +// has fixed https://github.com/nodejs/cjs-module-lexer/issues/38, however we +// still need to support older versions of Node that does not have the latest +// version of cjs-module-lexer (Node < 14.18) +// +// At the same time, we want to upgrade to Rollup 3 so we are not forever locked +// on an old version of Rollup. +// +// What this patch does: +// 1. Rewrite the for...in loop to Object.keys() so cjs-module-lexer can find it +// The for...in loop is only used when output.externalLiveBindings is set to +// false, and we do want to set it to false to avoid perf costs during SSR. +// 2. Also remove exports.hasOwnProperty check, which breaks the detection in +// Node.js versions that +// +// TODO in the future, we should no longer rely on this if we inline all deps +// in the main `vue` package. +function cjsReExportsPatchPlugin() { + const matcher = + /for \(var k in (\w+)\) {(\s+if \(k !== 'default') && !exports.hasOwnProperty\(k\)(\) exports\[k\] = (?:\w+)\[k\];\s+)}/ + return { + name: 'patch-cjs-re-exports', + renderChunk(code, _, options) { + if (matcher.test(code)) { + return code.replace(matcher, (_, r1, r2, r3) => { + return `Object.keys(${r1}).forEach(function(k) {${r2}${r3}});` + }) + } else if (options.file.endsWith('packages/vue/dist/vue.cjs.js')) { + // make sure we don't accidentally miss the rewrite in case Rollup + // changes the output again. + throw new Error('cjs build re-exports rewrite failed.') + } + } + } +} diff --git a/tsconfig.json b/tsconfig.json index 4f0b12dfb..29c7aee3f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,7 @@ "noUnusedLocals": true, "experimentalDecorators": true, "resolveJsonModule": true, + "isolatedModules": true, "esModuleInterop": true, "removeComments": false, "jsx": "preserve",