Skip to content

Commit ff7bcd5

Browse files
committed
docs: More detailed explanation of AMD->ESM transpiler rejection
1 parent 00ad4f9 commit ff7bcd5

1 file changed

Lines changed: 28 additions & 8 deletions

File tree

rfcs/0020-npm-package-integration.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -416,19 +416,39 @@ This rewriting runs as a post-bundling step, after all NPM bundles are generated
416416

417417
#### 3.6.5 Architectural Decision: Integrated Scanning vs. AMD->ESM Transpilation
418418

419-
An alternative approach was considered: transpile all UI5 AMD source files to ESM format, then let Rollup discover NPM package imports automatically. This was **rejected** for the following reasons:
419+
An alternative approach was considered: transpile all UI5 AMD source files (`sap.ui.define` / `sap.ui.require`) to ESM format, then let Rollup discover NPM package imports automatically via its native module graph. This was **rejected** in favor of extending the existing `JSModuleAnalyzer` with a lightweight `thirdparty/*` check.
420+
421+
##### Existence proof — UI5 Linter's AMD->ESM transpiler
422+
423+
AMD->ESM transpilation is not hypothetical. The [UI5 Linter](https://github.com/SAP/ui5-linter) ships a production transpiler at `src/linter/ui5Types/amdTranspiler/`.
424+
425+
This transpiler converts AMD modules into ESM so that the TypeScript type-checker can understand UI5 code. It is **purpose-built for static analysis (linting), not for bundling or dependency discovery**.
426+
427+
##### Why the transpilation approach was rejected
428+
429+
**1. Solving the wrong problem.** Even after transpiling AMD->ESM, Rollup still cannot discover *which* NPM packages an application uses. It needs explicit entry points. Otherwise it just bundles everything as a single bundle.
430+
431+
**2. Disproportionate complexity.** Extending `JSModuleAnalyzer` to detect `thirdparty/*` prefixes requires less efforts (a single `if (dep.startsWith("thirdparty/"))`) than a transpiler utility — for the same end result: a list of NPM package names.
432+
433+
**3. Parser mismatch.** The UI5 Builder's analysis infrastructure (`JSModuleAnalyzer`, `parseUtils.js`) uses **espree** — a lightweight, JS-only parser targeting ES2023. The UI5 Linter's transpiler uses the **TypeScript Compiler API** (`ts.createTransformer`), which is a fundamentally different tool with different performance characteristics and a much larger dependency footprint. Introducing the TS compiler API into the build pipeline purely for dependency scanning would be a significant architectural change.
434+
435+
**4. XML views compound the problem.** UI5 applications declare NPM-backed Web Component dependencies in XML views via `xmlns:webc="thirdparty.@ui5/webcomponents"`. The current `XMLTemplateAnalyzer` already pattern-matches `xmlns` attributes directly. An AMD->ESM approach would require a *second* transpiler for XML->JS. The UI5 Linter indeed has a separate XML transpiler (`src/linter/xmlTemplate/`, using `sax-wasm` + `ViewGenerator`), further multiplying the code that would need to be ported and maintained.
436+
437+
**5. Runtime overhead.** The transpilation approach requires **three parse passes** per source file: (1) the existing AST parse, (2) AMD->ESM code generation, and (3) Rollup re-parsing the transpiled output. The scanning approach adds a single `startsWith` check to pass (1) — effectively zero overhead on top of the existing analysis.
438+
439+
##### Comparison summary
420440

421441
| Criterion | Integrated Scanning (chosen) | AMD->ESM Transpilation (rejected) |
422442
|-----------|------------------------------|----------------------------------|
423-
| **Parse passes** | 1 (existing AST walk) | 3+ (original parse + transpile + Rollup re-parse) |
424-
| **Temporary files** | None | Must write transpiled ESM to disk, then discard |
425-
| **Discovery benefit** | Direct extraction | **None** — Rollup still needs explicit entry points; it cannot discover which NPM packages the app uses |
426-
| **XML views** | Pattern-match xmlns attributes directly | Additional transpilation from XML to JS -> ESM |
427-
| **Implementation** | Small extension to existing infrastructure | New transpiler subsystem (AMD->ESM code generation, source maps, file management) |
443+
444+
| **Parse passes** | 1 (existing AST walk) | 3+ (original parse -> transpile -> Rollup re-parse) |
445+
| **Parser** | espree (lightweight, JS-only) | TypeScript Compiler API (heavyweight) |
446+
| **Discovery benefit** | Direct extraction of `thirdparty/*` deps | **None** — Rollup still needs explicit entry points |
447+
| **XML views** | Pattern-match `xmlns` attributes directly | Requires additional XML->JS transpiler |
428448
| **Pattern logic** | `if (dep.startsWith('thirdparty/'))` | Identical `thirdparty/*` detection — same algorithm, more overhead |
429-
| **Maintenance** | Extends well-tested JSModuleAnalyzer | New transformation layer to maintain |
449+
| **Maintenance** | Extends well-tested `JSModuleAnalyzer` | New transformation layer to maintain and keep in sync with UI5 runtime semantics |
430450

431-
**Key insight**: Both approaches use the **identical `thirdparty/*` convention** for NPM package detection. The only difference is execution model — direct extraction during AST traversal vs. code transformation followed by re-analysis. The transpilation approach adds multiple processing passes without eliminating the need for scanning.
451+
**Key insight**: Both approaches use the **identical `thirdparty/*` convention** for NPM package detection. The only difference is execution model — direct extraction during AST traversal vs. full code transformation followed by re-analysis. The transpilation approach adds lots of new code and multiple processing passes without producing any additional signal for dependency discovery. The UI5 Linter proves that AMD->ESM transpilation *works*, but its purpose (enabling type-checking) is fundamentally different from the build pipeline's goal (enumerating packages to bundle).
432452

433453
---
434454

0 commit comments

Comments
 (0)