Skip to content

Latest commit

 

History

History
270 lines (199 loc) · 10.9 KB

File metadata and controls

270 lines (199 loc) · 10.9 KB

Jasper — Development & Build Guide

English · 中文

For everyday use, see the Docker quick start. This guide covers running from source, the single-binary build, the demo library, the browser-only WASM preview, and the environment variables.

Running from source

Requirements: a Rust toolchain and pnpm.

# Backend — serves the API and the built UI on http://127.0.0.1:27583
cd server && cargo run                       # uses saved config, or the setup wizard
cd server && cargo run -- /path/to/JoplinDir # bootstrap with a local folder
cd server && cargo run -- https://host/dav/  # or a WebDAV URL

# Frontend
cd web && pnpm install
cd web && pnpm build      # produces web/dist, served by the backend at :27583
cd web && pnpm dev        # or hot-reload dev server on :5173 (proxies /api)

# Tests (see the Tests section below for the full suite)
cd server && cargo test   # Rust unit tests
cd web && pnpm test       # frontend unit tests (Vitest)

Then open http://127.0.0.1:27583/. On first run the wizard lets you pick existing library / new library × local / WebDAV.

Tests

Three layers, all run in CI (.github/workflows/ci.yml):

# 1) Rust unit tests — core (parser / serialize / library) + server (config / storage / cache / webdav)
cd core && cargo test
cd server && cargo test

# 2) Frontend unit tests (Vitest + jsdom): render, i18n, api helpers,
#    and the image-block alt round-trip (web/src/lib/milkdown/imageBlockAlt.test.ts)
cd web && pnpm test
cd web && pnpm check         # type-check (also covers *.test.ts)

# 3) Full-stack e2e (Playwright): builds the UI + a real Rust backend against a
#    generated Joplin fixture, then drives a browser end-to-end.
cd web && pnpm build                 # UI must be built (served via JASPER_WEB_DIR)
cd server && cargo build             # backend binary the e2e launcher runs
cd web && pnpm e2e:install           # one-time: download the Chromium browser
cd web && pnpm e2e

The e2e harness lives in web/e2e/: make-fixture.mjs writes a tiny Joplin library (a notebook, a note with an image, a to-do, a resource), server.mjs is the Playwright webServer launcher (fresh temp data + isolated JASPER_CONFIG_DIR each run), and the *.spec.ts files cover load/search, rendering, editing + write-back, and the WYSIWYG image-alt regression.

Single binary

The frontend can be embedded into the executable (via rust-embed) so the whole app ships as one self-contained file — no separate web/dist at runtime:

cd web && pnpm build                                   # build web/dist first
cd server && cargo build --release --features embed    # → server/target/release/jasper (~5 MB)

Copy that single binary anywhere and run it. The embed feature is opt-in; without it the backend serves web/dist from disk as before (so plain cargo run still works without building the frontend).

Building the Docker image

docker compose up --build   # then open http://localhost:27583/

Multi-stage build: Node builds the frontend → Rust embeds it with --features embed → the runtime image is a single self-contained binary on debian-slim. Published images (via .github/workflows/docker.yml) go to ghcr.io/jasper-note/jasper: main builds latest (+ sha-…), and version tags (v1.2.3) get semver tags.

Try it with demo content

docs/gen-demo-library.py generates a small sample library (the one in the screenshots):

python3 docs/gen-demo-library.py /tmp/jasper-demo
cd server && cargo run -- /tmp/jasper-demo

Browser-only demo (WASM, no server)

The core (model / parser / serializer / index) is a dependency-light jasper-core crate that also compiles to WebAssembly. With a bundled sample library it powers a read-only, server-less preview that runs entirely in the browser tab — handy for a static demo (e.g. GitHub Pages).

# needs: rustup target add wasm32-unknown-unknown + wasm-pack
cd web && pnpm build:demo   # builds the wasm, then a static demo bundle into web/dist

It does not affect the native build: when not in demo mode the wasm import is tree-shaken out entirely.

Browser WASM demo

Environment variables

Variable Default Purpose
JASPER_HOST 127.0.0.1 Bind address; set 0.0.0.0 for LAN / containers
JASPER_PORT 27583 Listen port
JASPER_CONFIG_DIR platform config dir Where config.db / cache.db live (/config in Docker)
JASPER_WEB_DIR next to source Static frontend dir (overrides embedded/disk defaults)
JASPER_SOURCE First-run bootstrap data source (local path or WebDAV URL)
JASPER_WEBDAV_USER / JASPER_WEBDAV_PASS WebDAV credentials for the bootstrap source

Architecture

Browser SPA (Svelte 5 + CodeMirror)  ──HTTP──▶  Rust server (axum)  ──read/write──▶  Local folder / WebDAV

The server scans the sync directory, parses every <id>.md item into an in-memory index, and exposes a small JSON API (/api/folders, /api/notes, /api/resources, /api/search, …). The SPA renders Markdown client-side and rewrites :/id resource links to /api/resources/id. See CLAUDE.md for the full module layout and docs/joplin-data-format.md for the data format.


开发与构建指南(中文)

English · 中文

日常使用请看 Docker 快速开始。本文覆盖:源码运行、 单文件打包、演示库、浏览器 WASM 预览,以及环境变量。

