feat: add WebAssembly build for browser-based VCL tooling#556
feat: add WebAssembly build for browser-based VCL tooling#556acme wants to merge 13 commits intoysugimoto:mainfrom
Conversation
Compile Falco to WebAssembly, exposing a JavaScript API for VCL development in
the browser.
- New `cmd/wasm/` package with entry point and API implementation
- `FalcoVCL.parse(vcl)` parses VCL to AST
- `FalcoVCL.tokenize(vcl)` tokenizes with semantic categories for syntax
highlighting
- `FalcoVCL.format(vcl, options)` formats with configurable options
- `FalcoVCL.lint(vcl, options)` lints with scope-aware validation
- Build-tagged regex validation splits PCRE dependency for Wasm compatibility
- `linter/regex.go` uses PCRE for native builds
- `linter/regex_wasm.go` uses Go's `regexp` for Wasm (documented limitations)
- Makefile targets `make wasm` and `make wasm_exec`
- Demo and tests
- `wasm/index.html` interactive demo page
- `wasm/tests/` Vitest browser tests via Playwright
|
Have you considered https://pkg.go.dev/go.arsenm.dev/pcre for PCRE ? |
It looks like that depends on modernc.org/libc/, which won't work in Wasm? |
cmd/wasm/api.go
Outdated
| errors = append(errors, LintError{ | ||
| Severity: "error", | ||
| Message: l.FatalError.Error.Error(), | ||
| Line: 1, |
There was a problem hiding this comment.
Can't Fatal errors get a line/position?
Indeed. Maybe that package could work on Wasm with a minimal libc shim? PCRE is a common requirement, so this would be very useful for Go and WebAssembly users in general, and it would also avoid an inconsistency between Falco running on Wasm and non-Wasm environments. |
|
The CGO-free PCRE can work on WebAssembly: https://github.com/dip-proto/go-pcre/tree/wasm |
- Replace `go.elara.ws/pcre` with `dip-proto/go-pcre` fork that supports js/wasm target - Remove `regex_wasm.go` fallback that used Go's limited `regexp` package - Consolidate into single `regex.go` without build tags - Enables lookahead/lookbehind regex validation in browser environment
Nice! 0d5280b uses that instead. |
- Parse `FatalError.Error` as `ParseError` to get actual token location
- Add explicit yaml.v3 dependency to go.mod
wasm/README.md
Outdated
| ## Limitations | ||
|
|
||
| **Regex validation**: The native Falco CLI uses PCRE for regex validation, but PCRE's native code cannot run in WebAssembly. The Wasm build uses Go's standard `regexp` package instead, which lacks support for some PCRE features: | ||
|
|
||
| - Lookahead (`(?=...)`, `(?!...)`) | ||
| - Lookbehind (`(?<=...)`, `(?<!...)`) | ||
| - Atomic groups (`(?>...)`) | ||
| - Possessive quantifiers (`*+`, `++`, `?+`) | ||
|
|
||
| VCL patterns using these features will pass validation in the WASM build but may fail in production or when using the native CLI. |
There was a problem hiding this comment.
That section can be removed.
| package linter | ||
|
|
||
| import ( | ||
| regexp "go.elara.ws/pcre" |
There was a problem hiding this comment.
From discussion of #556 (comment), can we replace to github.com/dip-proto/go-pcre ?
| modernc.org/memory v1.2.0 // indirect | ||
| ) | ||
|
|
||
| replace go.elara.ws/pcre => github.com/dip-proto/go-pcre v0.0.0-20260204122309-dcbff9cb6240 |
There was a problem hiding this comment.
No longer we need replace section due to you have removed this package?
There was a problem hiding this comment.
Hmm, I'm not sure. I think we still need it as @jedisct1's fork identifies as go.elara.ws/pcre https://github.com/dip-proto/go-pcre/blob/wasm/go.mod#L1C8-L2C1 ?
| } | ||
|
|
||
| function escapeHtml(str) { | ||
| return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); |
There was a problem hiding this comment.
To escape completely, I think we need to escape ' and " for HTML attribute also.
There was a problem hiding this comment.
79fa83c renames the function and adds a comment to make it clearer what it is escaping
- Clarify that the function only escapes characters needed for safe text node insertion, not attribute values
Compile Falco to WebAssembly, exposing a JavaScript API for VCL development in the browser.
New
cmd/wasm/package with entry point and API implementationFalcoVCL.parse(vcl)parses VCL to ASTFalcoVCL.tokenize(vcl)tokenizes with semantic categories for syntax highlightingFalcoVCL.format(vcl, options)formats with configurable optionsFalcoVCL.lint(vcl, options)lints with scope-aware validationUse https://github.com/dip-proto/go-pcre/tree/wasm for PCRE in both Go and Wasm
Makefile targets
make wasmandmake wasm_execDemo and tests
wasm/index.htmlinteractive demo pagewasm/tests/Vitest browser tests via Playwright