JavaScript rewriting
The JavaScript rewriter is the most complex component, powered by a Rust-based WASM module using the OXC parser for high-performance AST transformations.Architecture
JavaScript rewriting occurs in two layers:- TypeScript wrapper (
src/shared/rewriters/js.ts) - Handles error recovery and sourcemap injection - Rust/WASM core (
rewriter/js/) - Performs AST-level transformations using OXC
Rewriter output
The WASM rewriter returns structured output:The rewriter can process both strings and
Uint8Array for efficiency. When working with large scripts, use Uint8Array to avoid encoding overhead.Error handling
Scramjet includes graceful error recovery:URL transformations in JavaScript
The rewriter intercepts:- Function calls:
fetch(),XMLHttpRequest.open(),WebSocket() - Property access:
location.href,document.URL - Dynamic imports:
import(),require() - Worker creation:
new Worker(),new SharedWorker()
HTML rewriting
The HTML rewriter useshtmlparser2 for streaming DOM parsing and dom-serializer for output generation.
Implementation
HTML rules
Scramjet maintains a set of HTML rewriting rules that define which attributes to rewrite:Script injection
WhenfromTop=true, Scramjet injects client scripts into the <head>:
Special HTML handling
Special HTML handling
Inline event handlers: Event attributes like Import maps: JSON import maps have URLs rewritten:CSP meta tags: Content Security Policy tags are commented out:
onclick are rewritten as JavaScript:Srcset rewriting
Responsive images withsrcset attributes require special handling:
CSS rewriting
The CSS rewriter targets URL references in stylesheets using regex-based transformations.Basic usage
CSS URL patterns
The rewriter handles:url()function:url('/path/to/resource')@importrules:@import url('...')or@import '...'
CSS rewriting is less complex than JavaScript because CSS doesn’t contain executable code that can dynamically generate URLs.
URL metadata (URLMeta)
All rewriters share a commonURLMeta type that provides context:
Base URL handling
The<base> tag affects relative URL resolution:
meta.base when encountering <base> tags: