ENbext.dev
DocumentationArchitecture

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Frontend TypeScript (tsc-rs)

bext ne fait pas appel au tsc, SWC ou esbuild officiel pour son travail TypeScript. L'ensemble de l'interface TS/TSX → JS est tsc-rs, un compilateur TypeScript à partir de zéro écrit en Rust. Il réside dans son propre espace de travail (ts-rs sur disque, publié sous le nom de chaîne d'outils tsc-rs) et est consommé par bext à la fois en tant qu'ensemble de caisses de bibliothèque (en cours, pour le travail AST) et en tant que sous-processus --pipe. (pour l'émission TSX→JS réelle).

Cette page mappe l'espace de travail tsc-rs et documente exactement comment bext le connecte. Pour savoir où il se trouve dans un rendu, voir le Pipeline de rendu PRISM.

Pourquoi un compilateur personnalisé#

Le PRISM passe de compilation a besoin d'un véritable AST TypeScript : il plie les sous-arbres JSX statiques en concaténations de chaînes en inspectant les nœuds analysés et en épissant le texte source d'origine. Cela nécessite un analyseur :

  • rapide — il s'exécute à chaque compilation de route froide, à l'intérieur de la requête chemin;
  • intégrable — appelable en tant que bibliothèque Rust, pas en tant que sous-processus Node, pour les pass AST ; et
  • convivial pour les outils — tsc-rs propose des modes de préservation ** ( preserveTypeAnnotations, preserveComments ) et un émetteur préservant le texte source qui conserve le formatage d'origine pour les nœuds qui ne nécessitent aucune transformation.

tsc-rs se décrit comme un compilateur axé sur les outils plutôt que comme un clone tsc octet par octet. La parité signalée à la révision épinglée est ~92 % de la suite de tests du compilateur (92,2 %) et ~85 % de conformité (85,0 %) ; le vérificateur de type est intentionnellement incomplet ( bext utilise uniquement l'analyseur/classeur/émetteur, pas le vérificateur).

L'espace de travail tsc-rs#

Le compilateur est un pipeline par étapes classique, une caisse par étape :

code
source ─▶ scanner ─▶ parser ─▶ binder/symbols ─▶ checker/types ─▶ emitter ─▶ JS
         (tokens)   (SourceFile)  (SymbolTable)    (TypeId)      (EmitOutput)

Caisses de base du compilateur#

Caisse Rôle
tsc_rs_ast Tous les types de nœuds AST : SourceFile, Stmt / StmtKind, Expr / ExprKind, TypeNode, nœuds JSX, Span, Diagnostic, CompilerOptions. NodeId / SymbolId / TypeId sont u32 ; les identifiants ≤24 octets sont stockés en ligne ( CompactString ) et les énumérations de types de nœuds sont épinglées en taille (≤32 octets) par des assertions au moment de la compilation.
tsc_rs_scanner Lexer — tokeniseurs de streaming ( TsScanner ) et par lots ( Scanner ) ; scan_all_with_comments() pour l'outillage.
tsc_rs_parser Analyseur de descente récursive → SourceFile. API publique : parse(file_name, source) (JSX activé automatiquement pour .tsx / .jsx ) et parse_with_jsx(file_name, source, jsx_enabled).
tsc_rs_symbols Binder - fait entrer l'AST dans un SymbolTable avec un ScopeGraph et un ReferenceKind. Public : bind(file) -> SymbolTable.
tsc_rs_types Tapez système + inférence ( check, is_assignable, faits de rétrécissement du flux de contrôle). Non utilisé par bext.
tsc_rs_resolver Résolution du module Nœud + Classique → ResolvedModule.
tsc_rs_emitter Émetteur JS / source-map / .d.ts préservant le texte source. Public : emit, emit_strip_types, emit_strip_types_jsx(file, jsx, jsx_import_source) et variantes pour les consts/const-enum inter-fichiers inlining. Renvoie EmitOutput { javascript, source_map, declaration_file }.
tsc_rs_project Gestion de tsconfig.json, orchestration multi-fichiers (rayon), .tsbuildinfo incrémentielle, références de projet ( -b ).

Caisses d'outillage, de serveur et de satellite#

Caisse Rôle
tsc_rs_cli Le binaire tsc-rs — compilation, les lecteurs --watch, --lsp et le mode --pipe bext.
tsc_rs_server LSP JSON-RPC roulé à la main (diagnostics, survol, accès à la définition, références, complétions, renommage, formatage).
tsc_rs_query QueryEngine — une façade d'outils unifiée sur analyseur/classeur/résolveur/vérificateur, utilisée par tsc_rs_project et le LSP.
tsc_rs_incremental Métadonnées de construction incrémentielle + détection des modifications ChangeReason.
tsc_rs_constraints Solveur expérimental de graphe de contraintes ("expliquer pourquoi le type X est Y").
tsc_rs_control_flow Primitives CFG expérimentales construites une fois lors de la liaison et réutilisées.
tsc_rs_harness Infrastructure de test de base/Oracle (compilateur + tests LSP fourslash).
tsc_rs_bench Benchmarks de critères pour scanner / analyseur / émetteur / pipeline.
tsc_rs_openapi Génère des spécifications OpenAPI à partir des routeurs tRPC par analyse statique (Zod → JSON Schema).
tsc_rs_analyze Analyse statique Monorepo - graphique d'importation, cycles, code mort, externes - analyse + résolution uniquement, aucune vérification.
tsc_rs_wasm Liaisons wasm-bindgen exposant compile() / validate() pour une utilisation navigateur/bord/intégrée.

Comment bext dépend de tsc-rs#

bext-core déclare quatre caisses tsc-rs comme dépendances git épinglées à une révision ( crates/bext-core/Cargo.toml ) :

toml
tsc_rs_parser  = { git = "https://github.com/bext-stack/ts-rs.git", rev = "651ef98c" }
tsc_rs_ast     = { git = "https://github.com/bext-stack/ts-rs.git", rev = "651ef98c" }
tsc_rs_emitter = { git = "https://github.com/bext-stack/ts-rs.git", rev = "651ef98c" }
tsc_rs_symbols = { git = "https://github.com/bext-stack/ts-rs.git", rev = "651ef98c" }

La racine de l'espace de travail ( bext/Cargo.toml ) redirige ensuite ces dépôts git vers la caisse sœur locale avec un [patch] afin que le développement quotidien s'appuie sur l'arborescence de travail :

toml
[patch."https://github.com/bext-stack/ts-rs.git"]
tsc_rs_ast     = { path = "../ts-rs/crates/tsc_rs_ast" }
tsc_rs_parser  = { path = "../ts-rs/crates/tsc_rs_parser" }
tsc_rs_emitter = { path = "../ts-rs/crates/tsc_rs_emitter" }
tsc_rs_symbols = { path = "../ts-rs/crates/tsc_rs_symbols" }

Conséquence pratique : édite ../ts-rs et reconstruit bext récupère immédiatement vos modifications. – la version épinglée n'a d'importance que pour les versions CI/release propres qui n'ont pas l'extraction sœur. Les autres caisses bext ( bext-turbopack, bext-server ) ne dépendent pas directement de tsc-rs - elles l'atteignent via bext-core pour les passes AST et via le binaire tsc-rs ** pour l'émission.

Deux modes d'intégration#

bext utilise tsc-rs de deux manières distinctes, et la division est l'élément clé à comprendre.

Mode 1 — caisses de bibliothèque (passes AST en cours)#

Les transformations sources qui doivent inspecter ou réécrire le code l’analysent avec tsc_rs_parser et parcourent les nœuds tsc_rs_ast dans le même processus. Aucun de ces chemins n’émet de JavaScript : ils modifient la chaîne source ou construisent un manifeste annexe, puis transmettent le résultat au mode 2 pour la transpilation.

Fichier bext API tsc-rs utilisées Ce que ça fait
bext-core/src/transform/prism_compile.rs tsc_rs_parser::parse + tsc_rs_ast::{JsxElement, JsxAttribute, JsxChild, Expr, Stmt, …} Le Passe de compilation et de repliement PRISM. Transforme le JSX statique en concaténation de chaînes en remplaçant les plages d’octets du code source d’origine.
bext-core/src/transform/react_semantics.rs tsc_rs_parser::parse + tsc_rs_symbols::{bind, ScopeGraph, ReferenceKind} Le seul consommateur du lieur : il construit un manifeste des portées et références pour la passe du compilateur React et la détection des limites RSC.
bext-core/src/transform/prism_signals.rs tsc_rs_parser::parse + tsc_rs_ast La transformation JSX de "use signals". Voir Signaux.
bext-core/src/transform/rsc_directives.rs tsc_rs_parser::parse Détecte et réécrit "use client" / "use server" pour le chemin RSC.
bext-core/src/transform/{flow_extract,cache_directive,server_boundary,import_strip}.rs tsc_rs_ast::SourceFile déjà analysé Extraction des directives et suppression des imports ; reçoit l’AST de mod.rs::maybe_parse_ast à la demande, uniquement si le code source contient une chaîne déclencheuse.
bext-core/src/framework/prism_data.rs tsc_rs_parser::parse (dans catch_unwind) Analyse les exports des routes : loader, action, metadata. Voir Données PRISM.
bext-core/src/runtime/typescript.rs tsc_rs_parser::parse + tsc_rs_emitter::emit_strip_types strip_types() : le seul chemin interne au processus qui utilise directement l’émetteur, pour de courts extraits TypeScript qui ne justifient pas un aller-retour par le pipe.

La règle d’analyse à la demande dans transform/mod.rs::maybe_parse_ast limite volontairement le coût : l’AST n’est construit que lorsque la source contient "use flow", "use server", "use client", "use cache" ou le nom d’un paquet interdit. Les fichiers qui n’en ont pas besoin évitent entièrement l’analyse.

Conseil

Si vous extrayez ts-rs à côté de bext, toutes les modifications AST prennent effet sur le prochain cargo build — le [patch] dans la racine de l'espace de travail redirige automatiquement les dépôts git épinglés vers votre arborescence locale. Vous n'avez pas besoin de modifier la révision épinglée pendant le développement.

Mode 2 — le travailleur tsc-rs --pipe (le vrai TSX → JS)#

La transpilation réelle — TSX → CommonJS évaluée par V8 — est effectuée par un sous-processus de longue durée tsc-rs --pipe, géré par TscRsPipeWorker dans bext-turbopack/src/direct.rs :

  • une requête JSON délimitée par une nouvelle ligne par module : { filename, source, options } → { output, imports, dynamic_imports, exports, source_map };
  • Broches PipeOptions target: es2022, module: commonjs et JSX mode ( react classique ou react-jsx automatique lorsque jsx_import_source est défini );
  • le travailleur enregistre le mtime du binaire et **réapparaît automatiquement lorsque vous reconstruisez tsc-rs **, afin que les modifications du frontend s'appliquent sans redémarrer bext ;
  • un pool de travailleurs ( BEXT_TURBOPACK_PIPE_POOL_SIZE, par défaut 1) permet des modules distincts se transpirent en parallèle.

bext-turbopack::direct::transform_module est la façade ; les trois chemins de compilation du serveur bext ( ssr_compile_native, rsc_server_compile_native, rsc_client_build_native ) y transitent tous, avec un sous-processus tsc-rs fork par appel comme solution de secours si le tuyauteur n'est pas disponible.

Le mode Pipe existe pour éviter fork+exec sur chaque module — une route froide avec des dizaines d'importations transitives paierait autrement une génération de processus par fichier.

Division du travail (la version en un paragraphe)#

tsc-rs le binaire effectue le vrai transpile TSX → JS (Mode 2). tsc-rs la bibliothèque ( tsc_rs_parser + tsc_rs_ast, plus tsc_rs_symbols pour la sémantique React) est l'interface AST pour les bext. passes source en cours (Mode 1), qui réécrivent le texte source avant le binaire le transpile. Turbopack /le bundler fait le module résolution, marche de fermeture transitive et assemblage de paquets - et non la transformée TS par module. SWC est utilisé uniquement par le Passe Compilateur React, pas pour le décapage genres.

Références croisées#

Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.