Skip to content

Latest commit

 

History

History
57 lines (43 loc) · 3.84 KB

design.md

File metadata and controls

57 lines (43 loc) · 3.84 KB

Architecture

The original design in vuejs/core mixes code generation and ast parsing in the same data structure. As we can see, the transform pass will in-place mutate ast nodes, leaving the node with both code generation node and ssr code generation node.

This is typically a sign of leaky abstraction.

So in the Rust version I decided to take another approach.

The design targets at three different levels of developers in Vue ecosystem:

  • Lib/App creator: every Vue developers who write component library or application code.
  • Platform developer: Devs who write compiler implementation for DOM/SSR/Native platform.
  • Framework author: Vue core lib author a.k.a Evan.

The core framework targets multiple platforms and can be extended to support more. Core framework components span all platforms and are hardwired to the core lib runtime.

Platforms are usually DOM or SSR environment. Hosts are browser and node, respectively. Developing a platform needs to write code for both vue-compiler and vue-runtime. Optionally platform developer can write code in host, e.g. in hybrid app or mini-program.

And finally lib or app creators can write component library, business code or application components targeted to certain platforms.

The compilation has several phases:

  • Scan (output: Tokens): Hardwired in the compiler at framework level.
  • Parse (output: template AST): Hardwired in the compiler at framework level.
  • Convert (output: intermediate representation): Customizable for platform developers with sensible default.
  • Transform (input/output: customizable IR): Customizable with default by using generic/traits.
  • Code Generate (customizable output: e.g. JS/TS): Customizable with default.

Other Design different from the original compiler

  • Directive parsing is implemented manually instead of by regexp.
  • nodeTransforms is not supported. It's too hard for app creator to use and maintain IR invariants. Platform devs can still customize by implementing converter/transformer.
  • directiveTransforms now can returns not only Props but also SimpleExpression. The extra flexibility makes a more cohesive v-bind/v-on conversion: the logic for processing the directives now resides in one single file without regard to the presence of an argument.
  • Runtime helper collection context.helper/helperString is moved out from convert and tracked in transform phase, avoiding several methods and reducing HashMap to a bitflag.

Implementation Detail

  • Plenty of debug_asserts to maintain compiler state invariants.
  • The library seeks minimal allocation by using &str, Cow<'_, str> and smallvec.
  • A customized VStr is used to minimize string manipulation.
  • Fxhash is preferred over default hasher since hash collision is not a concern.
  • The bitflags crate is used to represent runtime helper and vnode patch flags.
  • Use heavily optimized routines for string search primitives. (Perf reference)
  • Benchmark with criterion.rs.
  • Test compiler output by snapshot test.
  • Use alternative allocator like wee_alloc or mi_malloc.
  • Use Box<[T]> instead of Vec to reduce type size.
  • Use Arean to minimize allocation.
  • A Future like stack-allocated transformation Pass composition.
  • Use Rc to manage error handler. Don't optimize wrong code.
  • Parallelized conversion with Rayon.