Browse Source

progress

dev
Evan You 8 years ago
parent
commit
a00e4d3cbf
  1. 55
      src/compiler/create-compiler.js
  2. 58
      src/compiler/index.js
  3. 18
      src/compiler/to-function.js
  4. 1
      src/platforms/web/entry-compiler.js
  5. 11
      src/platforms/web/server/compiler.js
  6. 22
      src/server/optimizing-compiler/codegen.js
  7. 53
      src/server/optimizing-compiler/index.js

55
src/compiler/create-compiler.js

@ -0,0 +1,55 @@
/* @flow */
import { extend } from 'shared/util'
import { detectErrors } from './error-detector'
import { createCompileToFunctionFn } from './to-function'
export function createCompilerCreator (baseCompile: Function): Function {
return function createCompiler (baseOptions: CompilerOptions) {
function compile (
template: string,
options?: CompilerOptions
): CompiledResult {
const finalOptions = Object.create(baseOptions)
const errors = []
const tips = []
finalOptions.warn = (msg, tip) => {
(tip ? tips : errors).push(msg)
}
if (options) {
// merge custom modules
if (options.modules) {
finalOptions.modules =
(baseOptions.modules || []).concat(options.modules)
}
// merge custom directives
if (options.directives) {
finalOptions.directives = extend(
Object.create(baseOptions.directives),
options.directives
)
}
// copy other options
for (const key in options) {
if (key !== 'modules' && key !== 'directives') {
finalOptions[key] = options[key]
}
}
}
const compiled = baseCompile(template, finalOptions)
if (process.env.NODE_ENV !== 'production') {
errors.push.apply(errors, detectErrors(compiled.ast))
}
compiled.errors = errors
compiled.tips = tips
return compiled
}
return {
compile,
compileToFunctions: createCompileToFunctionFn(compile)
}
}
}

58
src/compiler/index.js

@ -1,13 +1,14 @@
/* @flow */ /* @flow */
import { extend } from 'shared/util'
import { parse } from './parser/index' import { parse } from './parser/index'
import { optimize } from './optimizer' import { optimize } from './optimizer'
import { generate } from './codegen/index' import { generate } from './codegen/index'
import { detectErrors } from './error-detector' import { createCompilerCreator } from './create-compiler'
import { createCompileToFunctionFn } from './to-function'
function baseCompile ( // `createCompilerCreator` allows creating compilers that use alternative
// parser/optimizer/codegen, e.g the SSR optimizing compiler.
// Here we just export a default compiler using the default parts.
export const createCompiler = createCompilerCreator(function baseCompile (
template: string, template: string,
options: CompilerOptions options: CompilerOptions
): CompiledResult { ): CompiledResult {
@ -19,51 +20,4 @@ function baseCompile (
render: code.render, render: code.render,
staticRenderFns: code.staticRenderFns staticRenderFns: code.staticRenderFns
} }
} })
export function createCompiler (baseOptions: CompilerOptions) {
function compile (
template: string,
options?: CompilerOptions
): CompiledResult {
const finalOptions = Object.create(baseOptions)
const errors = []
const tips = []
finalOptions.warn = (msg, tip) => {
(tip ? tips : errors).push(msg)
}
if (options) {
// merge custom modules
if (options.modules) {
finalOptions.modules = (baseOptions.modules || []).concat(options.modules)
}
// merge custom directives
if (options.directives) {
finalOptions.directives = extend(
Object.create(baseOptions.directives),
options.directives
)
}
// copy other options
for (const key in options) {
if (key !== 'modules' && key !== 'directives') {
finalOptions[key] = options[key]
}
}
}
const compiled = baseCompile(template, finalOptions)
if (process.env.NODE_ENV !== 'production') {
errors.push.apply(errors, detectErrors(compiled.ast))
}
compiled.errors = errors
compiled.tips = tips
return compiled
}
return {
compile,
compileToFunctions: createCompileToFunctionFn(compile)
}
}

18
src/compiler/to-function.js

