Skip to content

Commit

Permalink
feat(types): add types for vue-template-compiler (#7918)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktsn authored and yyx990803 committed Dec 11, 2018
1 parent 5f275d1 commit 0c40261
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/vue-template-compiler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"unpkg": "browser.js",
"jsdelivr": "browser.js",
"browser": "browser.js",
"types": "types/index.d.ts",
"repository": {
"type": "git",
"url": "git+https://github.com/vuejs/vue.git"
Expand All @@ -23,5 +24,8 @@
"dependencies": {
"he": "^1.1.0",
"de-indent": "^1.0.2"
},
"devDependencies": {
"vue": "file:../.."
}
}
221 changes: 221 additions & 0 deletions packages/vue-template-compiler/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -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;
60 changes: 60 additions & 0 deletions packages/vue-template-compiler/types/test.ts
Original file line number Diff line number Diff line change
@@ -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");
13 changes: 13 additions & 0 deletions packages/vue-template-compiler/types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"strict": true,
"noEmit": true
},
"compileOnSave": false,
"include": [
"**/*.ts"
]
}

0 comments on commit 0c40261

Please sign in to comment.