diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index dd2372c6..250fde48 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -1,4 +1,5 @@ -import { parse, ParserOptions, TextModes } from '../src/parse' +import { ParserOptions } from '../src/options' +import { parse, TextModes } from '../src/parse' import { ErrorCodes } from '../src/errors' import { CommentNode, diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 7cbbd275..6f7abff5 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -11,7 +11,7 @@ import { FRAGMENT } from './runtimeHelpers' import { PropsExpression } from './transforms/transformElement' -import { ImportsOption } from './transform' +import { ImportItem } from './transform' // Vue template is a platform-agnostic superset of HTML (syntax only). // More namespaces like SVG and MathML are declared by platform specific @@ -95,7 +95,7 @@ export interface RootNode extends Node { components: string[] directives: string[] hoists: JSChildNode[] - imports: ImportsOption[] + imports: ImportItem[] cached: number codegenNode: TemplateChildNode | JSChildNode | undefined } diff --git a/packages/compiler-core/src/codegen.ts b/packages/compiler-core/src/codegen.ts index 649b5f62..fed61519 100644 --- a/packages/compiler-core/src/codegen.ts +++ b/packages/compiler-core/src/codegen.ts @@ -1,3 +1,4 @@ +import { CodegenOptions } from './options' import { RootNode, TemplateChildNode, @@ -38,31 +39,10 @@ import { CREATE_COMMENT, CREATE_TEXT } from './runtimeHelpers' -import { ImportsOption } from './transform' +import { ImportItem } from './transform' type CodegenNode = TemplateChildNode | JSChildNode -export interface CodegenOptions { - // - Module mode will generate ES module import statements for helpers - // and export the render function as the default export. - // - Function mode will generate a single `const { helpers... } = Vue` - // statement and return the render function. It is meant to be used with - // `new Function(code)()` to generate a render function at runtime. - // Default: 'function' - mode?: 'module' | 'function' - // Prefix suitable identifiers with _ctx. - // If this option is false, the generated code will be wrapped in a - // `with (this) { ... }` block. - // Default: false - prefixIdentifiers?: boolean - // Generate source map? - // Default: false - sourceMap?: boolean - // Filename for source map generation. - // Default: `template.vue.html` - filename?: string -} - export interface CodegenResult { code: string ast: RootNode @@ -332,7 +312,7 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) { }) } -function genImports(importsOptions: ImportsOption[], context: CodegenContext) { +function genImports(importsOptions: ImportItem[], context: CodegenContext) { if (!importsOptions.length) { return } diff --git a/packages/compiler-core/src/index.ts b/packages/compiler-core/src/index.ts index ce4215b9..a91c094b 100644 --- a/packages/compiler-core/src/index.ts +++ b/packages/compiler-core/src/index.ts @@ -1,6 +1,7 @@ -import { parse, ParserOptions } from './parse' -import { transform, TransformOptions } from './transform' -import { generate, CodegenOptions, CodegenResult } from './codegen' +import { CompilerOptions } from './options' +import { parse } from './parse' +import { transform } from './transform' +import { generate, CodegenResult } from './codegen' import { RootNode } from './ast' import { isString } from '@vue/shared' import { transformIf } from './transforms/vIf' @@ -16,8 +17,6 @@ import { transformText } from './transforms/transformText' import { transformOnce } from './transforms/vOnce' import { transformModel } from './transforms/vModel' -export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions - // we name it `baseCompile` so that higher order compilers like @vue/compiler-dom // can export `compile` while re-exporting everything else. export function baseCompile( @@ -75,22 +74,22 @@ export function baseCompile( } // Also expose lower level APIs & types -export { parse, ParserOptions, TextModes } from './parse' +export { + CompilerOptions, + ParserOptions, + TransformOptions, + CodegenOptions +} from './options' +export { parse, TextModes } from './parse' export { transform, createStructuralDirectiveTransform, - TransformOptions, TransformContext, NodeTransform, StructuralDirectiveTransform, DirectiveTransform } from './transform' -export { - generate, - CodegenOptions, - CodegenContext, - CodegenResult -} from './codegen' +export { generate, CodegenContext, CodegenResult } from './codegen' export { ErrorCodes, CoreCompilerError, diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts new file mode 100644 index 00000000..6f7a168b --- /dev/null +++ b/packages/compiler-core/src/options.ts @@ -0,0 +1,67 @@ +import { ElementNode, Namespace } from './ast' +import { TextModes } from './parse' +import { CompilerError } from './errors' +import { NodeTransform, DirectiveTransform } from './transform' + +export interface ParserOptions { + isVoidTag?: (tag: string) => boolean // e.g. img, br, hr + isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex + isPreTag?: (tag: string) => boolean // e.g.
where whitespace is intact + isCustomElement?: (tag: string) => boolean + isBuiltInComponent?: (tag: string) => symbol | void + getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace + getTextMode?: (tag: string, ns: Namespace) => TextModes + delimiters?: [string, string] // ['{{', '}}'] + + // Map to HTML entities. E.g., `{ "amp;": "&" }` + // The full set is https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references + namedCharacterReferences?: Record+ // this number is based on the map above, but it should be pre-computed + // to avoid the cost on every parse() call. + maxCRNameLength?: number + + onError?: (error: CompilerError) => void +} + +export interface TransformOptions { + nodeTransforms?: NodeTransform[] + directiveTransforms?: { [name: string]: DirectiveTransform } + isBuiltInComponent?: (tag: string) => symbol | void + // Transform expressions like {{ foo }} to `_ctx.foo`. + // Default: mode === 'module' + prefixIdentifiers?: boolean + // Hoist static VNodes and props objects to `_hoisted_x` constants + // Default: false + hoistStatic?: boolean + // Cache v-on handlers to avoid creating new inline functions on each render, + // also avoids the need for dynamically patching the handlers by wrapping it. + // e.g `@click="foo"` by default is compiled to `{ onClick: foo }`. With this + // option it's compiled to: + // `{ onClick: _cache[0] || (_cache[0] = e => _ctx.foo(e)) }` + // Default: false + cacheHandlers?: boolean + onError?: (error: CompilerError) => void +} + +export interface CodegenOptions { + // - Module mode will generate ES module import statements for helpers + // and export the render function as the default export. + // - Function mode will generate a single `const { helpers... } = Vue` + // statement and return the render function. It is meant to be used with + // `new Function(code)()` to generate a render function at runtime. + // Default: 'function' + mode?: 'module' | 'function' + // Prefix suitable identifiers with _ctx. + // If this option is false, the generated code will be wrapped in a + // `with (this) { ... }` block. + // Default: false + prefixIdentifiers?: boolean + // Generate source map? + // Default: false + sourceMap?: boolean + // Filename for source map generation. + // Default: `template.vue.html` + filename?: string +} + +export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index 99008e01..6ed4e8bb 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -1,10 +1,6 @@ +import { ParserOptions } from './options' import { NO, isArray } from '@vue/shared' -import { - ErrorCodes, - createCompilerError, - defaultOnError, - CompilerError -} from './errors' +import { ErrorCodes, createCompilerError, defaultOnError } from './errors' import { assert, advancePositionWithMutation, @@ -12,7 +8,6 @@ import { isCoreComponent } from './utils' import { - Namespace, Namespaces, AttributeNode, CommentNode, @@ -30,26 +25,6 @@ import { } from './ast' import { extend } from '@vue/shared' -export interface ParserOptions { - isVoidTag?: (tag: string) => boolean // e.g. img, br, hr - isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex - isPreTag?: (tag: string) => boolean // e.g. where whitespace is intact - isCustomElement?: (tag: string) => boolean - isBuiltInComponent?: (tag: string) => symbol | void - getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace - getTextMode?: (tag: string, ns: Namespace) => TextModes - delimiters?: [string, string] // ['{{', '}}'] - - // Map to HTML entities. E.g., `{ "amp;": "&" }` - // The full set is https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references - namedCharacterReferences?: Record- // this number is based on the map above, but it should be pre-computed - // to avoid the cost on every parse() call. - maxCRNameLength?: number - - onError?: (error: CompilerError) => void -} - // `isNativeTag` is optional, others are required type OptionalOptions = 'isNativeTag' | 'isBuiltInComponent' type MergedParserOptions = Omit , OptionalOptions> & diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 5038cee1..0c01cd84 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -1,3 +1,4 @@ +import { TransformOptions } from './options' import { RootNode, NodeTypes, @@ -18,7 +19,7 @@ import { createCacheExpression } from './ast' import { isString, isArray, NOOP } from '@vue/shared' -import { CompilerError, defaultOnError } from './errors' +import { defaultOnError } from './errors' import { TO_STRING, FRAGMENT, @@ -65,17 +66,7 @@ export type StructuralDirectiveTransform = ( context: TransformContext ) => void | (() => void) -export interface TransformOptions { - nodeTransforms?: NodeTransform[] - directiveTransforms?: { [name: string]: DirectiveTransform } - isBuiltInComponent?: (tag: string) => symbol | void - prefixIdentifiers?: boolean - hoistStatic?: boolean - cacheHandlers?: boolean - onError?: (error: CompilerError) => void -} - -export interface ImportsOption { +export interface ImportItem { exp: string | ExpressionNode path: string } @@ -86,7 +77,7 @@ export interface TransformContext extends Required { components: Set directives: Set hoists: JSChildNode[] - imports: Set + imports: Set cached: number identifiers: { [name: string]: number | undefined } scopes: {