@ -3,6 +3,12 @@
import { noop } from 'shared/util' import { noop } from 'shared/util'
import { warn, tip } from 'core/util/debug' import { warn, tip } from 'core/util/debug'
type CompiledFunctionResult = {
render: Function;
staticRenderFns: Array<Function>;
stringRenderFns?: Array<Function>;
};
function createFunction (code, errors) { function createFunction (code, errors) {
try { try {
return new Function(code) return new Function(code)
@ -71,10 +77,14 @@ export function createCompileToFunctionFn (compile: Function): Function {
const res = {} const res = {}
const fnGenErrors = [] const fnGenErrors = []
res.render = createFunction(compiled.render, fnGenErrors) res.render = createFunction(compiled.render, fnGenErrors)
const l = compiled.staticRenderFns.length res.staticRenderFns = compiled.staticRenderFns.map(code => {
res.staticRenderFns = new Array(l) return createFunction(code, fnGenErrors)
for (let i = 0; i < l; i++) { })
res.staticRenderFns[i] = createFunction(compiled.staticRenderFns[i], fnGenErrors) // ssr-specific
if (res.stringRenderFns) {
res.stringRenderFns = compiled.stringRenderFns.map(code => {
return createFunction(code, fnGenErrors)
})
} }
// check function generation errors. // check function generation errors.

1
src/platforms/web/entry-compiler.js

@ -2,3 +2,4 @@
export { parseComponent } from 'sfc/parser' export { parseComponent } from 'sfc/parser'
export { compile, compileToFunctions } from './compiler/index' export { compile, compileToFunctions } from './compiler/index'
export { ssrCompile, ssrCompileToFunctions } from './server/compiler'

11
src/platforms/web/server/compiler.js

@ -0,0 +1,11 @@
/* @flow */
import { baseOptions } from '../compiler/options'
import { createCompiler } from 'server/optimizing-compiler/index'
const { compile, compileToFunctions } = createCompiler(baseOptions)
export {
compile as ssrCompile,
compileToFunctions as ssrCompileToFunctions
}

22
src/server/optimizing-compiler/codegen.js

@ -1,7 +1,11 @@
/* @flow */ /* @flow */
// The SSR codegen is essentially extending the default codegen to handle
// SSR-optimizable nodes and turn them into string render fns. In cases where
// a node is not optimizable it simply falls back to the default codegen.
// import * as directives from './directives' // import * as directives from './directives'
import { CodegenState } from 'compiler/codegen/index' import { CodegenState, genElement } from 'compiler/codegen/index'
type SSRCompileResult = { type SSRCompileResult = {
render: string; render: string;
@ -23,7 +27,7 @@ export function generate (
options: CompilerOptions options: CompilerOptions
): SSRCompileResult { ): SSRCompileResult {
const state = new SSRCodegenState(options) const state = new SSRCodegenState(options)
const code = ast ? genElement(ast, state) : '_c("div")' const code = ast ? genSSRElement(ast, state, true) : '_c("div")'
return { return {
render: `with(this){return ${code}}`, render: `with(this){return ${code}}`,
staticRenderFns: state.staticRenderFns, staticRenderFns: state.staticRenderFns,
@ -31,6 +35,18 @@ export function generate (
} }
} }
function genElement (el: ASTElement, state: SSRCodegenState): string { function genSSRElement (
el: ASTElement,
state: SSRCodegenState,
isComponentRoot?: boolean
): string {
if (el.ssrOptimizableRoot && !isComponentRoot) {
return genStringRenderFn(el, state)
} else {
return genElement(el, state)
}
}
function genStringRenderFn (el, state) {
return ''
} }

53
src/server/optimizing-compiler/index.js

@ -1,13 +1,11 @@
/* @flow */ /* @flow */
import { extend } from 'shared/util'
import { parse } from 'compiler/parser/index' import { parse } from 'compiler/parser/index'
import { detectErrors } from 'compiler/error-detector'
import { generate } from './codegen' import { generate } from './codegen'
import { optimize } from './optimizer' import { optimize } from './optimizer'
import { createCompilerCreator } from 'compiler/create-compiler'
function baseCompile ( export const createCompiler = createCompilerCreator(function baseCompile (
template: string, template: string,
options: CompilerOptions options: CompilerOptions
): CompiledResult { ): CompiledResult {
@ -17,48 +15,7 @@ function baseCompile (
return { return {
ast, ast,
render: code.render, render: code.render,
staticRenderFns: code.staticRenderFns staticRenderFns: code.staticRenderFns,
} stringRenderFns: code.stringRenderFns
}
export function createCompiler (baseOptions: CompilerOptions) {
return function compile (
template: string,
options?: CompilerOptions
): CompiledResult {
const finalOptions = Object.create(baseOptions)
const errors = []
const tips = []
finalOptions.warn = (msg, tip) => {
(tip ? tips : errors).push(msg)
}
if (options) {
// merge custom modules
if (options.modules) {
finalOptions.modules = (baseOptions.modules || []).concat(options.modules)
}
// merge custom directives
if (options.directives) {
finalOptions.directives = extend(
Object.create(baseOptions.directives),
options.directives
)
}
// copy other options
for (const key in options) {
if (key !== 'modules' && key !== 'directives') {
finalOptions[key] = options[key]
}
}
}