refactor(compiler-core): centralize compiler options

This commit is contained in:
Evan You 2019-12-10 12:53:26 -05:00
parent 03301b264e
commit 5cd1495767
7 changed files with 92 additions and 79 deletions

View File

@ -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,

View File

@ -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
}

View File

@ -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
}

View File

@ -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,

View File

@ -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. <pre> 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<string, string>
// 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

View File

@ -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. <pre> 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<string, string>
// 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<Required<ParserOptions>, OptionalOptions> &

View File

@ -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<TransformOptions> {
components: Set<string>
directives: Set<string>
hoists: JSChildNode[]
imports: Set<ImportsOption>
imports: Set<ImportItem>
cached: number
identifiers: { [name: string]: number | undefined }
scopes: {