源码运行

需要:Rust 工具链与 pnpm

# 后端 —— 在 http://127.0.0.1:27583 提供 API 并托管前端
cd server && cargo run                       # 读已保存配置,或进入向导
cd server && cargo run -- /路径/JoplinDir     # 用本地文件夹引导
cd server && cargo run -- https://host/dav/   # 或一个 WebDAV 地址

# 前端
cd web && pnpm install
cd web && pnpm build      # 产出 web/dist,由后端在 :27583 托管
cd web && pnpm dev        # 或开发热更新(:5173,/api 代理到后端)

# 测试(完整套件见下方「测试」一节)
cd server && cargo test   # Rust 单元测试
cd web && pnpm test       # 前端单元测试(Vitest)

然后打开 **http://127.0.0.1:27583/**。首次启动可在向导里选择 现有库 / 新建库 × 本地 / WebDAV

测试

三层,全部在 CI(.github/workflows/ci.yml)里跑:

# 1) Rust 单元测试 —— core(parser / serialize / library)+ server(config / storage / cache / webdav)
cd core && cargo test
cd server && cargo test

# 2) 前端单元测试(Vitest + jsdom):渲染、i18n、api 助手,
#    以及图片块 alt 往返(web/src/lib/milkdown/imageBlockAlt.test.ts)
cd web && pnpm test
cd web && pnpm check         # 类型检查(也覆盖 *.test.ts)

# 3) 全栈 e2e(Playwright):构建前端 + 真 Rust 后端(指向生成的 Joplin 测试库),
#    再用浏览器端到端驱动。
cd web && pnpm build                 # 需先构建前端(经 JASPER_WEB_DIR 托管)
cd server && cargo build             # e2e 启动器要运行的后端二进制
cd web && pnpm e2e:install           # 一次性:下载 Chromium 浏览器
cd web && pnpm e2e

e2e 相关代码在 web/e2e/make-fixture.mjs 写出一个最小 Joplin 库(一个笔记本、 一篇带图笔记、一条待办、一个资源);server.mjs 是 Playwright 的 webServer 启动器(每次重建临时数据 + 隔离的 JASPER_CONFIG_DIR);各 *.spec.ts 覆盖 加载/搜索、渲染、编辑写回,以及富文本图片 alt 回归。

单文件打包

前端可经 rust-embed 编译进二进制,整个 应用就是一个自带前端的可执行文件 —— 运行时不再需要 web/dist

cd web && pnpm build                                  # 先构建出 web/dist
cd server && cargo build --release --features embed    # → server/target/release/jasper(约 5 MB)

把这个文件拷到任意位置直接运行即可。embed 是可选 feature;不带它时后端照旧从磁盘 web/dist 托管(所以不构建前端也能直接 cargo run)。

自行构建 Docker 镜像

docker compose up --build   # 然后访问 http://localhost:27583/

多阶段构建:Node 构建前端 → Rust 用 --features embed 把前端内嵌进二进制 → 运行镜像是 debian-slim 上的单个自带前端二进制。发布镜像(由 .github/workflows/docker.yml)推到 ghcr.io/jasper-note/jaspermain 构建 latest(+ sha-…),版本 tag (v1.2.3)打语义化版本标签。

用演示内容试一试

docs/gen-demo-library.py 会生成一个小型示例库(即这些截图所用):

python3 docs/gen-demo-library.py /tmp/jasper-demo
cd server && cargo run -- /tmp/jasper-demo

浏览器 demo(WASM,无 server)

核心逻辑(数据模型 / 解析 / 序列化 / 索引)抽成了依赖很轻的 jasper-core crate, 它也能编译到 WebAssembly。配上内置的演示库,就能做一个只读、零服务器的预览—— 整页跑在浏览器标签里,适合做静态演示站(如 GitHub Pages)。

# 需先装:rustup target add wasm32-unknown-unknown + wasm-pack
cd web && pnpm build:demo   # 先编 wasm,再产出静态 demo 到 web/dist

不影响原生构建:非 demo 模式下 wasm import 会被整体 tree-shake 掉。

浏览器 WASM demo

环境变量

变量 默认值 用途
JASPER_HOST 127.0.0.1 绑定地址;局域网 / 容器设 0.0.0.0
JASPER_PORT 27583 监听端口
JASPER_CONFIG_DIR 平台配置目录 config.db / cache.db 位置(Docker 里为 /config
JASPER_WEB_DIR 源码旁 前端静态目录(覆盖内嵌/磁盘默认)
JASPER_SOURCE —— 首次引导用的数据源(本地路径或 WebDAV 地址)
JASPER_WEBDAV_USER / JASPER_WEBDAV_PASS —— 引导数据源的 WebDAV 账号密码

工作原理

浏览器 SPA (Svelte 5 + CodeMirror)  ──HTTP──▶  Rust 服务 (axum)  ──读写──▶  本地文件夹 / WebDAV

服务扫描同步目录,把每个 <id>.md 条目解析进内存索引,对外暴露一组精简 JSON API (/api/folders/api/notes/api/resources/api/search 等)。前端在浏览器侧 渲染 Markdown,并把 :/id 资源链接改写为 /api/resources/id。完整模块划分见 CLAUDE.md,数据格式见 docs/joplin-data-format.md