current position:Home>Principles of vue3 compiler

Principles of vue3 compiler

2022-06-24 09:21:20yibucuo

1. Execute code

<script src="../../dist/vue.global.js"></script>
<div id="app">
  <div>vue3 compiler principle</div>
  <div>{
    {
    count}}</div>
</div>
<script>
  var {
     createApp } = Vue
  var app = createApp({
    
    data() {
    
      return {
    
        count: 1
      }
    }
  })
  app.mount('#app')
  console.log(app._instance.render);
</script>

Print out the rendering function render

  1. Static cache :_hoisted_1 hold <div>vue3 compiler principle</div> Put it in the cache , Because it doesn't need to be handled
  2. sfc playground
(function anonymous(
) {
    
const _Vue = Vue
const {
     createElementVNode: _createElementVNode } = _Vue

const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "vue3 compiler principle", -1 /* HOISTED */)

return function render(_ctx, _cache) {
    
  with (_ctx) {
    
    const {
     createElementVNode: _createElementVNode, toDisplayString: _toDisplayString, Fragment: _Fragment, openBlock: _openBlock, createElementBlock: _createElementBlock } = _Vue

    return (_openBlock(), _createElementBlock(_Fragment, null, [
      _hoisted_1,
      _createElementVNode("div", null, _toDisplayString(count), 1 /* TEXT */)
    ], 64 /* STABLE_FRAGMENT */))
  }
}
})

2.vue Why do I need a compiler

  1. The compiler is to convert one language into another
  2. vue Is declarative rendering
  3. The compiler will template Compiled into render function ( js )
  4. Front End Developer , Prefer to use html Description view , High development efficiency
  5. performance optimization
    1. Static analysis

3.vue template and react jsx similarities and differences ?

  1. different approaches but equally satisfactory results
    1. Is to generate virtual dom
    2. js、jsx、ts、tsx
    3. Improve front-end programmer view development efficiency
    4. jsx:babel The conversion tool will create Function call , And then finally convert to vdom
    5. template:compile Generate... After compiling the template render function , Execute the build at some future time vdom
  2. Execution time
    1. vue
      1. precompile ( edition and execution environment ) :webpack sfc vue-loader
      2. Runtime (global,browser):template Options , Mount stage
    2. react
    3. translation transpile
  3. performance optimization :vue3 Perform compile time optimization , It can be analyzed statically

4. Compiler execution time

  1. precompile :vue edition esm Combined with packaging tools webpack etc. , combination sfc
  2. Compile at run time
    1. vue edition global、esm-browser、 Compile on Mount
    2. vue/src/index.ts Of compileToFunction
    3. In execution setupComponent when
    4. Will execute finishComponentSetup
    5. Further triggers compile
    6. That's execution compileToFunction

First backup compileToFunction

registerRuntimeCompiler(compileToFunction)
let compile
function registerRuntimeCompiler(_compile) {
    
  compile = _compile //  Put... Here compileToFunction  Deposit in  compile
  installWithProxy = i => {
    
    if (i.render!._rc) {
    
      i.withProxy = new Proxy(i.ctx, RuntimeCompiledPublicInstanceProxyHandlers)
    }
  }
}
function compileToFunction(
  template options
) {
    
  if (!isString(template)) {
     //  This kind of thing is   The user directly enters the node 
    if (template.nodeType) {
    
      template = template.innerHTML
    } else {
    
      return NOOP
    }
  }
  const key = template
  const cached = compileCache[key]
  if (cached) {
    
    return cached
  }
  if (template[0] === '#') {
    
    const el = document.querySelector(template)
    template = el ? el.innerHTML : ``
  }
  const {
     code } = compile( //  Compile the template 
    template,
    extend(
      {
    
        hoistStatic: true
      options
    )
  )
  const render = ( //  Use new  Convert the above code For a function 
    __GLOBAL__ ? new Function(code)() : new Function('Vue', code)(runtimeDom)
  )
  render._rc = true
  return (compileCache[key] = render)
}

perform compile Is to perform a backup compileToFunction

function finishComponentSetup(
  instance, isSSR, skipOptions
) {
    
	Component.render = compile(template, finalCompilerOptions)
}

5. How the compiler works

  1. parse: analysis template by AST
  2. transform:AST => AST
  3. generate:AST Convert to render function
function compileToFunction(template,options) {
    
  const {
     code } = compile( template )
}
export function compile(
  template: string, options: CompilerOptions = {
     }
): CodegenResult {
    
  return baseCompile(
    template,
    extend({
    }, parserOptions, options, {
    
      nodeTransforms: [
        ignoreSideEffectTags,
        ...DOMNodeTransforms,
        ...(options.nodeTransforms || [])
      ],
      directiveTransforms: extend(
        {
    },
        DOMDirectiveTransforms,
        options.directiveTransforms || {
    }
      ),
      transformHoist: __BROWSER__ ? null : stringifyStatic
    })
  )
}

copyright notice
author[yibucuo],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2022/175/202206240801439170.html

Random recommended