@bleedingdev/modern-js-main-doc 3.2.0-ultramodern.12 → 3.2.0-ultramodern.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/en/apis/app/commands.mdx +32 -32
- package/docs/en/community/blog/2022-0708-updates.md +1 -1
- package/docs/en/community/blog/2022-0910-updates.md +2 -2
- package/docs/en/community/blog/v2-release-note.mdx +5 -5
- package/docs/en/community/blog/v3-release-note.mdx +1 -1
- package/docs/en/community/contributing-guide.mdx +2 -3
- package/docs/en/community/releases.mdx +2 -2
- package/docs/en/components/build-output.mdx +1 -1
- package/docs/en/components/debug-app.mdx +1 -1
- package/docs/en/components/deploy-command.mdx +3 -3
- package/docs/en/components/init-app.mdx +36 -66
- package/docs/en/components/init-rspack-app.mdx +1 -1
- package/docs/en/components/prerequisites.mdx +1 -2
- package/docs/en/components/serve-command.mdx +3 -3
- package/docs/en/configure/app/bff/runtime-framework.mdx +1 -1
- package/docs/en/configure/app/tools/ts-checker.mdx +30 -2
- package/docs/en/configure/app/usage.mdx +6 -6
- package/docs/en/guides/advanced-features/international/api.mdx +4 -1
- package/docs/en/guides/advanced-features/international/configuration.mdx +1 -0
- package/docs/en/guides/advanced-features/international/locale-detection.mdx +1 -1
- package/docs/en/guides/advanced-features/international/routing.mdx +43 -2
- package/docs/en/guides/basic-features/debug/using-storybook.mdx +1 -1
- package/docs/en/guides/basic-features/deploy.mdx +14 -14
- package/docs/en/guides/basic-features/env-vars.mdx +2 -2
- package/docs/en/guides/basic-features/routes/config-routes.mdx +2 -2
- package/docs/en/guides/basic-features/routes/routes.mdx +24 -9
- package/docs/en/guides/basic-features/testing/_meta.json +1 -1
- package/docs/en/guides/concept/server.mdx +2 -2
- package/docs/en/guides/get-started/quick-start.mdx +2 -2
- package/docs/en/guides/get-started/tech-stack.mdx +10 -4
- package/docs/en/guides/get-started/ultramodern.mdx +87 -19
- package/docs/en/guides/topic-detail/module-federation/application.mdx +1 -1
- package/docs/en/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/en/guides/topic-detail/module-federation/usage.mdx +5 -5
- package/docs/en/guides/troubleshooting/builder.mdx +1 -1
- package/docs/en/guides/upgrade/other.mdx +7 -7
- package/docs/zh/apis/app/commands.mdx +32 -32
- package/docs/zh/community/blog/2022-0708-updates.md +1 -1
- package/docs/zh/community/blog/2022-0910-updates.md +2 -2
- package/docs/zh/community/blog/v2-release-note.mdx +5 -5
- package/docs/zh/community/blog/v3-release-note.mdx +1 -1
- package/docs/zh/community/contributing-guide.mdx +2 -3
- package/docs/zh/community/releases.mdx +2 -2
- package/docs/zh/components/build-output.mdx +1 -1
- package/docs/zh/components/debug-app.mdx +1 -1
- package/docs/zh/components/deploy-command.mdx +3 -3
- package/docs/zh/components/init-app.mdx +36 -34
- package/docs/zh/components/init-rspack-app.mdx +1 -1
- package/docs/zh/components/prerequisites.mdx +1 -2
- package/docs/zh/components/serve-command.mdx +3 -3
- package/docs/zh/configure/app/bff/runtime-framework.mdx +1 -1
- package/docs/zh/configure/app/tools/ts-checker.mdx +30 -2
- package/docs/zh/configure/app/usage.mdx +5 -5
- package/docs/zh/guides/advanced-features/international/api.mdx +4 -1
- package/docs/zh/guides/advanced-features/international/configuration.mdx +1 -0
- package/docs/zh/guides/advanced-features/international/locale-detection.mdx +1 -1
- package/docs/zh/guides/advanced-features/international/routing.mdx +43 -2
- package/docs/zh/guides/basic-features/debug/using-storybook.mdx +1 -1
- package/docs/zh/guides/basic-features/deploy.mdx +13 -13
- package/docs/zh/guides/basic-features/env-vars.mdx +2 -2
- package/docs/zh/guides/basic-features/routes/config-routes.mdx +2 -2
- package/docs/zh/guides/basic-features/routes/routes.mdx +24 -9
- package/docs/zh/guides/basic-features/testing/_meta.json +1 -1
- package/docs/zh/guides/concept/server.mdx +2 -2
- package/docs/zh/guides/get-started/quick-start.mdx +2 -2
- package/docs/zh/guides/get-started/tech-stack.mdx +10 -4
- package/docs/zh/guides/get-started/ultramodern.mdx +90 -1
- package/docs/zh/guides/topic-detail/module-federation/application.mdx +1 -1
- package/docs/zh/guides/topic-detail/module-federation/deploy.mdx +2 -2
- package/docs/zh/guides/topic-detail/module-federation/usage.mdx +5 -5
- package/docs/zh/guides/troubleshooting/builder.mdx +1 -1
- package/docs/zh/guides/upgrade/other.md +7 -8
- package/main-doc/docs/en/guides/get-started/ultramodern.mdx +97 -14
- package/main-doc/docs/zh/guides/get-started/ultramodern.mdx +62 -3
- package/package.json +12 -12
- package/docs/en/guides/basic-features/testing/cypress.mdx +0 -95
- package/docs/en/guides/basic-features/testing/jest.mdx +0 -148
- package/docs/en/guides/basic-features/testing/vitest.mdx +0 -100
- package/docs/zh/guides/basic-features/testing/cypress.mdx +0 -95
- package/docs/zh/guides/basic-features/testing/jest.mdx +0 -148
- package/docs/zh/guides/basic-features/testing/vitest.mdx +0 -100
|
@@ -38,7 +38,7 @@ This page is the complete public difference reference for the UltraModern.js 3.0
|
|
|
38
38
|
| Metrics/trace correlation | SSR metrics tags do not parse W3C trace context | `traceparent` is parsed and emits `trace_id` / `span_id` tags | Implemented | Improves cross-system observability joins |
|
|
39
39
|
| App-level MF SSR contract flag | No dedicated app-level MF SSR stability contract switch | Adds `server.ssr.moduleFederationAppSSR` contract and auto-enables env wiring when MF SSR markers are detected | Implemented | Sets `process.env.MODERN_MF_APP_SSR` |
|
|
40
40
|
| App-level MF SSR runtime bridge | Not a stable default bridge path | V3 applies stable bridge defaults for MF SSR node output/runtime env when server rendering + MF markers are present | Implemented | Keeps explicit opt-out path via config/env |
|
|
41
|
-
| MF
|
|
41
|
+
| MF vertical loading reliability contracts | Loading fallback patterns are typically app-defined | Adds deterministic timeout/network/contract-error fallback matrix and distributed OTEL continuity assertions | Implemented | `routes-tanstack-mf` reliability suite |
|
|
42
42
|
| BFF runtime choices | Hono runtime path only in Modern.js 3.0 baseline (no built-in Effect runtime path) | Sets Effect as default runtime, enforces strict runtime split (`effect` -> `api/effect`, `hono` -> `api/lambda`), and adds Effect-Schema-only MF data contracts plus failure-injection coverage for federated data fetch | Implemented (Effect-default + strict split) | Stream is explicit about no Zod introduction |
|
|
43
43
|
| Module SDK contract artifact | No framework-level module contract artifact | Adds machine-readable module contract + typed module SDK interfaces | Implemented | `module-sdk-contracts.json` + `moduleSdk.d.ts` |
|
|
44
44
|
| Boundary anti-pattern CI guards | No dedicated boundary anti-pattern workflow | Adds profile-driven CI checks for boundary imports, required hooks, and forbidden module patterns | Implemented | `.github/workflows/boundary-anti-patterns.yml` |
|
|
@@ -239,7 +239,7 @@ UltraModern.js 3.0 shipped additional reliability work aligned to Beads stream D
|
|
|
239
239
|
|
|
240
240
|
- `@modern-js/plugin-bff` runtime path migrated to Effect v4.
|
|
241
241
|
- Effect-only MF data-fetch contract guidance (explicitly no Zod layer in this stream).
|
|
242
|
-
- MF reliability matrix includes deterministic failure injection (timeout/network/contract error).
|
|
242
|
+
- MF vertical loading reliability matrix includes deterministic failure injection (timeout/network/contract error).
|
|
243
243
|
- Distributed trace continuity checks were re-enabled for build and serve paths.
|
|
244
244
|
- Data-platform architecture defines operation identity, envelope integrity, scoped invalidation, and trace propagation contracts.
|
|
245
245
|
|
|
@@ -247,7 +247,7 @@ Reference materials:
|
|
|
247
247
|
|
|
248
248
|
- `docs/super-app-rfc-adr/ADR-0003-effect-only-mf-data-fetch-reliability.md`
|
|
249
249
|
- `packages/cli/plugin-bff/docs/data-platform-architecture.md`
|
|
250
|
-
- `
|
|
250
|
+
- `routes-tanstack-mf` reliability coverage
|
|
251
251
|
|
|
252
252
|
### 11) Release and module certification gate model
|
|
253
253
|
|
|
@@ -280,21 +280,104 @@ The following are intentionally out of scope for this public V3 preset profile:
|
|
|
280
280
|
- Forcing Effect-only data-fetch runtime as the mandatory default for every app.
|
|
281
281
|
- Forcing app-level MF SSR for every app regardless of readiness.
|
|
282
282
|
|
|
283
|
-
##
|
|
283
|
+
## Human Workflow
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
The public BleedingDev create package starts small. The default command creates
|
|
286
|
+
one production-ready UltraModern app with `presetUltramodern(...)`, SSR,
|
|
287
|
+
TanStack Router, Tailwind CSS v4, i18n, Effect BFF, generated quality gates, and
|
|
288
|
+
production URL metadata:
|
|
286
289
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
290
|
+
```bash
|
|
291
|
+
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
292
|
+
cd myapp
|
|
293
|
+
mise install
|
|
294
|
+
pnpm install
|
|
295
|
+
pnpm run ultramodern:check
|
|
296
|
+
MODERN_PUBLIC_SITE_URL=https://example.com pnpm build
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Create a SuperApp workspace only when independent ownership is useful:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
pnpm dlx @bleedingdev/modern-js-create my-super-app --ultramodern-workspace
|
|
303
|
+
cd my-super-app
|
|
304
|
+
mise install
|
|
305
|
+
pnpm install
|
|
306
|
+
pnpm check
|
|
307
|
+
pnpm build
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
The initial SuperApp workspace is shell-only: `apps/shell-super-app` owns route
|
|
311
|
+
assembly and Module Federation host wiring, `verticals/*` starts empty, and
|
|
312
|
+
`packages/shared-*` holds placeholders for contracts, tokens, and API support.
|
|
313
|
+
Add verticals only when a real business domain needs independent ownership.
|
|
291
314
|
|
|
292
|
-
|
|
315
|
+
Add real business MicroVerticals as they become ownership boundaries:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
319
|
+
pnpm dlx @bleedingdev/modern-js-create food-delivery --vertical
|
|
320
|
+
pnpm dlx @bleedingdev/modern-js-create payments --vertical
|
|
321
|
+
pnpm dlx @bleedingdev/modern-js-create maps --vertical
|
|
322
|
+
pnpm check
|
|
323
|
+
pnpm build
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
The `--vertical` command mutates the current workspace. It creates the vertical
|
|
327
|
+
package and updates topology metadata, ownership records, shell Module
|
|
328
|
+
Federation wiring, local development overlays, package dependencies, generated
|
|
329
|
+
contracts, ports, route-owned i18n, CSS isolation, and the vertical-owned Effect
|
|
330
|
+
BFF/client surface.
|
|
331
|
+
|
|
332
|
+
Generated apps and verticals keep SSR on the normal Modern.js path. SuperApp
|
|
333
|
+
workspaces add `server.ssr.moduleFederationAppSSR` when Module Federation SSR is
|
|
334
|
+
needed, but the flag remains an explicit contract rather than a requirement for
|
|
335
|
+
every app.
|
|
336
|
+
|
|
337
|
+
Each app emits `src/routes/ultramodern-route-metadata` with
|
|
338
|
+
`ultramodernLocalisedUrls`. The i18n plugin reads that map in
|
|
339
|
+
`localeDetection.localisedUrls` and serves dynamic backend JSON from
|
|
340
|
+
`/locales/{{lng}}/{{ns}}.json`.
|
|
341
|
+
|
|
342
|
+
The generated contract writes `.modernjs/ultramodern-generated-contract.json`
|
|
343
|
+
with `cssFederation`: shared design tokens stay in `packages/shared-design-tokens`,
|
|
344
|
+
shell CSS owns shell layers, each vertical owns one CSS layer with app-local
|
|
345
|
+
prefixes, and SSR first paint uses Modern/Rspack assets plus manifest-owned
|
|
346
|
+
vertical CSS.
|
|
347
|
+
|
|
348
|
+
Generated workspaces include `scripts/proof-cloudflare-version.mjs` for live
|
|
349
|
+
Cloudflare and Zephyr proof. Deploy first, then pass each deployed app's
|
|
350
|
+
generated public URL env key into the proof step. Shell-only workspaces only
|
|
351
|
+
need the shell URL; added verticals use the same
|
|
352
|
+
`ULTRAMODERN_PUBLIC_URL_<APP_ID>` pattern with hyphens converted to underscores
|
|
353
|
+
and uppercased.
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
pnpm cloudflare:deploy
|
|
357
|
+
ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP=https://shell-super-app.example.workers.dev \
|
|
358
|
+
ULTRAMODERN_PUBLIC_URL_TRANSPORTATION=https://transportation.example.workers.dev \
|
|
359
|
+
pnpm cloudflare:proof -- --require-public-urls
|
|
360
|
+
```
|
|
293
361
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
362
|
+
Live proof requires public Worker URLs and Zephyr credentials; local checks
|
|
363
|
+
still validate generated contracts, builds, Cloudflare output, dry-run Zephyr
|
|
364
|
+
evidence plans, and local evidence schemas.
|
|
365
|
+
|
|
366
|
+
## Current Troubleshooting
|
|
367
|
+
|
|
368
|
+
| Symptom | Current check | Owner |
|
|
369
|
+
| --- | --- | --- |
|
|
370
|
+
| Package cohort mismatch | Regenerate with one package source strategy, run `mise install`, then rerun `pnpm install` from the activated shell. | Generated workspace package source metadata |
|
|
371
|
+
| Install failure | Check the active Node/pnpm from `mise install`; rerun `pnpm install` after the shell sees the pinned versions. | Toolchain setup |
|
|
372
|
+
| Build failure | Run `pnpm check` before `pnpm build`; fix reported format, lint, type, skill, i18n, or generated-contract failures first. | Owning package or generated contract |
|
|
373
|
+
| Missing public URL | Set the env key from `.modernjs/ultramodern-generated-contract.json`, for example `ULTRAMODERN_PUBLIC_URL_SHELL_SUPER_APP`. | Deployment operator |
|
|
374
|
+
| Cloudflare credentials | Confirm Wrangler credentials before `pnpm cloudflare:deploy`; local checks do not prove live Worker access. | Deployment operator |
|
|
375
|
+
| Asset or CSS 404 | Rebuild with `pnpm build` or `pnpm cloudflare:deploy` and inspect emitted Modern/Rspack asset paths instead of hardcoding CSS URLs. | Framework/runtime asset pipeline |
|
|
376
|
+
| Federation manifest failure | Run the shell and vertical build scripts, then check each deployed `/mf-manifest.json` URL used by the shell. | Module Federation owner |
|
|
377
|
+
|
|
378
|
+
BleedingDev packages are published through GitHub Actions trusted publishing.
|
|
379
|
+
The public workflow is tokenless; do not publish packages manually from a
|
|
380
|
+
developer machine.
|
|
298
381
|
|
|
299
382
|
## Baseline Switches (Opt-out)
|
|
300
383
|
|
|
@@ -38,7 +38,7 @@ UltraModern.js V3 记录的是一套“更强默认值的 Modern.js 参考档案
|
|
|
38
38
|
| Metrics 与 Trace 关联 | SSR metrics 不解析 W3C trace 上下文 | 解析 `traceparent` 并注入 `trace_id` / `span_id` 标签 | 已实现 | 提升跨系统观测关联度 |
|
|
39
39
|
| 应用级 MF SSR 合约开关 | 无专门 app-level MF SSR 稳定性契约开关 | 新增 `server.ssr.moduleFederationAppSSR`,并在检测到 MF SSR 标记时自动启用环境变量握手 | 已实现 | 注入 `process.env.MODERN_MF_APP_SSR` |
|
|
40
40
|
| 应用级 MF SSR 运行时桥接 | 非稳定默认桥接路径 | V3 在「服务端渲染 + MF 标记」场景下提供稳定桥接默认行为 | 已实现 | 保留显式关闭路径 |
|
|
41
|
-
| MF
|
|
41
|
+
| MF vertical 加载可靠性契约 | 加载重试/降级策略通常由业务自管 | 新增 timeout/network/contract-error 的确定性降级矩阵与分布式 OTEL 连续性断言 | 已实现 | 对应 `routes-tanstack-mf` 可靠性套件 |
|
|
42
42
|
| BFF 运行时选型 | Modern.js V3 基线仅提供 Hono 运行时路径(无内建 Effect 运行时) | 将 Effect 设为默认运行时,并采用严格运行时拆分(`effect` -> `api/effect`,`hono` -> `api/lambda`),同时补齐 Effect-Schema-only MF 数据契约与 failure-injection 覆盖 | 已实现(Effect 默认 + 严格拆分) | 该流明确不引入 Zod |
|
|
43
43
|
| 模块 SDK 合约产物 | 无框架级模块契约产物 | 新增机器可读模块家族契约与类型化模块 SDK 接口 | 已实现 | `module-sdk-contracts.json` + `moduleSdk.d.ts` |
|
|
44
44
|
| 边界反模式 CI 守卫 | 无专门边界反模式工作流 | 新增基于 profile 的边界检查(导入边界/必需钩子/模块禁用模式) | 已实现 | `.github/workflows/boundary-anti-patterns.yml` |
|
|
@@ -239,7 +239,7 @@ UltraModern.js V3 对应 Beads Stream D 落地了额外可靠性能力:
|
|
|
239
239
|
|
|
240
240
|
- `@modern-js/plugin-bff` 运行时路径迁移到 Effect v4。
|
|
241
241
|
- MF 数据拉取契约采用 Effect-only 指导(该流明确不引入 Zod)。
|
|
242
|
-
-
|
|
242
|
+
- MF vertical 加载可靠性矩阵覆盖 timeout/network/contract error 的确定性注入场景。
|
|
243
243
|
- build 与 serve 路径重新启用分布式 trace 连续性断言。
|
|
244
244
|
- 数据平台架构补齐 operation identity、请求/水合 envelope 完整性、scope key 与失效路由契约。
|
|
245
245
|
|
|
@@ -247,7 +247,7 @@ UltraModern.js V3 对应 Beads Stream D 落地了额外可靠性能力:
|
|
|
247
247
|
|
|
248
248
|
- `docs/super-app-rfc-adr/ADR-0003-effect-only-mf-data-fetch-reliability.md`
|
|
249
249
|
- `packages/cli/plugin-bff/docs/data-platform-architecture.md`
|
|
250
|
-
- `
|
|
250
|
+
- `routes-tanstack-mf` 可靠性覆盖
|
|
251
251
|
|
|
252
252
|
### 11) 发布与模块认证 Gate 模型
|
|
253
253
|
|
|
@@ -280,6 +280,65 @@ UltraModern.js V3 对应 Beads Stream D 落地了额外可靠性能力:
|
|
|
280
280
|
- 将应用级 MF SSR 强制为所有应用的默认路径。
|
|
281
281
|
- 将 Effect-only 数据获取运行时强制为所有应用的默认路径。
|
|
282
282
|
|
|
283
|
+
## 人类工作流
|
|
284
|
+
|
|
285
|
+
公开的 BleedingDev create 包默认从简单路径开始。默认命令会创建一个
|
|
286
|
+
可上线的 UltraModern 单应用,包含 `presetUltramodern(...)`、SSR、
|
|
287
|
+
TanStack Router、Tailwind CSS v4、i18n、Effect BFF、生成质量 gate,以及
|
|
288
|
+
Cloudflare 部署基础:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
292
|
+
cd myapp
|
|
293
|
+
mise install
|
|
294
|
+
mise exec -- pnpm install
|
|
295
|
+
mise exec -- pnpm ultramodern:check
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
只有当独立归属边界有实际价值时,才创建 SuperApp workspace:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
pnpm dlx @bleedingdev/modern-js-create my-super-app --ultramodern-workspace
|
|
302
|
+
cd my-super-app
|
|
303
|
+
mise install
|
|
304
|
+
mise exec -- pnpm install
|
|
305
|
+
mise exec -- pnpm ultramodern:check
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
真实业务边界出现后,再添加对应 MicroVertical:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
312
|
+
pnpm dlx @bleedingdev/modern-js-create food-delivery --vertical
|
|
313
|
+
pnpm dlx @bleedingdev/modern-js-create payments --vertical
|
|
314
|
+
pnpm dlx @bleedingdev/modern-js-create maps --vertical
|
|
315
|
+
mise exec -- pnpm ultramodern:check
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
`--vertical` 会修改当前 workspace:创建 vertical 包,并更新 topology 元数据、
|
|
319
|
+
ownership 记录、shell Module Federation、开发 overlays、包依赖、生成契约、
|
|
320
|
+
端口、路由归属 i18n、CSS 隔离,以及 vertical 自己拥有的 Effect BFF/client surface。
|
|
321
|
+
|
|
322
|
+
生成应用和 vertical 沿用正常的 Modern.js SSR 路径。SuperApp workspace 在需要
|
|
323
|
+
Module Federation SSR 时会加入 `server.ssr.moduleFederationAppSSR`,但这个开关是
|
|
324
|
+
显式契约,不是所有应用的强制要求。
|
|
325
|
+
|
|
326
|
+
每个应用都会产出 `src/routes/ultramodern-route-metadata` 和
|
|
327
|
+
`ultramodernLocalisedUrls`。i18n 插件在 `localeDetection.localisedUrls` 中读取它,
|
|
328
|
+
并从 `/locales/{{lng}}/{{ns}}.json` 提供动态后端 JSON。
|
|
329
|
+
|
|
330
|
+
生成契约会在 `.modernjs/ultramodern-generated-contract.json` 中写入
|
|
331
|
+
`cssFederation`:共享 design tokens 保留在 `packages/shared-design-tokens`,
|
|
332
|
+
shell CSS 拥有 shell layer,每个 vertical 拥有自己的 CSS layer 与应用本地前缀,
|
|
333
|
+
SSR 首屏使用 Modern/Rspack 产物和 manifest 归属的 vertical CSS。
|
|
334
|
+
|
|
335
|
+
生成 workspace 包含 `scripts/proof-cloudflare-version.mjs`,用于 live Cloudflare 和
|
|
336
|
+
Zephyr 证据。Live 证明需要公开 Worker URL 和 Zephyr 凭据;本地检查仍可校验
|
|
337
|
+
生成契约、构建、Cloudflare 输出、dry-run Zephyr 证据计划和本地证据 schema。
|
|
338
|
+
|
|
339
|
+
BleedingDev 包通过 GitHub Actions trusted publishing 发布。公开发布 workflow 不使用
|
|
340
|
+
长期 npm token;不要从开发机器手动发布包。
|
|
341
|
+
|
|
283
342
|
## 基线开关(可按需关闭)
|
|
284
343
|
|
|
285
344
|
生成的 `presetUltramodern(...)` create 模板会开启更严格的平台契约。以下环境变量会在生成的 `modern.config.ts` 中读取,可按应用或按环境关闭/覆盖:
|
package/package.json
CHANGED
|
@@ -18,30 +18,30 @@
|
|
|
18
18
|
"modern",
|
|
19
19
|
"modern.js"
|
|
20
20
|
],
|
|
21
|
-
"version": "3.2.0-ultramodern.
|
|
21
|
+
"version": "3.2.0-ultramodern.120",
|
|
22
22
|
"publishConfig": {
|
|
23
23
|
"registry": "https://registry.npmjs.org/",
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"mermaid": "^11.15.0",
|
|
28
|
-
"@modern-js/sandpack-react": "npm:@bleedingdev/modern-js-sandpack-react@3.2.0-ultramodern.
|
|
28
|
+
"@modern-js/sandpack-react": "npm:@bleedingdev/modern-js-sandpack-react@3.2.0-ultramodern.120"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@rsbuild/plugin-sass": "1.5.
|
|
32
|
-
"@rspress/core": "2.0.
|
|
33
|
-
"@rspress/plugin-llms": "2.0.
|
|
34
|
-
"@rspress/shared": "2.0.
|
|
35
|
-
"@shikijs/transformers": "^4.0
|
|
31
|
+
"@rsbuild/plugin-sass": "1.5.3",
|
|
32
|
+
"@rspress/core": "2.0.14",
|
|
33
|
+
"@rspress/plugin-llms": "2.0.14",
|
|
34
|
+
"@rspress/shared": "2.0.14",
|
|
35
|
+
"@shikijs/transformers": "^4.2.0",
|
|
36
36
|
"@types/fs-extra": "11.0.4",
|
|
37
|
-
"@types/node": "^25.
|
|
38
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
37
|
+
"@types/node": "^25.9.3",
|
|
38
|
+
"@typescript/native-preview": "7.0.0-dev.20260610.1",
|
|
39
39
|
"classnames": "^2.5.1",
|
|
40
40
|
"clsx": "^2.1.1",
|
|
41
41
|
"fs-extra": "^11.3.5",
|
|
42
|
-
"react": "^19.2.
|
|
43
|
-
"react-dom": "^19.2.
|
|
44
|
-
"rsbuild-plugin-open-graph": "1.1.
|
|
42
|
+
"react": "^19.2.7",
|
|
43
|
+
"react-dom": "^19.2.7",
|
|
44
|
+
"rsbuild-plugin-open-graph": "1.1.3"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
47
|
"dev": "rspress dev",
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
# Cypress
|
|
2
|
-
|
|
3
|
-
Cypress is a framework for E2E testing and component testing.
|
|
4
|
-
|
|
5
|
-
To use Cypress in Modern.js, you need to install the dependencies first. You can run the following commands:
|
|
6
|
-
|
|
7
|
-
import { PackageManagerTabs } from '@theme';
|
|
8
|
-
|
|
9
|
-
<PackageManagerTabs command={{ npm: "npm install -D cypress", yarn: "yarn add -D cypress", pnpm: "pnpm install -D cypress" }} />
|
|
10
|
-
|
|
11
|
-
Next, create a `cypress.config.ts` file and add the following content:
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { defineConfig } from 'cypress'
|
|
15
|
-
|
|
16
|
-
export default defineConfig({
|
|
17
|
-
e2e: {
|
|
18
|
-
setupNodeEvents(on, config) {},
|
|
19
|
-
},
|
|
20
|
-
})
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Writing Test Cases
|
|
24
|
-
|
|
25
|
-
Now, use Cypress to write an E2E test case by first creating two Modern.js pages.
|
|
26
|
-
|
|
27
|
-
```tsx title="routes/page.tsx"
|
|
28
|
-
import { Link } from '@modern-js/runtime/router';
|
|
29
|
-
|
|
30
|
-
const Index = () => (
|
|
31
|
-
<div>
|
|
32
|
-
<h1>Home</h1>
|
|
33
|
-
<Link to="/about">About</Link>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
export default Index;
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
```tsx title="routes/about/page.tsx"
|
|
41
|
-
import { Link } from '@modern-js/runtime/router';
|
|
42
|
-
|
|
43
|
-
const Index = () => (
|
|
44
|
-
<div>
|
|
45
|
-
<h1>About</h1>
|
|
46
|
-
<Link to="/">Home</Link>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
export default Index;
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Next, create the test case file:
|
|
54
|
-
|
|
55
|
-
```ts title="cypress/e2e/app.cy.ts"
|
|
56
|
-
describe('Navigation', () => {
|
|
57
|
-
it('should navigate to the about page', () => {
|
|
58
|
-
// Start from the index page
|
|
59
|
-
cy.visit('http://localhost:8080/')
|
|
60
|
-
|
|
61
|
-
// Find a link with an href attribute containing "about" and click it
|
|
62
|
-
cy.get('a[href*="about"]').click()
|
|
63
|
-
|
|
64
|
-
// The new url should include "/about"
|
|
65
|
-
cy.url().should('include', '/about')
|
|
66
|
-
|
|
67
|
-
// The new page should contain an h1 with "About"
|
|
68
|
-
cy.get('h1').contains('About')
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
The test file may lack type definitions for the API. You can refer to the [Cypress - Typescript](https://docs.cypress.io/guides/tooling/typescript-support#Configure-tsconfigjson) documentation to resolve this.
|
|
74
|
-
|
|
75
|
-
You can add the command to your `package.json`:
|
|
76
|
-
|
|
77
|
-
```json title="package.json"
|
|
78
|
-
{
|
|
79
|
-
"scripts": {
|
|
80
|
-
"test": "cypress open"
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Run Test Cases
|
|
86
|
-
|
|
87
|
-
Execute the above `test` command to run the test cases:
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
DevTools listening on ws://127.0.0.1:55203/devtools/browser/xxxxx
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Cypress will open a headless browser. Following the prompts, you can find the corresponding test files and automatically run the E2E tests:
|
|
94
|
-
|
|
95
|
-

|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
# Jest
|
|
2
|
-
|
|
3
|
-
Jest is a JavaScript testing framework that is primarily used with React Testing Library for unit testing and Snapshot testing.
|
|
4
|
-
|
|
5
|
-
To use Jest in Modern.js, you need to install the dependencies first. You can run the following commands:
|
|
6
|
-
|
|
7
|
-
import { PackageManagerTabs } from '@theme';
|
|
8
|
-
|
|
9
|
-
<PackageManagerTabs command={{
|
|
10
|
-
npm: "npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom",
|
|
11
|
-
yarn: "yarn add -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom",
|
|
12
|
-
pnpm: "pnpm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom"
|
|
13
|
-
}} />
|
|
14
|
-
|
|
15
|
-
Next, you can run the following commands to automatically initialize Jest in your project and generate a basic `jest.config.ts` configuration:
|
|
16
|
-
|
|
17
|
-
<PackageManagerTabs command={{
|
|
18
|
-
npm: "npm init jest@latest",
|
|
19
|
-
yarn: "yarn create jest@latest",
|
|
20
|
-
pnpm: "pnpm create jest@latest"
|
|
21
|
-
}} />
|
|
22
|
-
|
|
23
|
-
## Configuration File
|
|
24
|
-
|
|
25
|
-
:::note
|
|
26
|
-
This section will use `.ts` files for Jest testing.
|
|
27
|
-
:::
|
|
28
|
-
|
|
29
|
-
Compared to other testing frameworks, Jest requires more configuration at the build level, such as handling JSX and ESM syntax. Therefore, you need to install some additional dependencies:
|
|
30
|
-
|
|
31
|
-
<PackageManagerTabs command={{
|
|
32
|
-
npm: "npm install -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript",
|
|
33
|
-
yarn: "yarn add -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript",
|
|
34
|
-
pnpm: "pnpm install -D babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript"
|
|
35
|
-
}} />
|
|
36
|
-
|
|
37
|
-
### Configure Jest
|
|
38
|
-
|
|
39
|
-
You need to further configure the `jest.config.ts` file to allow Jest to correctly compile and run test cases. Here is a basic configuration:
|
|
40
|
-
|
|
41
|
-
```ts title="jest.config.ts"
|
|
42
|
-
import type { Config } from 'jest';
|
|
43
|
-
|
|
44
|
-
const config: Config = {
|
|
45
|
-
coverageProvider: 'babel',
|
|
46
|
-
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
|
47
|
-
testEnvironment: 'jsdom',
|
|
48
|
-
transform: {
|
|
49
|
-
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
|
|
50
|
-
},
|
|
51
|
-
transformIgnorePatterns: [],
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export default config;
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
In the configuration, the `transformIgnorePatterns` is set to an empty array, meaning that all files will be compiled. If you want to speed up the test run, you can configure it as needed.
|
|
58
|
-
|
|
59
|
-
The `setupFilesAfterEnv` will be executed at startup. In `jest.setup.ts`, you can import `@testing-library/jest-dom`, which includes a set of convenient custom matchers, such as `.toBeInTheDocument()`, to make writing tests easier:
|
|
60
|
-
|
|
61
|
-
```ts title="jest.setup.ts"
|
|
62
|
-
import '@testing-library/jest-dom';
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Configure Babel
|
|
66
|
-
|
|
67
|
-
You need to configure Babel to allow Jest to automatically compile JSX and other syntax. Here is a basic configuration:
|
|
68
|
-
|
|
69
|
-
```js title="babel.config.js"
|
|
70
|
-
module.exports = {
|
|
71
|
-
presets: [
|
|
72
|
-
['@babel/preset-env', { targets: { node: 'current' } }],
|
|
73
|
-
['@babel/preset-react', { runtime: 'automatic' }],
|
|
74
|
-
'@babel/preset-typescript',
|
|
75
|
-
],
|
|
76
|
-
};
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Writing Test Cases
|
|
80
|
-
|
|
81
|
-
Now, you can start writing tests. First, add a `test` command in `package.json`:
|
|
82
|
-
|
|
83
|
-
```json title="package.json"
|
|
84
|
-
{
|
|
85
|
-
"scripts": {
|
|
86
|
-
"test": "jest"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Create a simple page for testing:
|
|
92
|
-
|
|
93
|
-
```tsx title="routes/page.tsx"
|
|
94
|
-
import { Link } from '@modern-js/runtime/router';
|
|
95
|
-
|
|
96
|
-
const Index = () => (
|
|
97
|
-
<div>
|
|
98
|
-
<h1>Home</h1>
|
|
99
|
-
<Link to="/about">About</Link>
|
|
100
|
-
</div>
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
export default Index;
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Add a test case to check if the page has the expected text:
|
|
107
|
-
|
|
108
|
-
```tsx title="__tests__/page.test.tsx"
|
|
109
|
-
import '@testing-library/jest-dom';
|
|
110
|
-
import { render, screen } from '@testing-library/react';
|
|
111
|
-
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
112
|
-
import Page from '../routes/page';
|
|
113
|
-
|
|
114
|
-
describe('Page', () => {
|
|
115
|
-
it('renders a heading', () => {
|
|
116
|
-
render(
|
|
117
|
-
<Router>
|
|
118
|
-
<Page />
|
|
119
|
-
</Router>,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const heading = screen.getByRole('heading', { level: 1 });
|
|
123
|
-
|
|
124
|
-
expect(heading).toBeInTheDocument();
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
In the above test case, we imported the `<Router>` component from `@modern-js/runtime/router` because React Router requires the corresponding context when rendering some route-related components.
|
|
130
|
-
|
|
131
|
-
:::note
|
|
132
|
-
When running directly in the Modern.js application, the `<Router>` component will be automatically injected.
|
|
133
|
-
:::
|
|
134
|
-
|
|
135
|
-
## Run Test Cases
|
|
136
|
-
|
|
137
|
-
Execute the above `test` command to run the test cases:
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
PASS src/__tests__/page.test.tsx
|
|
141
|
-
Page
|
|
142
|
-
✓ renders a heading (31 ms)
|
|
143
|
-
|
|
144
|
-
Test Suites: 1 passed, 1 total
|
|
145
|
-
Tests: 1 passed, 1 total
|
|
146
|
-
Snapshots: 0 total
|
|
147
|
-
Time: 0.959 s, estimated 1 s
|
|
148
|
-
```
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# Vitest
|
|
2
|
-
|
|
3
|
-
Vitest is a testing framework driven by Vite, which can be used for unit testing in combination with React Testing Library.
|
|
4
|
-
|
|
5
|
-
To use Vitest in Modern.js, you need to install the dependencies first. You can run the following commands:
|
|
6
|
-
|
|
7
|
-
import { PackageManagerTabs } from '@theme';
|
|
8
|
-
|
|
9
|
-
<PackageManagerTabs command={{
|
|
10
|
-
npm: "npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
|
|
11
|
-
yarn: "yarn add -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
|
|
12
|
-
pnpm: "pnpm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom",
|
|
13
|
-
bun: "bun add -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom"
|
|
14
|
-
}} />
|
|
15
|
-
|
|
16
|
-
Next, you need to create a Vitest configuration file `vitest.config.ts` with the following content:
|
|
17
|
-
|
|
18
|
-
```ts title="vitest.config.ts"
|
|
19
|
-
import { defineConfig } from 'vitest/config'
|
|
20
|
-
import react from '@vitejs/plugin-react'
|
|
21
|
-
|
|
22
|
-
export default defineConfig({
|
|
23
|
-
plugins: [react()],
|
|
24
|
-
test: {
|
|
25
|
-
environment: 'jsdom',
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
For more information about Vitest configuration, you can refer to the [Vitest configuration documentation](https://vitest.dev/config/#configuration).
|
|
31
|
-
|
|
32
|
-
You can optionally add the `vitest` command to `package.json`:
|
|
33
|
-
|
|
34
|
-
```json title="package.json"
|
|
35
|
-
{
|
|
36
|
-
"scripts": {
|
|
37
|
-
"test": "vitest"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
After running this command, Vitest will automatically watch your file changes and rerun the test cases.
|
|
43
|
-
|
|
44
|
-
## Create Unit Tests
|
|
45
|
-
|
|
46
|
-
First, create a simple page for testing:
|
|
47
|
-
|
|
48
|
-
```tsx title="routes/page.tsx"
|
|
49
|
-
import { Link } from '@modern-js/runtime/router';
|
|
50
|
-
|
|
51
|
-
const Index = () => (
|
|
52
|
-
<div>
|
|
53
|
-
<h1>Home</h1>
|
|
54
|
-
<Link to="/about">About</Link>
|
|
55
|
-
</div>
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
export default Index;
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Add a test case to check if the page has the expected text:
|
|
62
|
-
|
|
63
|
-
```tsx title="__tests__/page.test.tsx"
|
|
64
|
-
import { expect, test } from 'vitest';
|
|
65
|
-
import { render, screen } from '@testing-library/react';
|
|
66
|
-
import { BrowserRouter as Router } from '@modern-js/runtime/router';
|
|
67
|
-
import Page from '../routes/page';
|
|
68
|
-
|
|
69
|
-
test('Page', () => {
|
|
70
|
-
render(
|
|
71
|
-
<Router>
|
|
72
|
-
<Page />
|
|
73
|
-
</Router>,
|
|
74
|
-
);
|
|
75
|
-
expect(screen.getByRole('heading', { level: 1, name: 'Home' })).toBeDefined();
|
|
76
|
-
});
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
In the above test case, we imported the `<Router>` component from `@modern-js/runtime/router` because React Router requires the corresponding context when rendering some route-related components.
|
|
80
|
-
|
|
81
|
-
:::note
|
|
82
|
-
When running directly in the Modern.js application, the `<Router>` component will be automatically injected.
|
|
83
|
-
:::
|
|
84
|
-
|
|
85
|
-
## Run Test Cases
|
|
86
|
-
|
|
87
|
-
Execute the above `test` command to run the test cases:
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
✓ src/__tests__/page.test.tsx (1)
|
|
91
|
-
✓ Page
|
|
92
|
-
|
|
93
|
-
Test Files 1 passed (1)
|
|
94
|
-
Tests 1 passed (1)
|
|
95
|
-
Start at 15:37:12
|
|
96
|
-
Duration 999ms (transform 119ms, setup 0ms, collect 365ms, tests 33ms, environment 421ms, prepare 44ms)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
PASS Waiting for file changes...
|
|
100
|
-
```
|