LearnNewsExamplesServices
Frontmatter
id7156
titleFinalize Build-Time AST Transformation
stateClosed
labels
enhancement
assigneestobiu
createdAtAug 1, 2025, 6:07 PM
updatedAtAug 2, 2025, 1:11 PM
githubUrlhttps://github.com/neomjs/neo/issues/7156
authortobiu
commentsCount1
parentIssue7130
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtAug 2, 2025, 1:11 PM

Finalize Build-Time AST Transformation

Closed v10.3.0 enhancement
tobiu
tobiu commented on Aug 1, 2025, 6:07 PM

1. Summary

This ticket addresses the final, robust implementation of the build-time HTML-to-VDOM conversion. Previous attempts using regex and incomplete AST patching have proven to be brittle. This task will implement a full, proper AST transformation pipeline to ensure correctness and handle all edge cases, including nested templates, complex expressions, and conditional rendering.

2. Rationale

The core problem is that the build process must reliably convert an html tagged template literal into a standard JavaScript object (the VDOM) within the source code itself. The process must correctly handle interpolated expressions, converting them into valid AST nodes that can be integrated back into the main file's AST. The previous failures were due to improper string manipulation and parsing, leading to syntax errors. A full AST-based approach is the only way to guarantee a syntactically correct and robust transformation.

3. Scope & Implementation Plan

This task will replace the existing template processing logic in buildScripts/buildESModules.mjs with the following, more robust pipeline:

  1. Parse to AST: For each input file, use acorn to parse the entire source code into a complete Abstract Syntax Tree (AST). Add parent pointers to each node during a walk for easier tree manipulation.

  2. Post-Order Traversal: Traverse the AST in post-order (children first). This is critical for correctly handling nested html templates, as it ensures the innermost templates are processed and replaced before their parents.

  3. Identify html Templates: During the traversal, identify all TaggedTemplateExpression nodes whose tag is an Identifier with the name html.

  4. Process Template to JSON VDOM: For each identified template node:

  • Extract the raw strings and the source code of the interpolated expressions.
  • Use the existing buildScripts/util/templateBuildProcessor.mjs to convert this into a serializable JSON VDOM object. This utility is already effective at this specific step, creating placeholders like ##__NEO_EXPR__...## for dynamic parts.
  1. Convert JSON VDOM to AST Node: This is the most critical step. Create a new, robust jsonToAst function inside buildScripts/buildESModules.mjs that recursively converts the JSON VDOM object from the previous step into a valid acorn AST ObjectExpression node. This function will:
  • Correctly handle primitives (string, number, boolean) by creating Literal nodes.
  • Correctly handle arrays by creating ArrayExpression nodes.
  • When it encounters a string that is a placeholder (e.g., ##__NEO_EXPR__(...)##__NEO_EXPR__##), it will extract the inner expression string, parse only that expression with acorn.parse(), and insert the resulting Expression node directly into the AST. This avoids all previous syntax errors.
  • When it encounters a component placeholder ({__neo_component_name__: 'MyComponent'}), it will create an Identifier node.
  1. Replace Node in Main AST: Replace the original TaggedTemplateExpression node in the main AST with the newly generated ObjectExpression node from the previous step.

  2. Rename render method: As part of the same traversal, if a processed html template was inside a method definition or object property named render, rename that key to createVdom.

  3. Generate Final Code: After the traversal and all replacements are complete, use astring to generate the final, correct, and human-readable JavaScript code from the modified AST.

  4. Minify: Pass the generated code to Terser for final minification.

4. Definition of Done

  • The build process no longer produces any parsing or syntax errors related to template conversion.
  • The buildESModules.mjs script is updated to use the full AST transformation pipeline described above.
  • The final dist/esm output for components with html templates is syntactically correct and functionally equivalent to the client-side parsed version.
  • All previous edge cases (conditional rendering, mixed static/dynamic text, self-closing tags) are handled correctly.
tobiu assigned to @tobiu on Aug 1, 2025, 6:07 PM
tobiu added the enhancement label on Aug 1, 2025, 6:07 PM
tobiu added parent issue #7130 on Aug 1, 2025, 6:07 PM
tobiu referenced in commit acb0410 - "Finalize Build-Time AST Transformation #7156 WIP" on Aug 2, 2025, 1:33 AM
tobiu referenced in commit c9c75f2 - "Finalize Build-Time AST Transformation #7156 WIP" on Aug 2, 2025, 1:02 PM
tobiu referenced in commit 32975a7 - "Finalize Build-Time AST Transformation #7156" on Aug 2, 2025, 1:09 PM
tobiu
tobiu Aug 2, 2025, 1:11 PM

this is a huge step forwards for build-time replacements.

Image

gets transformed into:

Image
tobiu closed this issue on Aug 2, 2025, 1:11 PM