mirror of https://github.com/vuejs/core.git
parent
47ea285be3
commit
fff7b864f4
|
@ -3,6 +3,15 @@
|
||||||
const DOMGlobals = ['window', 'document']
|
const DOMGlobals = ['window', 'document']
|
||||||
const NodeGlobals = ['module', 'require']
|
const NodeGlobals = ['module', 'require']
|
||||||
|
|
||||||
|
const banConstEnum = {
|
||||||
|
selector: 'TSEnumDeclaration[const=true]',
|
||||||
|
message:
|
||||||
|
'Please use non-const enums. This project automatically inlines enums.'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('eslint-define-config').ESLintConfig}
|
||||||
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
|
@ -16,6 +25,7 @@ module.exports = {
|
||||||
|
|
||||||
'no-restricted-syntax': [
|
'no-restricted-syntax': [
|
||||||
'error',
|
'error',
|
||||||
|
banConstEnum,
|
||||||
// since we target ES2015 for baseline support, we need to forbid object
|
// since we target ES2015 for baseline support, we need to forbid object
|
||||||
// rest spread usage in destructure as it compiles into a verbose helper.
|
// rest spread usage in destructure as it compiles into a verbose helper.
|
||||||
'ObjectPattern > RestElement',
|
'ObjectPattern > RestElement',
|
||||||
|
@ -55,7 +65,7 @@ module.exports = {
|
||||||
files: ['packages/{compiler-sfc,compiler-ssr,server-renderer}/**'],
|
files: ['packages/{compiler-sfc,compiler-ssr,server-renderer}/**'],
|
||||||
rules: {
|
rules: {
|
||||||
'no-restricted-globals': ['error', ...DOMGlobals],
|
'no-restricted-globals': ['error', ...DOMGlobals],
|
||||||
'no-restricted-syntax': 'off'
|
'no-restricted-syntax': ['error', banConstEnum]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Private package, browser only + no syntax restrictions
|
// Private package, browser only + no syntax restrictions
|
||||||
|
@ -63,7 +73,7 @@ module.exports = {
|
||||||
files: ['packages/template-explorer/**', 'packages/sfc-playground/**'],
|
files: ['packages/template-explorer/**', 'packages/sfc-playground/**'],
|
||||||
rules: {
|
rules: {
|
||||||
'no-restricted-globals': ['error', ...NodeGlobals],
|
'no-restricted-globals': ['error', ...NodeGlobals],
|
||||||
'no-restricted-syntax': 'off'
|
'no-restricted-syntax': ['error', banConstEnum]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// JavaScript files
|
// JavaScript files
|
||||||
|
@ -79,7 +89,7 @@ module.exports = {
|
||||||
files: ['scripts/**', '*.{js,ts}', 'packages/**/index.js'],
|
files: ['scripts/**', '*.{js,ts}', 'packages/**/index.js'],
|
||||||
rules: {
|
rules: {
|
||||||
'no-restricted-globals': 'off',
|
'no-restricted-globals': 'off',
|
||||||
'no-restricted-syntax': 'off'
|
'no-restricted-syntax': ['error', banConstEnum]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -66,7 +66,9 @@
|
||||||
"@rollup/plugin-replace": "^5.0.4",
|
"@rollup/plugin-replace": "^5.0.4",
|
||||||
"@rollup/plugin-terser": "^0.4.4",
|
"@rollup/plugin-terser": "^0.4.4",
|
||||||
"@types/hash-sum": "^1.0.2",
|
"@types/hash-sum": "^1.0.2",
|
||||||
|
"@types/minimist": "^1.2.5",
|
||||||
"@types/node": "^20.10.0",
|
"@types/node": "^20.10.0",
|
||||||
|
"@types/semver": "^7.5.5",
|
||||||
"@typescript-eslint/parser": "^6.13.0",
|
"@typescript-eslint/parser": "^6.13.0",
|
||||||
"@vitest/coverage-istanbul": "^0.34.6",
|
"@vitest/coverage-istanbul": "^0.34.6",
|
||||||
"@vue/consolidate": "0.17.3",
|
"@vue/consolidate": "0.17.3",
|
||||||
|
@ -75,6 +77,7 @@
|
||||||
"esbuild": "^0.19.5",
|
"esbuild": "^0.19.5",
|
||||||
"esbuild-plugin-polyfill-node": "^0.3.0",
|
"esbuild-plugin-polyfill-node": "^0.3.0",
|
||||||
"eslint": "^8.54.0",
|
"eslint": "^8.54.0",
|
||||||
|
"eslint-define-config": "^1.24.1",
|
||||||
"eslint-plugin-jest": "^27.6.0",
|
"eslint-plugin-jest": "^27.6.0",
|
||||||
"estree-walker": "^2.0.2",
|
"estree-walker": "^2.0.2",
|
||||||
"execa": "^8.0.1",
|
"execa": "^8.0.1",
|
||||||
|
|
|
@ -19,13 +19,13 @@ import { ImportItem, TransformContext } from './transform'
|
||||||
// More namespaces can be declared by platform specific compilers.
|
// More namespaces can be declared by platform specific compilers.
|
||||||
export type Namespace = number
|
export type Namespace = number
|
||||||
|
|
||||||
export const enum Namespaces {
|
export enum Namespaces {
|
||||||
HTML,
|
HTML,
|
||||||
SVG,
|
SVG,
|
||||||
MATH_ML
|
MATH_ML
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum NodeTypes {
|
export enum NodeTypes {
|
||||||
ROOT,
|
ROOT,
|
||||||
ELEMENT,
|
ELEMENT,
|
||||||
TEXT,
|
TEXT,
|
||||||
|
@ -59,7 +59,7 @@ export const enum NodeTypes {
|
||||||
JS_RETURN_STATEMENT
|
JS_RETURN_STATEMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum ElementTypes {
|
export enum ElementTypes {
|
||||||
ELEMENT,
|
ELEMENT,
|
||||||
COMPONENT,
|
COMPONENT,
|
||||||
SLOT,
|
SLOT,
|
||||||
|
@ -214,7 +214,7 @@ export interface DirectiveNode extends Node {
|
||||||
* Higher levels implies lower levels. e.g. a node that can be stringified
|
* Higher levels implies lower levels. e.g. a node that can be stringified
|
||||||
* can always be hoisted and skipped for patch.
|
* can always be hoisted and skipped for patch.
|
||||||
*/
|
*/
|
||||||
export const enum ConstantTypes {
|
export enum ConstantTypes {
|
||||||
NOT_CONSTANT = 0,
|
NOT_CONSTANT = 0,
|
||||||
CAN_SKIP_PATCH,
|
CAN_SKIP_PATCH,
|
||||||
CAN_HOIST,
|
CAN_HOIST,
|
||||||
|
|
|
@ -69,7 +69,7 @@ export interface CodegenResult {
|
||||||
map?: RawSourceMap
|
map?: RawSourceMap
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum NewlineType {
|
enum NewlineType {
|
||||||
Start = 0,
|
Start = 0,
|
||||||
End = -1,
|
End = -1,
|
||||||
None = -2,
|
None = -2,
|
||||||
|
|
|
@ -13,7 +13,7 @@ export interface CompilerCompatOptions {
|
||||||
compatConfig?: CompilerCompatConfig
|
compatConfig?: CompilerCompatConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CompilerDeprecationTypes {
|
export enum CompilerDeprecationTypes {
|
||||||
COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT',
|
COMPILER_IS_ON_ELEMENT = 'COMPILER_IS_ON_ELEMENT',
|
||||||
COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC',
|
COMPILER_V_BIND_SYNC = 'COMPILER_V_BIND_SYNC',
|
||||||
COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER',
|
COMPILER_V_BIND_OBJECT_ORDER = 'COMPILER_V_BIND_OBJECT_ORDER',
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function createCompilerError<T extends number>(
|
||||||
return error
|
return error
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum ErrorCodes {
|
export enum ErrorCodes {
|
||||||
// parse errors
|
// parse errors
|
||||||
ABRUPT_CLOSING_OF_EMPTY_COMMENT,
|
ABRUPT_CLOSING_OF_EMPTY_COMMENT,
|
||||||
CDATA_IN_HTML_CONTENT,
|
CDATA_IN_HTML_CONTENT,
|
||||||
|
|
|
@ -94,7 +94,7 @@ export type HoistTransform = (
|
||||||
parent: ParentNode
|
parent: ParentNode
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
export const enum BindingTypes {
|
export enum BindingTypes {
|
||||||
/**
|
/**
|
||||||
* returned from data()
|
* returned from data()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,13 +38,13 @@ import {
|
||||||
fromCodePoint
|
fromCodePoint
|
||||||
} from 'entities/lib/decode.js'
|
} from 'entities/lib/decode.js'
|
||||||
|
|
||||||
export const enum ParseMode {
|
export enum ParseMode {
|
||||||
BASE,
|
BASE,
|
||||||
HTML,
|
HTML,
|
||||||
SFC
|
SFC
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CharCodes {
|
export enum CharCodes {
|
||||||
Tab = 0x9, // "\t"
|
Tab = 0x9, // "\t"
|
||||||
NewLine = 0xa, // "\n"
|
NewLine = 0xa, // "\n"
|
||||||
FormFeed = 0xc, // "\f"
|
FormFeed = 0xc, // "\f"
|
||||||
|
@ -72,7 +72,6 @@ export const enum CharCodes {
|
||||||
UpperZ = 0x5a, // "Z"
|
UpperZ = 0x5a, // "Z"
|
||||||
LowerZ = 0x7a, // "z"
|
LowerZ = 0x7a, // "z"
|
||||||
LowerX = 0x78, // "x"
|
LowerX = 0x78, // "x"
|
||||||
OpeningSquareBracket = 0x5b, // "["
|
|
||||||
LowerV = 0x76, // "v"
|
LowerV = 0x76, // "v"
|
||||||
Dot = 0x2e, // "."
|
Dot = 0x2e, // "."
|
||||||
Colon = 0x3a, // ":"
|
Colon = 0x3a, // ":"
|
||||||
|
@ -85,7 +84,7 @@ const defaultDelimitersOpen = new Uint8Array([123, 123]) // "{{"
|
||||||
const defaultDelimitersClose = new Uint8Array([125, 125]) // "}}"
|
const defaultDelimitersClose = new Uint8Array([125, 125]) // "}}"
|
||||||
|
|
||||||
/** All the states the tokenizer can be in. */
|
/** All the states the tokenizer can be in. */
|
||||||
export const enum State {
|
export enum State {
|
||||||
Text = 1,
|
Text = 1,
|
||||||
|
|
||||||
// interpolation
|
// interpolation
|
||||||
|
@ -820,7 +819,7 @@ export default class Tokenizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private stateBeforeDeclaration(c: number): void {
|
private stateBeforeDeclaration(c: number): void {
|
||||||
if (c === CharCodes.OpeningSquareBracket) {
|
if (c === CharCodes.LeftSqaure) {
|
||||||
this.state = State.CDATASequence
|
this.state = State.CDATASequence
|
||||||
this.sequenceIndex = 0
|
this.sequenceIndex = 0
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -65,7 +65,7 @@ const nonIdentifierRE = /^\d|[^\$\w]/
|
||||||
export const isSimpleIdentifier = (name: string): boolean =>
|
export const isSimpleIdentifier = (name: string): boolean =>
|
||||||
!nonIdentifierRE.test(name)
|
!nonIdentifierRE.test(name)
|
||||||
|
|
||||||
const enum MemberExpLexState {
|
enum MemberExpLexState {
|
||||||
inMemberExp,
|
inMemberExp,
|
||||||
inBrackets,
|
inBrackets,
|
||||||
inParens,
|
inParens,
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function createDOMCompilerError(
|
||||||
) as DOMCompilerError
|
) as DOMCompilerError
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum DOMErrorCodes {
|
export enum DOMErrorCodes {
|
||||||
X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
|
X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
|
||||||
X_V_HTML_WITH_CHILDREN,
|
X_V_HTML_WITH_CHILDREN,
|
||||||
X_V_TEXT_NO_EXPRESSION,
|
X_V_TEXT_NO_EXPRESSION,
|
||||||
|
@ -36,7 +36,7 @@ export const enum DOMErrorCodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__TEST__) {
|
if (__TEST__) {
|
||||||
// esbuild cannot infer const enum increments if first value is from another
|
// esbuild cannot infer enum increments if first value is from another
|
||||||
// file, so we have to manually keep them in sync. this check ensures it
|
// file, so we have to manually keep them in sync. this check ensures it
|
||||||
// errors out if there are collisions.
|
// errors out if there are collisions.
|
||||||
if (DOMErrorCodes.X_V_HTML_NO_EXPRESSION < ErrorCodes.__EXTEND_POINT__) {
|
if (DOMErrorCodes.X_V_HTML_NO_EXPRESSION < ErrorCodes.__EXTEND_POINT__) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import {
|
||||||
isBooleanAttr
|
isBooleanAttr
|
||||||
} from '@vue/shared'
|
} from '@vue/shared'
|
||||||
|
|
||||||
export const enum StringifyThresholds {
|
export enum StringifyThresholds {
|
||||||
ELEMENT_WITH_BINDING_COUNT = 5,
|
ELEMENT_WITH_BINDING_COUNT = 5,
|
||||||
NODE_COUNT = 20
|
NODE_COUNT = 20
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ export function parseCssVars(sfc: SFCDescriptor): string[] {
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum LexerState {
|
enum LexerState {
|
||||||
inParens,
|
inParens,
|
||||||
inSingleQuoteString,
|
inSingleQuoteString,
|
||||||
inDoubleQuoteString
|
inDoubleQuoteString
|
||||||
|
|
|
@ -16,14 +16,14 @@ export function createSSRCompilerError(
|
||||||
return createCompilerError(code, loc, SSRErrorMessages) as SSRCompilerError
|
return createCompilerError(code, loc, SSRErrorMessages) as SSRCompilerError
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum SSRErrorCodes {
|
export enum SSRErrorCodes {
|
||||||
X_SSR_UNSAFE_ATTR_NAME = 65 /* DOMErrorCodes.__EXTEND_POINT__ */,
|
X_SSR_UNSAFE_ATTR_NAME = 65 /* DOMErrorCodes.__EXTEND_POINT__ */,
|
||||||
X_SSR_NO_TELEPORT_TARGET,
|
X_SSR_NO_TELEPORT_TARGET,
|
||||||
X_SSR_INVALID_AST_NODE
|
X_SSR_INVALID_AST_NODE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__TEST__) {
|
if (__TEST__) {
|
||||||
// esbuild cannot infer const enum increments if first value is from another
|
// esbuild cannot infer enum increments if first value is from another
|
||||||
// file, so we have to manually keep them in sync. this check ensures it
|
// file, so we have to manually keep them in sync. this check ensures it
|
||||||
// errors out if there are collisions.
|
// errors out if there are collisions.
|
||||||
if (SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME < DOMErrorCodes.__EXTEND_POINT__) {
|
if (SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME < DOMErrorCodes.__EXTEND_POINT__) {
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
// using literal strings instead of numbers so that it's easier to inspect
|
// using literal strings instead of numbers so that it's easier to inspect
|
||||||
// debugger events
|
// debugger events
|
||||||
|
|
||||||
export const enum TrackOpTypes {
|
export enum TrackOpTypes {
|
||||||
GET = 'get',
|
GET = 'get',
|
||||||
HAS = 'has',
|
HAS = 'has',
|
||||||
ITERATE = 'iterate'
|
ITERATE = 'iterate'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum TriggerOpTypes {
|
export enum TriggerOpTypes {
|
||||||
SET = 'set',
|
SET = 'set',
|
||||||
ADD = 'add',
|
ADD = 'add',
|
||||||
DELETE = 'delete',
|
DELETE = 'delete',
|
||||||
CLEAR = 'clear'
|
CLEAR = 'clear'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum ReactiveFlags {
|
export enum ReactiveFlags {
|
||||||
SKIP = '__v_skip',
|
SKIP = '__v_skip',
|
||||||
IS_REACTIVE = '__v_isReactive',
|
IS_REACTIVE = '__v_isReactive',
|
||||||
IS_READONLY = '__v_isReadonly',
|
IS_READONLY = '__v_isReadonly',
|
||||||
|
@ -22,7 +22,7 @@ export const enum ReactiveFlags {
|
||||||
RAW = '__v_raw'
|
RAW = '__v_raw'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum DirtyLevels {
|
export enum DirtyLevels {
|
||||||
NotDirty = 0,
|
NotDirty = 0,
|
||||||
ComputedValueMaybeDirty = 1,
|
ComputedValueMaybeDirty = 1,
|
||||||
ComputedValueDirty = 2,
|
ComputedValueDirty = 2,
|
||||||
|
|
|
@ -68,8 +68,4 @@ export {
|
||||||
getCurrentScope,
|
getCurrentScope,
|
||||||
onScopeDispose
|
onScopeDispose
|
||||||
} from './effectScope'
|
} from './effectScope'
|
||||||
export {
|
export { TrackOpTypes, TriggerOpTypes, ReactiveFlags } from './constants'
|
||||||
TrackOpTypes /* @remove */,
|
|
||||||
TriggerOpTypes /* @remove */,
|
|
||||||
ReactiveFlags /* @remove */
|
|
||||||
} from './constants'
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ export const shallowReactiveMap = new WeakMap<Target, any>()
|
||||||
export const readonlyMap = new WeakMap<Target, any>()
|
export const readonlyMap = new WeakMap<Target, any>()
|
||||||
export const shallowReadonlyMap = new WeakMap<Target, any>()
|
export const shallowReadonlyMap = new WeakMap<Target, any>()
|
||||||
|
|
||||||
const enum TargetType {
|
enum TargetType {
|
||||||
INVALID = 0,
|
INVALID = 0,
|
||||||
COMMON = 1,
|
COMMON = 1,
|
||||||
COLLECTION = 2
|
COLLECTION = 2
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from '../component'
|
} from '../component'
|
||||||
import { warn } from '../warning'
|
import { warn } from '../warning'
|
||||||
|
|
||||||
export const enum DeprecationTypes {
|
export enum DeprecationTypes {
|
||||||
GLOBAL_MOUNT = 'GLOBAL_MOUNT',
|
GLOBAL_MOUNT = 'GLOBAL_MOUNT',
|
||||||
GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER',
|
GLOBAL_MOUNT_CONTAINER = 'GLOBAL_MOUNT_CONTAINER',
|
||||||
GLOBAL_EXTEND = 'GLOBAL_EXTEND',
|
GLOBAL_EXTEND = 'GLOBAL_EXTEND',
|
||||||
|
|
|
@ -586,7 +586,7 @@ export type OptionTypesType<
|
||||||
Defaults: Defaults
|
Defaults: Defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum OptionTypes {
|
enum OptionTypes {
|
||||||
PROPS = 'Props',
|
PROPS = 'Props',
|
||||||
DATA = 'Data',
|
DATA = 'Data',
|
||||||
COMPUTED = 'Computed',
|
COMPUTED = 'Computed',
|
||||||
|
|
|
@ -164,7 +164,7 @@ export type ExtractPublicPropTypes<O> = {
|
||||||
[K in keyof Pick<O, PublicOptionalKeys<O>>]?: InferPropType<O[K]>
|
[K in keyof Pick<O, PublicOptionalKeys<O>>]?: InferPropType<O[K]>
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum BooleanFlags {
|
enum BooleanFlags {
|
||||||
shouldCast,
|
shouldCast,
|
||||||
shouldCastTrue
|
shouldCastTrue
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,7 @@ if (__COMPAT__) {
|
||||||
installCompatInstanceProperties(publicPropertiesMap)
|
installCompatInstanceProperties(publicPropertiesMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum AccessTypes {
|
enum AccessTypes {
|
||||||
OTHER,
|
OTHER,
|
||||||
SETUP,
|
SETUP,
|
||||||
DATA,
|
DATA,
|
||||||
|
|
|
@ -269,7 +269,7 @@ export const TeleportImpl = {
|
||||||
hydrate: hydrateTeleport
|
hydrate: hydrateTeleport
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum TeleportMoveTypes {
|
export enum TeleportMoveTypes {
|
||||||
TARGET_CHANGE,
|
TARGET_CHANGE,
|
||||||
TOGGLE, // enable / disable
|
TOGGLE, // enable / disable
|
||||||
REORDER // moved in the main view
|
REORDER // moved in the main view
|
||||||
|
|
|
@ -10,7 +10,7 @@ interface AppRecord {
|
||||||
types: Record<string, string | Symbol>
|
types: Record<string, string | Symbol>
|
||||||
}
|
}
|
||||||
|
|
||||||
const enum DevtoolsHooks {
|
enum DevtoolsHooks {
|
||||||
APP_INIT = 'app:init',
|
APP_INIT = 'app:init',
|
||||||
APP_UNMOUNT = 'app:unmount',
|
APP_UNMOUNT = 'app:unmount',
|
||||||
COMPONENT_UPDATED = 'component:updated',
|
COMPONENT_UPDATED = 'component:updated',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const enum LifecycleHooks {
|
export enum LifecycleHooks {
|
||||||
BEFORE_CREATE = 'bc',
|
BEFORE_CREATE = 'bc',
|
||||||
CREATED = 'c',
|
CREATED = 'c',
|
||||||
BEFORE_MOUNT = 'bm',
|
BEFORE_MOUNT = 'bm',
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { LifecycleHooks } from './enums'
|
||||||
|
|
||||||
// contexts where user provided function may be executed, in addition to
|
// contexts where user provided function may be executed, in addition to
|
||||||
// lifecycle hooks.
|
// lifecycle hooks.
|
||||||
export const enum ErrorCodes {
|
export enum ErrorCodes {
|
||||||
SETUP_FUNCTION,
|
SETUP_FUNCTION,
|
||||||
RENDER_FUNCTION,
|
RENDER_FUNCTION,
|
||||||
WATCH_GETTER,
|
WATCH_GETTER,
|
||||||
|
|
|
@ -30,7 +30,7 @@ export type RootHydrateFunction = (
|
||||||
container: (Element | ShadowRoot) & { _vnode?: VNode }
|
container: (Element | ShadowRoot) & { _vnode?: VNode }
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
const enum DOMNodeTypes {
|
enum DOMNodeTypes {
|
||||||
ELEMENT = 1,
|
ELEMENT = 1,
|
||||||
TEXT = 3,
|
TEXT = 3,
|
||||||
COMMENT = 8
|
COMMENT = 8
|
||||||
|
|
|
@ -361,7 +361,7 @@ export const ssrUtils = (__SSR__ ? _ssrUtils : null) as typeof _ssrUtils
|
||||||
|
|
||||||
// 2.x COMPAT ------------------------------------------------------------------
|
// 2.x COMPAT ------------------------------------------------------------------
|
||||||
|
|
||||||
export { DeprecationTypes } from './compat/compatConfig'
|
import { DeprecationTypes as _DeprecationTypes } from './compat/compatConfig'
|
||||||
export type { CompatVue } from './compat/global'
|
export type { CompatVue } from './compat/global'
|
||||||
export type { LegacyConfig } from './compat/globalConfig'
|
export type { LegacyConfig } from './compat/globalConfig'
|
||||||
|
|
||||||
|
@ -393,3 +393,7 @@ const _compatUtils = {
|
||||||
export const compatUtils = (
|
export const compatUtils = (
|
||||||
__COMPAT__ ? _compatUtils : null
|
__COMPAT__ ? _compatUtils : null
|
||||||
) as typeof _compatUtils
|
) as typeof _compatUtils
|
||||||
|
|
||||||
|
export const DeprecationTypes = (
|
||||||
|
__COMPAT__ ? _DeprecationTypes : null
|
||||||
|
) as typeof _DeprecationTypes
|
||||||
|
|
|
@ -265,7 +265,7 @@ export type SetupRenderEffectFn = (
|
||||||
optimized: boolean
|
optimized: boolean
|
||||||
) => void
|
) => void
|
||||||
|
|
||||||
export const enum MoveType {
|
export enum MoveType {
|
||||||
ENTER,
|
ENTER,
|
||||||
LEAVE,
|
LEAVE,
|
||||||
REORDER
|
REORDER
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { markRaw } from '@vue/reactivity'
|
import { markRaw } from '@vue/reactivity'
|
||||||
|
|
||||||
export const enum TestNodeTypes {
|
export enum TestNodeTypes {
|
||||||
TEXT = 'text',
|
TEXT = 'text',
|
||||||
ELEMENT = 'element',
|
ELEMENT = 'element',
|
||||||
COMMENT = 'comment'
|
COMMENT = 'comment'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum NodeOpTypes {
|
export enum NodeOpTypes {
|
||||||
CREATE = 'create',
|
CREATE = 'create',
|
||||||
INSERT = 'insert',
|
INSERT = 'insert',
|
||||||
REMOVE = 'remove',
|
REMOVE = 'remove',
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* Check the `patchElement` function in '../../runtime-core/src/renderer.ts' to see how the
|
* Check the `patchElement` function in '../../runtime-core/src/renderer.ts' to see how the
|
||||||
* flags are handled during diff.
|
* flags are handled during diff.
|
||||||
*/
|
*/
|
||||||
export const enum PatchFlags {
|
export enum PatchFlags {
|
||||||
/**
|
/**
|
||||||
* Indicates an element with dynamic textContent (children fast path)
|
* Indicates an element with dynamic textContent (children fast path)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const enum ShapeFlags {
|
export enum ShapeFlags {
|
||||||
ELEMENT = 1,
|
ELEMENT = 1,
|
||||||
FUNCTIONAL_COMPONENT = 1 << 1,
|
FUNCTIONAL_COMPONENT = 1 << 1,
|
||||||
STATEFUL_COMPONENT = 1 << 2,
|
STATEFUL_COMPONENT = 1 << 2,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const enum SlotFlags {
|
export enum SlotFlags {
|
||||||
/**
|
/**
|
||||||
* Stable slots that only reference slot props or context state. The slot
|
* Stable slots that only reference slot props or context state. The slot
|
||||||
* can fully capture its own dependencies so when passed down the parent won't
|
* can fully capture its own dependencies so when passed down the parent won't
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
|
|
||||||
export declare const RefType: unique symbol
|
export declare const RefType: unique symbol
|
||||||
|
|
||||||
export declare const enum RefTypes {
|
export declare enum RefTypes {
|
||||||
Ref = 1,
|
Ref = 1,
|
||||||
ComputedRef = 2,
|
ComputedRef = 2,
|
||||||
WritableComputedRef = 3
|
WritableComputedRef = 3
|
||||||
|
|
|
@ -35,9 +35,15 @@ importers:
|
||||||
'@types/hash-sum':
|
'@types/hash-sum':
|
||||||
specifier: ^1.0.2
|
specifier: ^1.0.2
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
|
'@types/minimist':
|
||||||
|
specifier: ^1.2.5
|
||||||
|
version: 1.2.5
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.10.0
|
specifier: ^20.10.0
|
||||||
version: 20.10.0
|
version: 20.10.0
|
||||||
|
'@types/semver':
|
||||||
|
specifier: ^7.5.5
|
||||||
|
version: 7.5.5
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^6.13.0
|
specifier: ^6.13.0
|
||||||
version: 6.13.0(eslint@8.54.0)(typescript@5.2.2)
|
version: 6.13.0(eslint@8.54.0)(typescript@5.2.2)
|
||||||
|
@ -62,6 +68,9 @@ importers:
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.54.0
|
specifier: ^8.54.0
|
||||||
version: 8.54.0
|
version: 8.54.0
|
||||||
|
eslint-define-config:
|
||||||
|
specifier: ^1.24.1
|
||||||
|
version: 1.24.1
|
||||||
eslint-plugin-jest:
|
eslint-plugin-jest:
|
||||||
specifier: ^27.6.0
|
specifier: ^27.6.0
|
||||||
version: 27.6.0(eslint@8.54.0)(typescript@5.2.2)
|
version: 27.6.0(eslint@8.54.0)(typescript@5.2.2)
|
||||||
|
@ -1514,6 +1523,10 @@ packages:
|
||||||
resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==}
|
resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/minimist@1.2.5:
|
||||||
|
resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/node@20.10.0:
|
/@types/node@20.10.0:
|
||||||
resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==}
|
resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -1528,8 +1541,8 @@ packages:
|
||||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/semver@7.5.4:
|
/@types/semver@7.5.5:
|
||||||
resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==}
|
resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/yauzl@2.10.2:
|
/@types/yauzl@2.10.2:
|
||||||
|
@ -1637,7 +1650,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
|
'@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0)
|
||||||
'@types/json-schema': 7.0.14
|
'@types/json-schema': 7.0.14
|
||||||
'@types/semver': 7.5.4
|
'@types/semver': 7.5.5
|
||||||
'@typescript-eslint/scope-manager': 5.62.0
|
'@typescript-eslint/scope-manager': 5.62.0
|
||||||
'@typescript-eslint/types': 5.62.0
|
'@typescript-eslint/types': 5.62.0
|
||||||
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2)
|
'@typescript-eslint/typescript-estree': 5.62.0(typescript@5.2.2)
|
||||||
|
@ -2842,6 +2855,11 @@ packages:
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/eslint-define-config@1.24.1:
|
||||||
|
resolution: {integrity: sha512-o36vBhPSWyIQlHoMqGhhcGmOOm2A2ccBVIdLTG/AWdm9YmjpsLpf+5ntf9LlHR6dduLREgxtGwvwPwSt7vnXJg==}
|
||||||
|
engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>= 8.6.0'}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/eslint-plugin-jest@27.6.0(eslint@8.54.0)(typescript@5.2.2):
|
/eslint-plugin-jest@27.6.0(eslint@8.54.0)(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-MTlusnnDMChbElsszJvrwD1dN3x6nZl//s4JD23BxB6MgR66TZlL064su24xEIS3VACfAoHV1vgyMgPw8nkdng==}
|
resolution: {integrity: sha512-MTlusnnDMChbElsszJvrwD1dN3x6nZl//s4JD23BxB6MgR66TZlL064su24xEIS3VACfAoHV1vgyMgPw8nkdng==}
|
||||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import terser from '@rollup/plugin-terser'
|
||||||
import esbuild from 'rollup-plugin-esbuild'
|
import esbuild from 'rollup-plugin-esbuild'
|
||||||
import alias from '@rollup/plugin-alias'
|
import alias from '@rollup/plugin-alias'
|
||||||
import { entries } from './scripts/aliases.js'
|
import { entries } from './scripts/aliases.js'
|
||||||
import { constEnum } from './scripts/const-enum.js'
|
import { inlineEnums } from './scripts/inline-enums.js'
|
||||||
|
|
||||||
if (!process.env.TARGET) {
|
if (!process.env.TARGET) {
|
||||||
throw new Error('TARGET package must be specified via --environment flag.')
|
throw new Error('TARGET package must be specified via --environment flag.')
|
||||||
|
@ -32,7 +32,7 @@ const pkg = require(resolve(`package.json`))
|
||||||
const packageOptions = pkg.buildOptions || {}
|
const packageOptions = pkg.buildOptions || {}
|
||||||
const name = packageOptions.filename || path.basename(packageDir)
|
const name = packageOptions.filename || path.basename(packageDir)
|
||||||
|
|
||||||
const [enumPlugin, enumDefines] = constEnum()
|
const [enumPlugin, enumDefines] = inlineEnums()
|
||||||
|
|
||||||
const outputConfigs = {
|
const outputConfigs = {
|
||||||
'esm-bundler': {
|
'esm-bundler': {
|
||||||
|
|
|
@ -17,26 +17,29 @@ const targetPackages = targets
|
||||||
? packages.filter(pkg => targets.includes(pkg))
|
? packages.filter(pkg => targets.includes(pkg))
|
||||||
: packages
|
: packages
|
||||||
|
|
||||||
export default targetPackages.map(pkg => {
|
export default targetPackages.map(
|
||||||
return {
|
/** @returns {import('rollup').RollupOptions} */
|
||||||
input: `./temp/packages/${pkg}/src/index.d.ts`,
|
pkg => {
|
||||||
output: {
|
return {
|
||||||
file: `packages/${pkg}/dist/${pkg}.d.ts`,
|
input: `./temp/packages/${pkg}/src/index.d.ts`,
|
||||||
format: 'es'
|
output: {
|
||||||
},
|
file: `packages/${pkg}/dist/${pkg}.d.ts`,
|
||||||
plugins: [dts(), patchTypes(pkg), ...(pkg === 'vue' ? [copyMts()] : [])],
|
format: 'es'
|
||||||
onwarn(warning, warn) {
|
},
|
||||||
// during dts rollup, everything is externalized by default
|
plugins: [dts(), patchTypes(pkg), ...(pkg === 'vue' ? [copyMts()] : [])],
|
||||||
if (
|
onwarn(warning, warn) {
|
||||||
warning.code === 'UNRESOLVED_IMPORT' &&
|
// during dts rollup, everything is externalized by default
|
||||||
!warning.exporter.startsWith('.')
|
if (
|
||||||
) {
|
warning.code === 'UNRESOLVED_IMPORT' &&
|
||||||
return
|
!warning.exporter?.startsWith('.')
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
warn(warning)
|
||||||
}
|
}
|
||||||
warn(warning)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Patch the dts generated by rollup-plugin-dts
|
* Patch the dts generated by rollup-plugin-dts
|
||||||
|
@ -45,6 +48,8 @@ export default targetPackages.map(pkg => {
|
||||||
* otherwise it gets weird in vitepress `defineComponent` call with
|
* otherwise it gets weird in vitepress `defineComponent` call with
|
||||||
* "the inferred type cannot be named without a reference"
|
* "the inferred type cannot be named without a reference"
|
||||||
* 2. Append custom augmentations (jsx, macros)
|
* 2. Append custom augmentations (jsx, macros)
|
||||||
|
*
|
||||||
|
* @param {string} pkg
|
||||||
* @returns {import('rollup').Plugin}
|
* @returns {import('rollup').Plugin}
|
||||||
*/
|
*/
|
||||||
function patchTypes(pkg) {
|
function patchTypes(pkg) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { execa, execaSync } from 'execa'
|
||||||
import { cpus } from 'node:os'
|
import { cpus } from 'node:os'
|
||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import { targets as allTargets, fuzzyMatchTarget } from './utils.js'
|
import { targets as allTargets, fuzzyMatchTarget } from './utils.js'
|
||||||
import { scanEnums } from './const-enum.js'
|
import { scanEnums } from './inline-enums.js'
|
||||||
import prettyBytes from 'pretty-bytes'
|
import prettyBytes from 'pretty-bytes'
|
||||||
|
|
||||||
const require = createRequire(import.meta.url)
|
const require = createRequire(import.meta.url)
|
||||||
|
|
|
@ -1,255 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We use rollup-plugin-esbuild for faster builds, but esbuild in isolation
|
|
||||||
* mode compiles const enums into runtime enums, bloating bundle size.
|
|
||||||
*
|
|
||||||
* Here we pre-process all the const enums in the project and turn them into
|
|
||||||
* global replacements, and remove the original declarations and re-exports.
|
|
||||||
*
|
|
||||||
* This erases the const enums before the esbuild transform so that we can
|
|
||||||
* leverage esbuild's speed while retaining the DX and bundle size benefits
|
|
||||||
* of const enums.
|
|
||||||
*
|
|
||||||
* This file is expected to be executed with project root as cwd.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { execaSync } from 'execa'
|
|
||||||
import {
|
|
||||||
existsSync,
|
|
||||||
mkdirSync,
|
|
||||||
readFileSync,
|
|
||||||
rmSync,
|
|
||||||
writeFileSync
|
|
||||||
} from 'node:fs'
|
|
||||||
import { parse } from '@babel/parser'
|
|
||||||
import path from 'node:path'
|
|
||||||
import MagicString from 'magic-string'
|
|
||||||
|
|
||||||
const ENUM_CACHE_PATH = 'temp/enum.json'
|
|
||||||
|
|
||||||
function evaluate(exp) {
|
|
||||||
return new Function(`return ${exp}`)()
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is called in the build script entry once
|
|
||||||
// so the data can be shared across concurrent Rollup processes
|
|
||||||
export function scanEnums() {
|
|
||||||
/**
|
|
||||||
* @type {{ ranges: Record<string, [number, number][]>, defines: Record<string, string>, ids: string[] }}
|
|
||||||
*/
|
|
||||||
const enumData = {
|
|
||||||
ranges: {},
|
|
||||||
defines: {},
|
|
||||||
ids: []
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. grep for files with exported const enum
|
|
||||||
const { stdout } = execaSync('git', ['grep', `export const enum`])
|
|
||||||
const files = [...new Set(stdout.split('\n').map(line => line.split(':')[0]))]
|
|
||||||
|
|
||||||
// 2. parse matched files to collect enum info
|
|
||||||
for (const relativeFile of files) {
|
|
||||||
const file = path.resolve(process.cwd(), relativeFile)
|
|
||||||
const content = readFileSync(file, 'utf-8')
|
|
||||||
const ast = parse(content, {
|
|
||||||
plugins: ['typescript'],
|
|
||||||
sourceType: 'module'
|
|
||||||
})
|
|
||||||
|
|
||||||
for (const node of ast.program.body) {
|
|
||||||
if (
|
|
||||||
node.type === 'ExportNamedDeclaration' &&
|
|
||||||
node.declaration &&
|
|
||||||
node.declaration.type === 'TSEnumDeclaration'
|
|
||||||
) {
|
|
||||||
if (file in enumData.ranges) {
|
|
||||||
// @ts-ignore
|
|
||||||
enumData.ranges[file].push([node.start, node.end])
|
|
||||||
} else {
|
|
||||||
// @ts-ignore
|
|
||||||
enumData.ranges[file] = [[node.start, node.end]]
|
|
||||||
}
|
|
||||||
|
|
||||||
const decl = node.declaration
|
|
||||||
let lastInitialized
|
|
||||||
for (let i = 0; i < decl.members.length; i++) {
|
|
||||||
const e = decl.members[i]
|
|
||||||
const id = decl.id.name
|
|
||||||
if (!enumData.ids.includes(id)) {
|
|
||||||
enumData.ids.push(id)
|
|
||||||
}
|
|
||||||
const key = e.id.type === 'Identifier' ? e.id.name : e.id.value
|
|
||||||
const fullKey = `${id}.${key}`
|
|
||||||
const saveValue = value => {
|
|
||||||
if (fullKey in enumData.defines) {
|
|
||||||
throw new Error(`name conflict for enum ${id} in ${file}`)
|
|
||||||
}
|
|
||||||
enumData.defines[fullKey] = JSON.stringify(value)
|
|
||||||
}
|
|
||||||
const init = e.initializer
|
|
||||||
if (init) {
|
|
||||||
let value
|
|
||||||
if (
|
|
||||||
init.type === 'StringLiteral' ||
|
|
||||||
init.type === 'NumericLiteral'
|
|
||||||
) {
|
|
||||||
value = init.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// e.g. 1 << 2
|
|
||||||
if (init.type === 'BinaryExpression') {
|
|
||||||
const resolveValue = node => {
|
|
||||||
if (
|
|
||||||
node.type === 'NumericLiteral' ||
|
|
||||||
node.type === 'StringLiteral'
|
|
||||||
) {
|
|
||||||
return node.value
|
|
||||||
} else if (node.type === 'MemberExpression') {
|
|
||||||
const exp = content.slice(node.start, node.end)
|
|
||||||
if (!(exp in enumData.defines)) {
|
|
||||||
throw new Error(
|
|
||||||
`unhandled enum initialization expression ${exp} in ${file}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return enumData.defines[exp]
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`unhandled BinaryExpression operand type ${node.type} in ${file}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const exp = `${resolveValue(init.left)}${
|
|
||||||
init.operator
|
|
||||||
}${resolveValue(init.right)}`
|
|
||||||
value = evaluate(exp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init.type === 'UnaryExpression') {
|
|
||||||
if (
|
|
||||||
init.argument.type === 'StringLiteral' ||
|
|
||||||
init.argument.type === 'NumericLiteral'
|
|
||||||
) {
|
|
||||||
const exp = `${init.operator}${init.argument.value}`
|
|
||||||
value = evaluate(exp)
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`unhandled UnaryExpression argument type ${init.argument.type} in ${file}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === undefined) {
|
|
||||||
throw new Error(
|
|
||||||
`unhandled initializer type ${init.type} for ${fullKey} in ${file}`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
saveValue(value)
|
|
||||||
lastInitialized = value
|
|
||||||
} else {
|
|
||||||
if (lastInitialized === undefined) {
|
|
||||||
// first initialized
|
|
||||||
saveValue((lastInitialized = 0))
|
|
||||||
} else if (typeof lastInitialized === 'number') {
|
|
||||||
saveValue(++lastInitialized)
|
|
||||||
} else {
|
|
||||||
// should not happen
|
|
||||||
throw new Error(`wrong enum initialization sequence in ${file}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. save cache
|
|
||||||
if (!existsSync('temp')) mkdirSync('temp')
|
|
||||||
writeFileSync(ENUM_CACHE_PATH, JSON.stringify(enumData))
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
rmSync(ENUM_CACHE_PATH, { force: true })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns {[import('rollup').Plugin, Record<string, string>]}
|
|
||||||
*/
|
|
||||||
export function constEnum() {
|
|
||||||
if (!existsSync(ENUM_CACHE_PATH)) {
|
|
||||||
throw new Error('enum cache needs to be initialized before creating plugin')
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @type {{ ranges: Record<string, [number, number][]>, defines: Record<string, string>, ids: string[] }}
|
|
||||||
*/
|
|
||||||
const enumData = JSON.parse(readFileSync(ENUM_CACHE_PATH, 'utf-8'))
|
|
||||||
|
|
||||||
// construct a regex for matching re-exports of known const enums
|
|
||||||
const reExportsRE = new RegExp(
|
|
||||||
`export {[^}]*?\\b(${enumData.ids.join('|')})\\b[^]*?}`
|
|
||||||
)
|
|
||||||
|
|
||||||
// 3. during transform:
|
|
||||||
// 3.1 files w/ const enum declaration: remove declaration
|
|
||||||
// 3.2 files using const enum: inject into esbuild define
|
|
||||||
/**
|
|
||||||
* @type {import('rollup').Plugin}
|
|
||||||
*/
|
|
||||||
const plugin = {
|
|
||||||
name: 'remove-const-enum',
|
|
||||||
transform(code, id) {
|
|
||||||
let s
|
|
||||||
|
|
||||||
if (id in enumData.ranges) {
|
|
||||||
s = s || new MagicString(code)
|
|
||||||
for (const [start, end] of enumData.ranges[id]) {
|
|
||||||
s.remove(start, end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for const enum re-exports that must be removed
|
|
||||||
if (reExportsRE.test(code)) {
|
|
||||||
s = s || new MagicString(code)
|
|
||||||
const ast = parse(code, {
|
|
||||||
plugins: ['typescript'],
|
|
||||||
sourceType: 'module'
|
|
||||||
})
|
|
||||||
for (const node of ast.program.body) {
|
|
||||||
if (
|
|
||||||
node.type === 'ExportNamedDeclaration' &&
|
|
||||||
node.exportKind !== 'type' &&
|
|
||||||
node.source
|
|
||||||
) {
|
|
||||||
for (let i = 0; i < node.specifiers.length; i++) {
|
|
||||||
const spec = node.specifiers[i]
|
|
||||||
if (
|
|
||||||
spec.type === 'ExportSpecifier' &&
|
|
||||||
spec.exportKind !== 'type' &&
|
|
||||||
enumData.ids.includes(spec.local.name)
|
|
||||||
) {
|
|
||||||
const next = node.specifiers[i + 1]
|
|
||||||
if (next) {
|
|
||||||
// @ts-ignore
|
|
||||||
s.remove(spec.start, next.start)
|
|
||||||
} else {
|
|
||||||
// last one
|
|
||||||
const prev = node.specifiers[i - 1]
|
|
||||||
// @ts-ignore
|
|
||||||
s.remove(prev ? prev.end : spec.start, spec.end)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
return {
|
|
||||||
code: s.toString(),
|
|
||||||
map: s.generateMap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [plugin, enumData.defines]
|
|
||||||
}
|
|
|
@ -41,6 +41,7 @@ const relativeOutfile = relative(process.cwd(), outfile)
|
||||||
|
|
||||||
// resolve externals
|
// resolve externals
|
||||||
// TODO this logic is largely duplicated from rollup.config.js
|
// TODO this logic is largely duplicated from rollup.config.js
|
||||||
|
/** @type {string[]} */
|
||||||
let external = []
|
let external = []
|
||||||
if (!inlineDeps) {
|
if (!inlineDeps) {
|
||||||
// cjs & esm-bundler: external all deps
|
// cjs & esm-bundler: external all deps
|
||||||
|
@ -80,7 +81,7 @@ if (!inlineDeps) {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** @type {Array<import('esbuild').Plugin>} */
|
||||||
const plugins = [
|
const plugins = [
|
||||||
{
|
{
|
||||||
name: 'log-rebuild',
|
name: 'log-rebuild',
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We used const enums before, but it caused some issues: #1228, so we
|
||||||
|
* switched to regular enums. But we still want to keep the zero-cost benefit
|
||||||
|
* of const enums, and minimize the impact on bundle size as much as possible.
|
||||||
|
*
|
||||||
|
* Here we pre-process all the enums in the project and turn them into
|
||||||
|
* global replacements, and rewrite the original declarations as object literals.
|
||||||
|
*
|
||||||
|
* This file is expected to be executed with project root as cwd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as assert from 'node:assert'
|
||||||
|
import {
|
||||||
|
existsSync,
|
||||||
|
mkdirSync,
|
||||||
|
readFileSync,
|
||||||
|
rmSync,
|
||||||
|
writeFileSync
|
||||||
|
} from 'node:fs'
|
||||||
|
import * as path from 'node:path'
|
||||||
|
import { parse } from '@babel/parser'
|
||||||
|
import { execaSync } from 'execa'
|
||||||
|
import MagicString from 'magic-string'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{ readonly name: string, readonly value: string | number }} EnumMember
|
||||||
|
* @typedef {{ readonly id: string, readonly range: readonly [start: number, end: number], readonly members: ReadonlyArray<EnumMember>}} EnumDeclaration
|
||||||
|
* @typedef {{ readonly declarations: { readonly [file: string] : ReadonlyArray<EnumDeclaration>}, readonly defines: { readonly [ id_key: `${string}.${string}`]: string } }} EnumData
|
||||||
|
*/
|
||||||
|
|
||||||
|
const ENUM_CACHE_PATH = 'temp/enum.json'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} exp
|
||||||
|
* @returns {string | number}
|
||||||
|
*/
|
||||||
|
function evaluate(exp) {
|
||||||
|
return new Function(`return ${exp}`)()
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is called in the build script entry once
|
||||||
|
// so the data can be shared across concurrent Rollup processes
|
||||||
|
export function scanEnums() {
|
||||||
|
/** @type {{ [file: string]: EnumDeclaration[] }} */
|
||||||
|
const declarations = Object.create(null)
|
||||||
|
/** @type {{ [id_key: `${string}.${string}`]: string; }} */
|
||||||
|
const defines = Object.create(null)
|
||||||
|
|
||||||
|
// 1. grep for files with exported enum
|
||||||
|
const { stdout } = execaSync('git', ['grep', `export enum`])
|
||||||
|
const files = [...new Set(stdout.split('\n').map(line => line.split(':')[0]))]
|
||||||
|
|
||||||
|
// 2. parse matched files to collect enum info
|
||||||
|
for (const relativeFile of files) {
|
||||||
|
const file = path.resolve(process.cwd(), relativeFile)
|
||||||
|
const content = readFileSync(file, 'utf-8')
|
||||||
|
const ast = parse(content, {
|
||||||
|
plugins: ['typescript'],
|
||||||
|
sourceType: 'module'
|
||||||
|
})
|
||||||
|
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
const enumIds = new Set()
|
||||||
|
for (const node of ast.program.body) {
|
||||||
|
if (
|
||||||
|
node.type === 'ExportNamedDeclaration' &&
|
||||||
|
node.declaration &&
|
||||||
|
node.declaration.type === 'TSEnumDeclaration'
|
||||||
|
) {
|
||||||
|
const decl = node.declaration
|
||||||
|
const id = decl.id.name
|
||||||
|
if (enumIds.has(id)) {
|
||||||
|
throw new Error(
|
||||||
|
`not support declaration merging for enum ${id} in ${file}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
enumIds.add(id)
|
||||||
|
/** @type {string | number | undefined} */
|
||||||
|
let lastInitialized
|
||||||
|
/** @type {Array<EnumMember>} */
|
||||||
|
const members = []
|
||||||
|
|
||||||
|
for (let i = 0; i < decl.members.length; i++) {
|
||||||
|
const e = decl.members[i]
|
||||||
|
const key = e.id.type === 'Identifier' ? e.id.name : e.id.value
|
||||||
|
const fullKey = /** @type {const} */ (`${id}.${key}`)
|
||||||
|
const saveValue = (/** @type {string | number} */ value) => {
|
||||||
|
// We need allow same name enum in different file.
|
||||||
|
// For example: enum ErrorCodes exist in both @vue/compiler-core and @vue/runtime-core
|
||||||
|
// But not allow `ErrorCodes.__EXTEND_POINT__` appear in two same name enum
|
||||||
|
if (fullKey in defines) {
|
||||||
|
throw new Error(`name conflict for enum ${id} in ${file}`)
|
||||||
|
}
|
||||||
|
members.push({
|
||||||
|
name: key,
|
||||||
|
value
|
||||||
|
})
|
||||||
|
defines[fullKey] = JSON.stringify(value)
|
||||||
|
}
|
||||||
|
const init = e.initializer
|
||||||
|
if (init) {
|
||||||
|
/** @type {string | number} */
|
||||||
|
let value
|
||||||
|
if (
|
||||||
|
init.type === 'StringLiteral' ||
|
||||||
|
init.type === 'NumericLiteral'
|
||||||
|
) {
|
||||||
|
value = init.value
|
||||||
|
}
|
||||||
|
// e.g. 1 << 2
|
||||||
|
else if (init.type === 'BinaryExpression') {
|
||||||
|
const resolveValue = (
|
||||||
|
/** @type {import('@babel/types').Expression | import('@babel/types').PrivateName} */ node
|
||||||
|
) => {
|
||||||
|
assert.ok(typeof node.start === 'number')
|
||||||
|
assert.ok(typeof node.end === 'number')
|
||||||
|
if (
|
||||||
|
node.type === 'NumericLiteral' ||
|
||||||
|
node.type === 'StringLiteral'
|
||||||
|
) {
|
||||||
|
return node.value
|
||||||
|
} else if (node.type === 'MemberExpression') {
|
||||||
|
const exp = /** @type {`${string}.${string}`} */ (
|
||||||
|
content.slice(node.start, node.end)
|
||||||
|
)
|
||||||
|
if (!(exp in defines)) {
|
||||||
|
throw new Error(
|
||||||
|
`unhandled enum initialization expression ${exp} in ${file}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return defines[exp]
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`unhandled BinaryExpression operand type ${node.type} in ${file}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const exp = `${resolveValue(init.left)}${
|
||||||
|
init.operator
|
||||||
|
}${resolveValue(init.right)}`
|
||||||
|
value = evaluate(exp)
|
||||||
|
} else if (init.type === 'UnaryExpression') {
|
||||||
|
if (
|
||||||
|
init.argument.type === 'StringLiteral' ||
|
||||||
|
init.argument.type === 'NumericLiteral'
|
||||||
|
) {
|
||||||
|
const exp = `${init.operator}${init.argument.value}`
|
||||||
|
value = evaluate(exp)
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`unhandled UnaryExpression argument type ${init.argument.type} in ${file}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`unhandled initializer type ${init.type} for ${fullKey} in ${file}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
lastInitialized = value
|
||||||
|
saveValue(lastInitialized)
|
||||||
|
} else {
|
||||||
|
if (lastInitialized === undefined) {
|
||||||
|
// first initialized
|
||||||
|
lastInitialized = 0
|
||||||
|
saveValue(lastInitialized)
|
||||||
|
} else if (typeof lastInitialized === 'number') {
|
||||||
|
lastInitialized++
|
||||||
|
saveValue(lastInitialized)
|
||||||
|
} else {
|
||||||
|
// should not happen
|
||||||
|
throw new Error(`wrong enum initialization sequence in ${file}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file in declarations)) {
|
||||||
|
declarations[file] = []
|
||||||
|
}
|
||||||
|
assert.ok(typeof node.start === 'number')
|
||||||
|
assert.ok(typeof node.end === 'number')
|
||||||
|
declarations[file].push({
|
||||||
|
id,
|
||||||
|
range: [node.start, node.end],
|
||||||
|
members
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. save cache
|
||||||
|
if (!existsSync('temp')) mkdirSync('temp')
|
||||||
|
|
||||||
|
/** @type {EnumData} */
|
||||||
|
const enumData = {
|
||||||
|
declarations,
|
||||||
|
defines
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFileSync(ENUM_CACHE_PATH, JSON.stringify(enumData))
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
rmSync(ENUM_CACHE_PATH, { force: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {[import('rollup').Plugin, Record<string, string>]}
|
||||||
|
*/
|
||||||
|
export function inlineEnums() {
|
||||||
|
if (!existsSync(ENUM_CACHE_PATH)) {
|
||||||
|
throw new Error('enum cache needs to be initialized before creating plugin')
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @type {EnumData}
|
||||||
|
*/
|
||||||
|
const enumData = JSON.parse(readFileSync(ENUM_CACHE_PATH, 'utf-8'))
|
||||||
|
|
||||||
|
// 3. during transform:
|
||||||
|
// 3.1 files w/ enum declaration: rewrite declaration as object literal
|
||||||
|
// 3.2 files using enum: inject into esbuild define
|
||||||
|
/**
|
||||||
|
* @type {import('rollup').Plugin}
|
||||||
|
*/
|
||||||
|
const plugin = {
|
||||||
|
name: 'inline-enum',
|
||||||
|
transform(code, id) {
|
||||||
|
/**
|
||||||
|
* @type {MagicString | undefined}
|
||||||
|
*/
|
||||||
|
let s
|
||||||
|
|
||||||
|
if (id in enumData.declarations) {
|
||||||
|
s = s || new MagicString(code)
|
||||||
|
for (const declaration of enumData.declarations[id]) {
|
||||||
|
const {
|
||||||
|
range: [start, end],
|
||||||
|
id,
|
||||||
|
members
|
||||||
|
} = declaration
|
||||||
|
s.update(
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
`export const ${id} = {${members
|
||||||
|
.flatMap(({ name, value }) => {
|
||||||
|
const forwardMapping =
|
||||||
|
JSON.stringify(name) + ': ' + JSON.stringify(value)
|
||||||
|
const reverseMapping =
|
||||||
|
JSON.stringify(value.toString()) + ': ' + JSON.stringify(name)
|
||||||
|
|
||||||
|
// see https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings
|
||||||
|
return typeof value === 'string'
|
||||||
|
? [
|
||||||
|
forwardMapping
|
||||||
|
// string enum members do not get a reverse mapping generated at all
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
forwardMapping,
|
||||||
|
// other enum members should support enum reverse mapping
|
||||||
|
reverseMapping
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.join(',\n')}}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
return {
|
||||||
|
code: s.toString(),
|
||||||
|
map: s.generateMap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [plugin, enumData.defines]
|
||||||
|
}
|
|
@ -10,6 +10,8 @@
|
||||||
"packages/runtime-test",
|
"packages/runtime-test",
|
||||||
"packages/template-explorer",
|
"packages/template-explorer",
|
||||||
"packages/sfc-playground",
|
"packages/sfc-playground",
|
||||||
"packages/dts-test"
|
"packages/dts-test",
|
||||||
|
"rollup.config.js",
|
||||||
|
"scripts/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"useDefineForClassFields": false,
|
"useDefineForClassFields": false,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowJs": false,
|
"allowJs": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
@ -34,6 +34,8 @@
|
||||||
"packages/*/__tests__",
|
"packages/*/__tests__",
|
||||||
"packages/dts-test",
|
"packages/dts-test",
|
||||||
"packages/vue/jsx-runtime",
|
"packages/vue/jsx-runtime",
|
||||||
"scripts/setupVitest.ts"
|
"scripts/*",
|
||||||
]
|
"rollup.*.js"
|
||||||
|
],
|
||||||
|
"exclude": ["rollup.config.js", "scripts/*"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue