行文介绍

本文主要介绍vue中template compile的主体思路和源码流程。

适合想要梳理模板编译对应的源码函数调用流程的童鞋。为大家滤清思路。

具体的分析请查看文末参考链接。

主体思路

三步走:

  1. 将模板解析为AST。parseparse使用正则等方式解析template模板中的指令,class,style等数据,形成AST
  2. 优化AST。optimize主要作用是标记static静态节点,后面当update更新界面时,会有diff的过程,会直接跳过静态节点,从而减少比较过程,优化patch性能。
  3. 将AST转换为render函数。generate。将AST转换为render function字符串,得到结果是render字符串以及staticRenderFns字符串。

源码函数调用流程

整个源码非常贴近函数式编程,但是也导致阅读理解的成本很高,基本都是高阶函数,函数被传入传出的,很容易被绕晕。

但是抓住核心就行,createCompiler 函数。

核心函数

createCompiler

简要流程

compileToFunctions
<==
createCompiler
<==
createCompilerCreator
<==
createCompileToFunctionFn
<==
createFunction

详细流程

// src/platforms/web/entry-runtime-with-compiler.js
const { render, staticRenderFns } = compileToFunctions(template, {
    outputSourceRange: process.env.NODE_ENV !== 'production',
    shouldDecodeNewlines,
    shouldDecodeNewlinesForHref,
    delimiters: options.delimiters,
    comments: options.comments
}, this)


// src/platforms/web/compiler/index.js
const { compile, compileToFunctions } = createCompiler(baseOptions)


// src/compiler/index.js
export const createCompiler = createCompilerCreator(function baseCompile (
  template: string,
  options: CompilerOptions
): CompiledResult {
  // 三步走 parse optimize generate
  const ast = parse(template.trim(), options)
  if (options.optimize !== false) {
    optimize(ast, options)
  }
  const code = generate(ast, options)
  return {
    ast,
    render: code.render,
    staticRenderFns: code.staticRenderFns
  }
})


// src/compiler/create-compiler.js
export function createCompilerCreator (baseCompile: Function): Function {
  return function createCompiler (baseOptions: CompilerOptions) {
    function compile (
      template: string,
      options?: CompilerOptions
    ): CompiledResult {
    
        const compiled = baseCompile(template.trim(), finalOptions)
        ...
        return compiled
        
    }
    
    return {
      compile,
      // 真实使用的是这个函数compileToFunctions
      compileToFunctions: createCompileToFunctionFn(compile)
    }
  }
}

// src/compiler/to-function.js
export function createCompileToFunctionFn (compile: Function): Function {

    return function compileToFunctions (
        template: string,
        options?: CompilerOptions,
        vm?: Component
    ): CompiledFunctionResult {
        
         // compile
        const compiled = compile(template, options)
    
        res.render = createFunction(compiled.render, fnGenErrors)
        
        return (cache[key] = res)
    }
}


// src/compiler/to-function.js
function createFunction (code, errors) {
  try {
    return new Function(code)
  } catch (err) {
    errors.push({ err, code })
    return noop
  }
}

参考链接

https://github.com/answershut... 【这篇文章不错,推荐阅读】


littlelightss
406 声望14 粉丝