mirror of https://github.com/vuejs/vue.git
feat(types): add types for vue-template-compiler (#7918)
This commit is contained in:
parent
57910723c6
commit
ced774be6d
|
@ -6,6 +6,7 @@
|
||||||
"unpkg": "browser.js",
|
"unpkg": "browser.js",
|
||||||
"jsdelivr": "browser.js",
|
"jsdelivr": "browser.js",
|
||||||
"browser": "browser.js",
|
"browser": "browser.js",
|
||||||
|
"types": "types/index.d.ts",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/vuejs/vue.git"
|
"url": "git+https://github.com/vuejs/vue.git"
|
||||||
|
@ -23,5 +24,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"he": "^1.1.0",
|
"he": "^1.1.0",
|
||||||
"de-indent": "^1.0.2"
|
"de-indent": "^1.0.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"vue": "file:../.."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
import Vue, { VNode } from "vue"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Template compilation options / results
|
||||||
|
*/
|
||||||
|
interface CompilerOptions {
|
||||||
|
modules?: ModuleOptions[];
|
||||||
|
directives?: Record<string, DirectiveFunction>;
|
||||||
|
preserveWhitespace?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CompiledResult {
|
||||||
|
ast: ASTElement | undefined;
|
||||||
|
render: string;
|
||||||
|
staticRenderFns: string[];
|
||||||
|
errors: string[];
|
||||||
|
tips: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CompiledResultFunctions {
|
||||||
|
render: () => VNode;
|
||||||
|
staticRenderFns: (() => VNode)[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModuleOptions {
|
||||||
|
preTransformNode: (el: ASTElement) => ASTElement | undefined;
|
||||||
|
transformNode: (el: ASTElement) => ASTElement | undefined;
|
||||||
|
postTransformNode: (el: ASTElement) => void;
|
||||||
|
genData: (el: ASTElement) => string;
|
||||||
|
transformCode?: (el: ASTElement, code: string) => string;
|
||||||
|
staticKeys?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type DirectiveFunction = (node: ASTElement, directiveMeta: ASTDirective) => void;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AST Types
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* - 0: FALSE - whole sub tree un-optimizable
|
||||||
|
* - 1: FULL - whole sub tree optimizable
|
||||||
|
* - 2: SELF - self optimizable but has some un-optimizable children
|
||||||
|
* - 3: CHILDREN - self un-optimizable but have fully optimizable children
|
||||||
|
* - 4: PARTIAL - self un-optimizable with some un-optimizable children
|
||||||
|
*/
|
||||||
|
export type SSROptimizability = 0 | 1 | 2 | 3 | 4
|
||||||
|
|
||||||
|
export interface ASTModifiers {
|
||||||
|
[key: string]: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTIfCondition {
|
||||||
|
exp: string | undefined;
|
||||||
|
block: ASTElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTElementHandler {
|
||||||
|
value: string;
|
||||||
|
params?: any[];
|
||||||
|
modifiers: ASTModifiers | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTElementHandlers {
|
||||||
|
[key: string]: ASTElementHandler | ASTElementHandler[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTDirective {
|
||||||
|
name: string;
|
||||||
|
rawName: string;
|
||||||
|
value: string;
|
||||||
|
arg: string | undefined;
|
||||||
|
modifiers: ASTModifiers | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ASTNode = ASTElement | ASTText | ASTExpression;
|
||||||
|
|
||||||
|
export interface ASTElement {
|
||||||
|
type: 1;
|
||||||
|
tag: string;
|
||||||
|
attrsList: { name: string; value: any }[];
|
||||||
|
attrsMap: Record<string, any>;
|
||||||
|
parent: ASTElement | undefined;
|
||||||
|
children: ASTNode[];
|
||||||
|
|
||||||
|
processed?: true;
|
||||||
|
|
||||||
|
static?: boolean;
|
||||||
|
staticRoot?: boolean;
|
||||||
|
staticInFor?: boolean;
|
||||||
|
staticProcessed?: boolean;
|
||||||
|
hasBindings?: boolean;
|
||||||
|
|
||||||
|
text?: string;
|
||||||
|
attrs?: { name: string; value: any }[];
|
||||||
|
props?: { name: string; value: string }[];
|
||||||
|
plain?: boolean;
|
||||||
|
pre?: true;
|
||||||
|
ns?: string;
|
||||||
|
|
||||||
|
component?: string;
|
||||||
|
inlineTemplate?: true;
|
||||||
|
transitionMode?: string | null;
|
||||||
|
slotName?: string;
|
||||||
|
slotTarget?: string;
|
||||||
|
slotScope?: string;
|
||||||
|
scopedSlots?: Record<string, ASTElement>;
|
||||||
|
|
||||||
|
ref?: string;
|
||||||
|
refInFor?: boolean;
|
||||||
|
|
||||||
|
if?: string;
|
||||||
|
ifProcessed?: boolean;
|
||||||
|
elseif?: string;
|
||||||
|
else?: true;
|
||||||
|
ifConditions?: ASTIfCondition[];
|
||||||
|
|
||||||
|
for?: string;
|
||||||
|
forProcessed?: boolean;
|
||||||
|
key?: string;
|
||||||
|
alias?: string;
|
||||||
|
iterator1?: string;
|
||||||
|
iterator2?: string;
|
||||||
|
|
||||||
|
staticClass?: string;
|
||||||
|
classBinding?: string;
|
||||||
|
staticStyle?: string;
|
||||||
|
styleBinding?: string;
|
||||||
|
events?: ASTElementHandlers;
|
||||||
|
nativeEvents?: ASTElementHandlers;
|
||||||
|
|
||||||
|
transition?: string | true;
|
||||||
|
transitionOnAppear?: boolean;
|
||||||
|
|
||||||
|
model?: {
|
||||||
|
value: string;
|
||||||
|
callback: string;
|
||||||
|
expression: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
directives?: ASTDirective[];
|
||||||
|
|
||||||
|
forbidden?: true;
|
||||||
|
once?: true;
|
||||||
|
onceProcessed?: boolean;
|
||||||
|
wrapData?: (code: string) => string;
|
||||||
|
wrapListeners?: (code: string) => string;
|
||||||
|
|
||||||
|
// 2.4 ssr optimization
|
||||||
|
ssrOptimizability?: SSROptimizability;
|
||||||
|
|
||||||
|
// weex specific
|
||||||
|
appendAsTree?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTExpression {
|
||||||
|
type: 2;
|
||||||
|
expression: string;
|
||||||
|
text: string;
|
||||||
|
tokens: (string | Record<string, any>)[];
|
||||||
|
static?: boolean;
|
||||||
|
// 2.4 ssr optimization
|
||||||
|
ssrOptimizability?: SSROptimizability;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ASTText {
|
||||||
|
type: 3;
|
||||||
|
text: string;
|
||||||
|
static?: boolean;
|
||||||
|
isComment?: boolean;
|
||||||
|
// 2.4 ssr optimization
|
||||||
|
ssrOptimizability?: SSROptimizability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SFC parser related types
|
||||||
|
*/
|
||||||
|
interface SFCParserOptions {
|
||||||
|
pad?: true | 'line' | 'space';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SFCBlock {
|
||||||
|
type: string;
|
||||||
|
content: string;
|
||||||
|
attrs: Record<string, string>;
|
||||||
|
start?: number;
|
||||||
|
end?: number;
|
||||||
|
lang?: string;
|
||||||
|
src?: string;
|
||||||
|
scoped?: boolean;
|
||||||
|
module?: string | boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SFCDescriptor {
|
||||||
|
template: SFCBlock | undefined;
|
||||||
|
script: SFCBlock | undefined;
|
||||||
|
styles: SFCBlock[];
|
||||||
|
customBlocks: SFCBlock[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exposed functions
|
||||||
|
*/
|
||||||
|
export function compile(
|
||||||
|
template: string,
|
||||||
|
options?: CompilerOptions
|
||||||
|
): CompiledResult;
|
||||||
|
|
||||||
|
export function compileToFunctions(template: string): CompiledResultFunctions;
|
||||||
|
|
||||||
|
export function ssrCompile(
|
||||||
|
template: string,
|
||||||
|
options?: CompilerOptions
|
||||||
|
): CompiledResult;
|
||||||
|
|
||||||
|
export function ssrCompileToFunctions(template: string): CompiledResultFunctions;
|
||||||
|
|
||||||
|
export function parseComponent(
|
||||||
|
file: string,
|
||||||
|
options?: SFCParserOptions
|
||||||
|
): SFCDescriptor;
|
|
@ -0,0 +1,60 @@
|
||||||
|
import Vue, { VNode } from "vue";
|
||||||
|
import {
|
||||||
|
compile,
|
||||||
|
compileToFunctions,
|
||||||
|
ssrCompile,
|
||||||
|
ssrCompileToFunctions,
|
||||||
|
parseComponent
|
||||||
|
} from "./";
|
||||||
|
|
||||||
|
// check compile options
|
||||||
|
const compiled = compile("<div>hi</div>", {
|
||||||
|
preserveWhitespace: false,
|
||||||
|
modules: [
|
||||||
|
{
|
||||||
|
preTransformNode: el => el,
|
||||||
|
transformNode: el => el,
|
||||||
|
postTransformNode: el => {
|
||||||
|
el.tag = "p";
|
||||||
|
},
|
||||||
|
genData: el => el.tag,
|
||||||
|
transformCode: (el, code) => code,
|
||||||
|
staticKeys: ["test"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
directives: {
|
||||||
|
test: (node, directiveMeta) => {
|
||||||
|
node.tag;
|
||||||
|
directiveMeta.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// can be passed to function constructor
|
||||||
|
new Function(compiled.render);
|
||||||
|
compiled.staticRenderFns.map(fn => new Function(fn));
|
||||||
|
|
||||||
|
const compiledFns = compileToFunctions("<div>hi</div>");
|
||||||
|
|
||||||
|
// can be passed to component render / staticRenderFns options
|
||||||
|
const vm = new Vue({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
test: "Test"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
render: compiledFns.render,
|
||||||
|
staticRenderFns: compiledFns.staticRenderFns
|
||||||
|
});
|
||||||
|
|
||||||
|
// can be called with component instance
|
||||||
|
const vnode: VNode = compiledFns.render.call(vm);
|
||||||
|
|
||||||
|
// check SFC parser
|
||||||
|
const desc = parseComponent("<template></template>", {
|
||||||
|
pad: "space"
|
||||||
|
});
|
||||||
|
|
||||||
|
const templateContent: string = desc.template!.content;
|
||||||
|
const scriptContent: string = desc.script!.content;
|
||||||
|
const styleContent: string = desc.styles.map(s => s.content).join("\n");
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true
|
||||||
|
},
|
||||||
|
"compileOnSave": false,
|
||||||
|
"include": [
|
||||||
|
"**/*.ts"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue