TLint web

Developer guide for the browser-based TLint playground: `tlint’s validation logic, compiled to WebAssembly and wrapped in a small web app so users can lint a check without installing anything. For the CLI itself, see TLint.

Architecture

Rust (../src, this repo's `tlint` crate)
  -> www/src/lib.rs        Thin wasm-bindgen wrapper around `tlint::validate`
  -> wasm-pack build       Compiles it to wasm + generates JS glue in www/pkg/
  -> js/lint.worker.js     Runs the wasm module inside a Web Worker
  -> js/index.js           UI: CodeMirror editor, buttons, calls the worker
  -> webpack               Bundles everything + static/index.html
  -> dist/                 The deployable static site

Linting runs inside a Web Worker rather than the main thread, so a large check does not freeze the UI while it is being validated. The worker exposes the wasm module’s lint() function via Comlink; the main thread calls it like a normal async function.

Only four of tlint’s five validators run in the playground: `Expectation, Schema, Value and Exclude. The Link validator is excluded because it needs outbound network access, which is incompatible to run from a browser tab; see TLint for details.

Prerequisites

  • A Rust toolchain via rustup, plus the wasm target:

    rustup target add wasm32-unknown-unknown
  • wasm-pack: cargo install wasm-pack

  • Node.js and npm.

There is no backend and no database, this builds to a static site.

Getting started

From www/:

wasm-pack build  # Compiles Rust -> www/pkg/ (wasm + JS glue)
npm install      # Installs JS dependencies, including the `tlint` wasm package itself via the `file:pkg` entry in package.json, run wasm-pack build first
npm run build    # Webpack production build -> www/dist/
npm run serve    # webpack-dev-server with live reload

Re-run wasm-pack build whenever you change Rust code (in www/src or the main tlint crate); the JS dev server only watches JS/HTML/CSS.

npm run build produces dist/, a plain static site you can serve however you like, that is what Dockerfile.www’s `nginx stage does.

Project layout

www/
  Cargo.toml        # The `tlint-wasm` crate.
  src/lib.rs        # wasm-bindgen entry point wrapping `tlint::validate`
  pkg/              # Generated by `wasm-pack build`. Gitignored.
  js/
    bootstrap.js    # Async entry point webpack loads first.
    index.js        # UI wiring: editor, buttons, draft persistence.
    lint.js         # Spins up the worker, exposes it as a promise.
    lint.worker.js  # Runs in the Web Worker, calls into pkg/.
    example.js      # Sample check used by "Load example".
  static/index.html # The app's single HTML file.
  webpack.config.js
  dist/             # Generated by `npm run build`. Gitignored.

Features

  • CodeMirror editor with YAML syntax highlighting.

  • "Load example", inserts a synthetic sample check.

  • Draft persistence, editor contents survive a page refresh (localStorage), cleared by "Reset".

  • A side panel linking to the official check DSL spec.

Container image

docker build . -t tlint-web -f Dockerfile.www
docker run --rm -p 8080:8080 tlint-web

Multi-stage build: a bci-base image installs a pinned Rust toolchain and the wasm32-unknown-unknown target via rustup (the RPM-packaged rustc is not binary-compatible with the upstream wasm32 std library) and compiles the wasm package, a Node image runs webpack, and the result is served by nginx on port 8080. Base image versions are configurable via build args.