@bleedingdev/modern-js-main-doc 3.8.3-ultramodern.1 → 3.8.3-ultramodern.2
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/community/showcase.mdx +4 -5
- package/docs/en/components/init-app.mdx +8 -7
- package/docs/en/components/init-rspack-app.mdx +1 -3
- package/docs/en/guides/advanced-features/bff/frameworks.mdx +1 -1
- package/docs/en/guides/basic-features/deploy.mdx +2 -2
- package/docs/en/guides/get-started/quick-start.mdx +1 -1
- package/docs/en/guides/get-started/tech-stack.mdx +1 -1
- package/docs/en/guides/get-started/ultramodern.mdx +18 -18
- package/docs/en/guides/troubleshooting/cli.mdx +1 -1
- package/docs/en/tutorials/examples/csr-auth.mdx +3 -1
- package/docs/zh/community/showcase.mdx +4 -5
- package/docs/zh/components/init-app.mdx +7 -7
- package/docs/zh/components/init-rspack-app.mdx +1 -3
- package/docs/zh/guides/basic-features/deploy.mdx +2 -2
- package/docs/zh/guides/get-started/quick-start.mdx +1 -1
- package/docs/zh/guides/get-started/tech-stack.mdx +1 -1
- package/docs/zh/guides/get-started/ultramodern.mdx +18 -18
- package/docs/zh/guides/troubleshooting/cli.mdx +1 -1
- package/docs/zh/tutorials/examples/csr-auth.mdx +3 -1
- package/package.json +3 -2
- package/rspress.config.ts +16 -54
- package/src/sandbox/csr-auth/src/routes/Auth-tsx.txt +13 -3
- package/src/sandbox/csr-auth/src/routes/layout-tsx.txt +3 -3
- package/src/sandbox/csr-auth/src/routes/login/page-tsx.txt +7 -3
- package/ultramodern-preset/assets/img/ultramodern-logo-dark.svg +7 -0
- package/ultramodern-preset/assets/img/ultramodern-social-card.png +0 -0
- package/ultramodern-preset/package.json +19 -0
- package/ultramodern-preset/src/index.ts +127 -0
- package/static/img/social-card.svg +0 -12
- /package/{static/img/logo.svg → ultramodern-preset/assets/img/ultramodern-logo-light.svg} +0 -0
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
sidebar_position: 0
|
|
3
|
+
title: Ecosystem
|
|
3
4
|
---
|
|
4
5
|
|
|
5
|
-
#
|
|
6
|
+
# Ecosystem
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
UltraModern.js builds on a focused ecosystem of frameworks and tools. These projects provide the Effect, TanStack Router, build, documentation, and Module Federation foundations used by the fork.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## The Cases
|
|
10
|
+
## Projects
|
|
12
11
|
|
|
13
12
|
import { ShowcaseList } from '@site/src/components/ShowcaseList';
|
|
14
13
|
|
|
@@ -3,26 +3,27 @@ workspaces. It does not require global installation and can be run on-demand
|
|
|
3
3
|
using `pnpm dlx`.
|
|
4
4
|
|
|
5
5
|
The supported pnpm command is the scoped package specifier:
|
|
6
|
-
`pnpm dlx @bleedingdev/modern-js-create <target>`. Do not shorten it
|
|
7
|
-
`pnpm dlx modern-js-create`; there is no unscoped package by
|
|
6
|
+
`pnpm dlx @bleedingdev/modern-js-ultramodern-create <target>`. Do not shorten it
|
|
7
|
+
to `pnpm dlx modern-js-ultramodern-create`; there is no unscoped package by
|
|
8
|
+
that name.
|
|
8
9
|
|
|
9
10
|
You can initialize the empty directory you are already in:
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
13
|
mkdir myapp && cd myapp
|
|
13
|
-
pnpm dlx @bleedingdev/modern-js-create .
|
|
14
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create .
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
You can also create a project directly in a new directory:
|
|
17
18
|
|
|
18
19
|
```bash
|
|
19
|
-
pnpm dlx @bleedingdev/modern-js-create my-super-app
|
|
20
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create my-super-app
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
To initialize with workspace protocol dependencies (for local monorepo testing of unreleased Modern.js packages):
|
|
23
24
|
|
|
24
25
|
```bash
|
|
25
|
-
pnpm dlx @bleedingdev/modern-js-create my-super-app --workspace
|
|
26
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create my-super-app --workspace
|
|
26
27
|
```
|
|
27
28
|
|
|
28
29
|
The BleedingDev create package will directly create the application without providing an interactive Q & A interface:
|
|
@@ -73,13 +74,13 @@ The default workspace starts shell-only and installs the published BleedingDev
|
|
|
73
74
|
package aliases:
|
|
74
75
|
|
|
75
76
|
```bash
|
|
76
|
-
pnpm dlx @bleedingdev/modern-js-create my-super-app
|
|
77
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create my-super-app
|
|
77
78
|
```
|
|
78
79
|
|
|
79
80
|
From a generated SuperApp workspace, add a business MicroVertical in place:
|
|
80
81
|
|
|
81
82
|
```bash
|
|
82
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
83
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical
|
|
83
84
|
```
|
|
84
85
|
|
|
85
86
|
The `--vertical` command mutates the current workspace: it adds the vertical
|
|
@@ -122,7 +122,7 @@ const response = await api.client.hello.ping({});
|
|
|
122
122
|
|
|
123
123
|
The `api.client.*` surface is materialized by the BFF loader for `@api/index` imports. Do not import `api/index` directly and expect `client` to run in server code, scripts, or tests; direct entry imports expose the server runtime definition, and `client` is only a typed placeholder there.
|
|
124
124
|
|
|
125
|
-
For UltraModern, Effect `HttpApi` plus Effect BFF is the single blessed authored HTTP path. Use `HttpApi` endpoints with `query`, `params`, `payload`, `success`, and declared errors such as `HttpApiSchema.status(...)`; implement them with `HttpApiBuilder.group(...).handle(...)` and `HttpApiBuilder.layer(...).pipe(Layer.provide(...))`, then default-export the entry as `defineEffectBff({ api, layer })`. See `packages/
|
|
125
|
+
For UltraModern, Effect `HttpApi` plus Effect BFF is the single blessed authored HTTP path. Use `HttpApi` endpoints with `query`, `params`, `payload`, `success`, and declared errors such as `HttpApiSchema.status(...)`; implement them with `HttpApiBuilder.group(...).handle(...)` and `HttpApiBuilder.layer(...).pipe(Layer.provide(...))`, then default-export the entry as `defineEffectBff({ api, layer })`. See `packages/server/bff-effect/tests/effect-edge-runtime.test.ts` for the live runtime shape.
|
|
126
126
|
|
|
127
127
|
Hono and `api/lambda/**` are internal compatibility only and feature-frozen.
|
|
128
128
|
|
|
@@ -267,11 +267,11 @@ First, you need to configure the **Root Directory** as `packages/app` on the Ver
|
|
|
267
267
|
|
|
268
268
|
<img src="https://sf16-sg.tiktokcdn.com/obj/eden-sg/lmeh7nuptpfnuhd/vercel-root-directory.png" />
|
|
269
269
|
|
|
270
|
-
Specify Node.js runtime as `
|
|
270
|
+
Specify Node.js runtime as `26.7.0` or newer:
|
|
271
271
|
|
|
272
272
|
```json title="package.json"
|
|
273
273
|
"engines": {
|
|
274
|
-
"node": "
|
|
274
|
+
"node": ">=26.7.0"
|
|
275
275
|
}
|
|
276
276
|
```
|
|
277
277
|
|
|
@@ -27,7 +27,7 @@ import DebugApp from '@site-docs-en/components/debug-app';
|
|
|
27
27
|
|
|
28
28
|
## Configuration
|
|
29
29
|
|
|
30
|
-
In an UltraModern.js project created using `@bleedingdev/modern-js-create`, a `modern.config.ts` file is generated by default.
|
|
30
|
+
In an UltraModern.js project created using `@bleedingdev/modern-js-ultramodern-create`, a `modern.config.ts` file is generated by default.
|
|
31
31
|
|
|
32
32
|
You can modify the configuration through this file to override the default behavior of Modern.js. For example, to enable SSR, add the following configuration:
|
|
33
33
|
|
|
@@ -24,7 +24,7 @@ Modern.js provides two first-party routing frameworks:
|
|
|
24
24
|
When creating an UltraModern project, TanStack Router is included by default:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
27
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Modern.js supports conventional routing, self-controlled routing, or other routing schemes. Please refer to ["Routing"](/guides/basic-features/routes/routes) to make your choice.
|
|
@@ -69,9 +69,9 @@ For an older generated workspace, migrate by treating the published cohort as
|
|
|
69
69
|
the source of truth:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
pnpm dlx @bleedingdev/modern-js-create@latest --help
|
|
73
|
-
pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical --dry-run
|
|
74
|
-
pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical
|
|
72
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest --help
|
|
73
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical --dry-run
|
|
74
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical
|
|
75
75
|
mise install
|
|
76
76
|
mise exec -- pnpm install
|
|
77
77
|
mise exec -- pnpm check
|
|
@@ -91,8 +91,8 @@ package cohort together. Resolve the current cohort version first, then run
|
|
|
91
91
|
the matching migration:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
COHORT="$(npm view @bleedingdev/modern-js-create version)"
|
|
95
|
-
pnpm dlx "@bleedingdev/modern-js-create@$COHORT" ultramodern \
|
|
94
|
+
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
95
|
+
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
96
96
|
migrate-strict-effect --version "$COHORT"
|
|
97
97
|
pnpm install
|
|
98
98
|
pnpm check
|
|
@@ -130,8 +130,8 @@ Before hand-editing package aliases or generated metadata, run the framework
|
|
|
130
130
|
migration command from the target workspace:
|
|
131
131
|
|
|
132
132
|
```bash
|
|
133
|
-
COHORT="$(npm view @bleedingdev/modern-js-create version)"
|
|
134
|
-
pnpm dlx "@bleedingdev/modern-js-create@$COHORT" ultramodern \
|
|
133
|
+
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
134
|
+
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
135
135
|
migrate-strict-effect --version "$COHORT"
|
|
136
136
|
pnpm api:check
|
|
137
137
|
pnpm contract:check
|
|
@@ -354,7 +354,7 @@ BFF, Module Federation topology, generated quality gates, and Cloudflare deploy
|
|
|
354
354
|
basics:
|
|
355
355
|
|
|
356
356
|
```bash
|
|
357
|
-
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
357
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp
|
|
358
358
|
cd myapp
|
|
359
359
|
mise install
|
|
360
360
|
mise exec -- pnpm install
|
|
@@ -366,10 +366,10 @@ generate a demo domain by default. Add real business MicroVerticals when they
|
|
|
366
366
|
become real ownership boundaries:
|
|
367
367
|
|
|
368
368
|
```bash
|
|
369
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
370
|
-
pnpm dlx @bleedingdev/modern-js-create food-delivery --vertical
|
|
371
|
-
pnpm dlx @bleedingdev/modern-js-create payments --vertical
|
|
372
|
-
pnpm dlx @bleedingdev/modern-js-create maps --vertical
|
|
369
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical
|
|
370
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create food-delivery --vertical
|
|
371
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create payments --vertical
|
|
372
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create maps --vertical
|
|
373
373
|
mise exec -- pnpm check
|
|
374
374
|
```
|
|
375
375
|
|
|
@@ -385,10 +385,10 @@ Automation can use explicit MicroVertical syntax instead of relying on the
|
|
|
385
385
|
positional form:
|
|
386
386
|
|
|
387
387
|
```bash
|
|
388
|
-
pnpm dlx @bleedingdev/modern-js-create --vertical=transportation
|
|
389
|
-
pnpm dlx @bleedingdev/modern-js-create --vertical-name transportation
|
|
390
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical --dry-run
|
|
391
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical \
|
|
388
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create --vertical=transportation
|
|
389
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create --vertical-name transportation
|
|
390
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical --dry-run
|
|
391
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical \
|
|
392
392
|
--codesmith-overlay ./generators/vertical-overlay
|
|
393
393
|
```
|
|
394
394
|
|
|
@@ -407,7 +407,7 @@ import {
|
|
|
407
407
|
addUltramodernVertical,
|
|
408
408
|
generateUltramodernWorkspace,
|
|
409
409
|
planUltramodernVertical,
|
|
410
|
-
} from '@modern-js/create/ultramodern-workspace';
|
|
410
|
+
} from '@modern-js/ultramodern-create/ultramodern-workspace';
|
|
411
411
|
|
|
412
412
|
const workspace = generateUltramodernWorkspace({
|
|
413
413
|
targetDir: '/tmp/my-workspace',
|
|
@@ -439,7 +439,7 @@ returns the same shape plus `dryRun`, `selectedPort`, `moduleFederationRemote`,
|
|
|
439
439
|
CodeSmith consumers can use the adapter subpath:
|
|
440
440
|
|
|
441
441
|
```ts
|
|
442
|
-
import ultramodernCodeSmith from '@modern-js/create/ultramodern-workspace/codesmith';
|
|
442
|
+
import ultramodernCodeSmith from '@modern-js/ultramodern-create/ultramodern-workspace/codesmith';
|
|
443
443
|
|
|
444
444
|
await ultramodernCodeSmith({
|
|
445
445
|
config: {
|
|
@@ -35,5 +35,5 @@ pnpm run command --options
|
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
:::tip
|
|
38
|
-
|
|
38
|
+
UltraModern.js requires Node.js >= 26.7.0 and pnpm >= 11. Use the repository's pinned mise toolchain so the CLI and native TypeScript runtime stay aligned.
|
|
39
39
|
:::
|
|
@@ -4,7 +4,7 @@ title: Route Authorization
|
|
|
4
4
|
|
|
5
5
|
# Route Authorization
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
UltraModern.js uses convention-based routing backed by TanStack Router. For more details, please refer to [Routing](/guides/basic-features/routes/routes#routing).
|
|
8
8
|
|
|
9
9
|
In a web application, if there are multiple routes, we may need to authorize access to some of them before accessing them. For example, in the following scenario:
|
|
10
10
|
|
|
@@ -12,6 +12,7 @@ In a web application, if there are multiple routes, we may need to authorize acc
|
|
|
12
12
|
- Access to the `/protected` route requires authorization. If there is no authorization, it will automatically redirect to the `/login` route. After successful login, it returns to `/protected`.
|
|
13
13
|
|
|
14
14
|
import Sandpack from '@site/src/components/Sandpack';
|
|
15
|
+
import { ultramodernSandpackFiles } from '@modern-js/ultramodern-sandpack-profile';
|
|
15
16
|
import srcRoutesPageText from '../../../../src/sandbox/csr-auth/src/routes/page-tsx.txt';
|
|
16
17
|
import srcRoutesLayoutText from '../../../../src/sandbox/csr-auth/src/routes/layout-tsx.txt';
|
|
17
18
|
import srcRoutesAuthText from '../../../../src/sandbox/csr-auth/src/routes/Auth-tsx.txt';
|
|
@@ -20,6 +21,7 @@ import srcRoutesProtectedPageText from '../../../../src/sandbox/csr-auth/src/rou
|
|
|
20
21
|
import srcRoutesLoginPageText from '../../../../src/sandbox/csr-auth/src/routes/login/page-tsx.txt';
|
|
21
22
|
|
|
22
23
|
<Sandpack template="web-app" files={{
|
|
24
|
+
...ultramodernSandpackFiles,
|
|
23
25
|
'/src/routes/page.tsx': srcRoutesPageText,
|
|
24
26
|
'/src/routes/layout.tsx': srcRoutesLayoutText,
|
|
25
27
|
'/src/routes/Auth.tsx': srcRoutesAuthText,
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
sidebar_position: 0
|
|
3
|
+
title: 生态系统
|
|
3
4
|
---
|
|
4
5
|
|
|
5
|
-
#
|
|
6
|
+
# 生态系统
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
UltraModern.js 建立在一组聚焦的框架与工具之上。这些项目提供了本 fork 使用的 Effect、TanStack Router、构建、文档与 Module Federation 基础能力。
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## 案例
|
|
10
|
+
## 项目
|
|
12
11
|
|
|
13
12
|
import { ShowcaseList } from '@site/src/components/ShowcaseList';
|
|
14
13
|
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
UltraModern.js 提供 BleedingDev create 包来创建 SuperApp workspace,不需要全局安装,直接使用 `pnpm dlx` 按需运行即可。
|
|
2
2
|
|
|
3
3
|
pnpm 支持的命令契约是 scoped package specifier:
|
|
4
|
-
`pnpm dlx @bleedingdev/modern-js-create <target>`。不要简写成
|
|
5
|
-
`pnpm dlx modern-js-create`;npm 上没有这个未加 scope 的包。
|
|
4
|
+
`pnpm dlx @bleedingdev/modern-js-ultramodern-create <target>`。不要简写成
|
|
5
|
+
`pnpm dlx modern-js-ultramodern-create`;npm 上没有这个未加 scope 的包。
|
|
6
6
|
|
|
7
7
|
你可以在当前已有的空目录中初始化项目:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
mkdir myapp && cd myapp
|
|
11
|
-
pnpm dlx @bleedingdev/modern-js-create .
|
|
11
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create .
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
也可以直接用新目录创建项目:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
17
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
使用 workspace 协议依赖初始化(用于在本地 monorepo 中联调未发布的 Modern.js 包):
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
pnpm dlx @bleedingdev/modern-js-create myapp --workspace
|
|
23
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp --workspace
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
BleedingDev create 包会直接创建应用,不再提供问答界面:
|
|
@@ -70,14 +70,14 @@ BleedingDev create 包会直接创建应用,不再提供问答界面:
|
|
|
70
70
|
默认 workspace 从 shell 起步,并安装已发布的 BleedingDev 包别名:
|
|
71
71
|
|
|
72
72
|
```bash
|
|
73
|
-
pnpm dlx @bleedingdev/modern-js-create my-super-app
|
|
73
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create my-super-app
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
在已生成的 SuperApp workspace 根目录中,可以就地添加业务
|
|
77
77
|
MicroVertical:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
80
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
`--vertical` 会修改当前 workspace:新增 vertical 包,并写入 topology、
|
|
@@ -258,11 +258,11 @@ Vercel 是一个面向现代 Web 应用的部署平台,它提供了丰富的
|
|
|
258
258
|
|
|
259
259
|
<img src="https://sf16-sg.tiktokcdn.com/obj/eden-sg/lmeh7nuptpfnuhd/vercel-root-directory.png" />
|
|
260
260
|
|
|
261
|
-
将 Node.js 运行时设置为 `
|
|
261
|
+
将 Node.js 运行时设置为 `26.7.0` 或更高版本:
|
|
262
262
|
|
|
263
263
|
```json title="package.json"
|
|
264
264
|
"engines": {
|
|
265
|
-
"node": "
|
|
265
|
+
"node": ">=26.7.0"
|
|
266
266
|
},
|
|
267
267
|
```
|
|
268
268
|
|
|
@@ -25,7 +25,7 @@ import DebugApp from '@site-docs/components/debug-app';
|
|
|
25
25
|
|
|
26
26
|
## 使用配置
|
|
27
27
|
|
|
28
|
-
通过 `@bleedingdev/modern-js-create` 创建的 UltraModern.js 项目中,会默认生成 `modern.config.ts` 文件。
|
|
28
|
+
通过 `@bleedingdev/modern-js-ultramodern-create` 创建的 UltraModern.js 项目中,会默认生成 `modern.config.ts` 文件。
|
|
29
29
|
|
|
30
30
|
你可以通过该配置文件修改配置,覆盖 Modern.js 的默认行为。例如添加如下配置,开启 SSR:
|
|
31
31
|
|
|
@@ -24,7 +24,7 @@ Modern.js 提供两套一方路由方案:
|
|
|
24
24
|
创建 UltraModern 项目时,默认会包含 TanStack Router:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
27
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Modern.js 支持约定式路由、自控式路由或其他路由方案,请参考 [页面入口](/guides/concept/entries) 进行选择。
|
|
@@ -62,9 +62,9 @@ UltraModern.js 的增强能力是新 SuperApp 的默认产品面。框架方向
|
|
|
62
62
|
旧版生成 workspace 迁移时,以已发布的包 cohort 作为事实来源:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
pnpm dlx @bleedingdev/modern-js-create@latest --help
|
|
66
|
-
pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical --dry-run
|
|
67
|
-
pnpm dlx @bleedingdev/modern-js-create@latest catalog --vertical
|
|
65
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest --help
|
|
66
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical --dry-run
|
|
67
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical
|
|
68
68
|
mise install
|
|
69
69
|
mise exec -- pnpm install
|
|
70
70
|
mise exec -- pnpm check
|
|
@@ -81,8 +81,8 @@ server runtime 中。请求 `/` 时,框架会按语言协商在服务端返回
|
|
|
81
81
|
先解析当前 cohort 版本,再运行同版本迁移命令:
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
|
-
COHORT="$(npm view @bleedingdev/modern-js-create version)"
|
|
85
|
-
pnpm dlx "@bleedingdev/modern-js-create@$COHORT" ultramodern \
|
|
84
|
+
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
85
|
+
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
86
86
|
migrate-strict-effect --version "$COHORT"
|
|
87
87
|
pnpm install
|
|
88
88
|
pnpm check
|
|
@@ -114,8 +114,8 @@ postprocess、生成产物编辑或本地 redirect shim 来修复旧版本的 ro
|
|
|
114
114
|
手写 package alias 或生成 metadata 之前,先在目标 workspace 运行框架迁移命令:
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
COHORT="$(npm view @bleedingdev/modern-js-create version)"
|
|
118
|
-
pnpm dlx "@bleedingdev/modern-js-create@$COHORT" ultramodern \
|
|
117
|
+
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
118
|
+
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
119
119
|
migrate-strict-effect --version "$COHORT"
|
|
120
120
|
pnpm api:check
|
|
121
121
|
pnpm contract:check
|
|
@@ -310,7 +310,7 @@ SSR、TanStack Router、Tailwind CSS v4、i18n、Effect HttpApi BFF、Module Fed
|
|
|
310
310
|
topology、生成质量 gate,以及 Cloudflare 部署基础:
|
|
311
311
|
|
|
312
312
|
```bash
|
|
313
|
-
pnpm dlx @bleedingdev/modern-js-create myapp
|
|
313
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create myapp
|
|
314
314
|
cd myapp
|
|
315
315
|
mise install
|
|
316
316
|
mise exec -- pnpm install
|
|
@@ -321,10 +321,10 @@ workspace 从 shell 和平台契约起步,不强制生成演示业务域。真
|
|
|
321
321
|
再添加对应 MicroVertical:
|
|
322
322
|
|
|
323
323
|
```bash
|
|
324
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical
|
|
325
|
-
pnpm dlx @bleedingdev/modern-js-create food-delivery --vertical
|
|
326
|
-
pnpm dlx @bleedingdev/modern-js-create payments --vertical
|
|
327
|
-
pnpm dlx @bleedingdev/modern-js-create maps --vertical
|
|
324
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical
|
|
325
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create food-delivery --vertical
|
|
326
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create payments --vertical
|
|
327
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create maps --vertical
|
|
328
328
|
mise exec -- pnpm check
|
|
329
329
|
```
|
|
330
330
|
|
|
@@ -337,10 +337,10 @@ ownership 记录、shell Module Federation、开发 overlays、包依赖、生
|
|
|
337
337
|
自动化脚本可以使用显式 MicroVertical 语法,不必依赖位置参数:
|
|
338
338
|
|
|
339
339
|
```bash
|
|
340
|
-
pnpm dlx @bleedingdev/modern-js-create --vertical=transportation
|
|
341
|
-
pnpm dlx @bleedingdev/modern-js-create --vertical-name transportation
|
|
342
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical --dry-run
|
|
343
|
-
pnpm dlx @bleedingdev/modern-js-create transportation --vertical \
|
|
340
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create --vertical=transportation
|
|
341
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create --vertical-name transportation
|
|
342
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical --dry-run
|
|
343
|
+
pnpm dlx @bleedingdev/modern-js-ultramodern-create transportation --vertical \
|
|
344
344
|
--codesmith-overlay ./generators/vertical-overlay
|
|
345
345
|
```
|
|
346
346
|
|
|
@@ -358,7 +358,7 @@ import {
|
|
|
358
358
|
addUltramodernVertical,
|
|
359
359
|
generateUltramodernWorkspace,
|
|
360
360
|
planUltramodernVertical,
|
|
361
|
-
} from '@modern-js/create/ultramodern-workspace';
|
|
361
|
+
} from '@modern-js/ultramodern-create/ultramodern-workspace';
|
|
362
362
|
|
|
363
363
|
const workspace = generateUltramodernWorkspace({
|
|
364
364
|
targetDir: '/tmp/my-workspace',
|
|
@@ -389,7 +389,7 @@ MicroVertical dry-run 返回相同结构,并额外包含 `dryRun`、`selectedP
|
|
|
389
389
|
CodeSmith 消费方可以使用 adapter subpath:
|
|
390
390
|
|
|
391
391
|
```ts
|
|
392
|
-
import ultramodernCodeSmith from '@modern-js/create/ultramodern-workspace/codesmith';
|
|
392
|
+
import ultramodernCodeSmith from '@modern-js/ultramodern-create/ultramodern-workspace/codesmith';
|
|
393
393
|
|
|
394
394
|
await ultramodernCodeSmith({
|
|
395
395
|
config: {
|
|
@@ -4,7 +4,7 @@ title: 路由鉴权
|
|
|
4
4
|
|
|
5
5
|
# 路由鉴权
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
UltraModern.js 默认使用基于 TanStack Router 的约定式路由,具体可查看[路由方案](/guides/basic-features/routes/routes#路由方案)。
|
|
8
8
|
|
|
9
9
|
在一个 Web 应用中如果存在多个路由,我们可能需要对部分路由进行鉴权后才能访问。例如下面这个案例:
|
|
10
10
|
|
|
@@ -12,6 +12,7 @@ Modern.js 默认提供的路由方式是基于 React Router 的约定式路由
|
|
|
12
12
|
- 访问 `/protected` 路由,需要鉴权,如果无,自动跳转到 `/login` 路由,登录成功后返回 `/protected`。
|
|
13
13
|
|
|
14
14
|
import Sandpack from '@site/src/components/Sandpack';
|
|
15
|
+
import { ultramodernSandpackFiles } from '@modern-js/ultramodern-sandpack-profile';
|
|
15
16
|
import srcRoutesPageText from '../../../../src/sandbox/csr-auth/src/routes/page-tsx.txt';
|
|
16
17
|
import srcRoutesLayoutText from '../../../../src/sandbox/csr-auth/src/routes/layout-tsx.txt';
|
|
17
18
|
import srcRoutesAuthText from '../../../../src/sandbox/csr-auth/src/routes/Auth-tsx.txt';
|
|
@@ -20,6 +21,7 @@ import srcRoutesProtectedPageText from '../../../../src/sandbox/csr-auth/src/rou
|
|
|
20
21
|
import srcRoutesLoginPageText from '../../../../src/sandbox/csr-auth/src/routes/login/page-tsx.txt';
|
|
21
22
|
|
|
22
23
|
<Sandpack template="web-app" files={{
|
|
24
|
+
...ultramodernSandpackFiles,
|
|
23
25
|
'/src/routes/page.tsx': srcRoutesPageText,
|
|
24
26
|
'/src/routes/layout.tsx': srcRoutesLayoutText,
|
|
25
27
|
'/src/routes/Auth.tsx': srcRoutesAuthText,
|
package/package.json
CHANGED
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
"modern.js",
|
|
20
20
|
"ultramodern.js"
|
|
21
21
|
],
|
|
22
|
-
"version": "3.8.3-ultramodern.
|
|
22
|
+
"version": "3.8.3-ultramodern.2",
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@modern-js/sandpack-react": "npm:@bleedingdev/modern-js-sandpack-react@3.8.3-ultramodern.
|
|
27
|
+
"@modern-js/sandpack-react": "npm:@bleedingdev/modern-js-sandpack-react@3.8.3-ultramodern.2",
|
|
28
|
+
"@modern-js/ultramodern-sandpack-profile": "npm:@bleedingdev/modern-js-ultramodern-sandpack-profile@3.8.3-ultramodern.2",
|
|
28
29
|
"mermaid": "^11.16.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
package/rspress.config.ts
CHANGED
|
@@ -1,44 +1,26 @@
|
|
|
1
1
|
import { pluginSass } from '@rsbuild/plugin-sass';
|
|
2
|
-
import { defineConfig } from '@rspress/core';
|
|
3
2
|
import { transformerNotationHighlight } from '@shikijs/transformers';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
import { pluginOpenGraph } from 'rsbuild-plugin-open-graph';
|
|
5
|
+
import { defineUltraModernConfig as defineConfig } from './ultramodern-preset/src/index.ts';
|
|
6
6
|
|
|
7
7
|
const docPath = path.join(__dirname, 'docs');
|
|
8
|
-
const
|
|
9
|
-
const siteTitle = 'UltraModern.js 3.0';
|
|
8
|
+
const siteTitle = 'Modern.js';
|
|
10
9
|
const siteDescription =
|
|
11
|
-
'
|
|
10
|
+
'The Modern.js framework is a progressive web framework based on React. At ByteDance, we use Modern.js to build upper-level frameworks that have supported the development of thousands of web applications.';
|
|
12
11
|
const socialDescription =
|
|
13
|
-
'A
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const trimmed = base.trim();
|
|
17
|
-
const withLeadingSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
18
|
-
return withLeadingSlash.endsWith('/')
|
|
19
|
-
? withLeadingSlash
|
|
20
|
-
: `${withLeadingSlash}/`;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Set by CI for GitHub Pages project sites. Defaults to root for local dev/custom domains.
|
|
24
|
-
const docsBase = normalizeBase(process.env.DOCS_BASE);
|
|
25
|
-
const docsOrigin = (
|
|
26
|
-
process.env.DOCS_ORIGIN || 'https://bleedingdev.github.io'
|
|
27
|
-
).replace(/\/+$/, '');
|
|
28
|
-
const siteUrl = new URL(docsBase, `${docsOrigin}/`).toString();
|
|
29
|
-
const socialImage = new URL('img/social-card.svg', siteUrl).toString();
|
|
30
|
-
const faviconUrl = new URL('img/favicon.ico', siteUrl).toString();
|
|
31
|
-
const docsAsset = (assetPath: string) =>
|
|
32
|
-
`${docsBase}${assetPath.replace(/^\//, '')}`;
|
|
12
|
+
'A Progressive React Framework for modern web development.';
|
|
13
|
+
const socialImage =
|
|
14
|
+
'https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/banner.jpeg';
|
|
33
15
|
|
|
34
16
|
export default defineConfig({
|
|
35
17
|
root: docPath,
|
|
36
18
|
llms: true,
|
|
37
19
|
title: siteTitle,
|
|
38
20
|
description: siteDescription,
|
|
39
|
-
base:
|
|
40
|
-
logo:
|
|
41
|
-
icon:
|
|
21
|
+
base: '/',
|
|
22
|
+
logo: 'https://lf-cdn-tos.bytescm.com/obj/static/webinfra/modern-js-website/assets/images/images/modernjs-logo.svg',
|
|
23
|
+
icon: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/uhbfnupenuhf/favicon.ico',
|
|
42
24
|
lang: 'en',
|
|
43
25
|
themeDir: path.join(__dirname, 'src'),
|
|
44
26
|
markdown: {
|
|
@@ -50,40 +32,24 @@ export default defineConfig({
|
|
|
50
32
|
search: {
|
|
51
33
|
codeBlocks: true,
|
|
52
34
|
},
|
|
53
|
-
// head: [
|
|
54
|
-
// () => {
|
|
55
|
-
// return [
|
|
56
|
-
// `<meta property="og:image" content="${socialImage}">`,
|
|
57
|
-
// `<meta property="og:description" content="${socialDescription}">`,
|
|
58
|
-
// `<meta property="og:image:alt" content="${siteTitle}">`,
|
|
59
|
-
// `<meta name="twitter:card" content="summary_large_image">`,
|
|
60
|
-
// `<meta name="twitter:title" content="${siteTitle}">`,
|
|
61
|
-
// `<meta name="twitter:description" content="${socialDescription}">`,
|
|
62
|
-
// `<meta name="twitter:image" content="${socialImage}">`,
|
|
63
|
-
// `<meta name="twitter:image:alt" content="${siteTitle}">`,
|
|
64
|
-
// ].join('');
|
|
65
|
-
// },
|
|
66
|
-
// ],
|
|
67
35
|
themeConfig: {
|
|
68
36
|
locales: [
|
|
69
37
|
{
|
|
70
38
|
lang: 'zh',
|
|
71
39
|
title: siteTitle,
|
|
72
40
|
description: socialDescription,
|
|
73
|
-
// nav: getNavbar('zh'),
|
|
74
41
|
label: '简体中文',
|
|
75
42
|
},
|
|
76
43
|
{
|
|
77
44
|
lang: 'en',
|
|
78
45
|
title: siteTitle,
|
|
79
46
|
description: socialDescription,
|
|
80
|
-
// nav: getNavbar('en'),
|
|
81
47
|
label: 'English',
|
|
82
48
|
},
|
|
83
49
|
],
|
|
84
50
|
editLink: {
|
|
85
51
|
docRepoBaseUrl:
|
|
86
|
-
'https://github.com/
|
|
52
|
+
'https://github.com/web-infra-dev/modern.js/tree/main/packages/document/docs',
|
|
87
53
|
text: 'Edit this page on GitHub',
|
|
88
54
|
},
|
|
89
55
|
socialLinks: [
|
|
@@ -95,7 +61,7 @@ export default defineConfig({
|
|
|
95
61
|
{
|
|
96
62
|
icon: 'github',
|
|
97
63
|
mode: 'link',
|
|
98
|
-
content: 'https://github.com/
|
|
64
|
+
content: 'https://github.com/web-infra-dev/modern.js',
|
|
99
65
|
},
|
|
100
66
|
],
|
|
101
67
|
},
|
|
@@ -105,7 +71,8 @@ export default defineConfig({
|
|
|
105
71
|
},
|
|
106
72
|
replaceRules: [
|
|
107
73
|
{
|
|
108
|
-
//
|
|
74
|
+
// The major version is different inside the ByteDance,
|
|
75
|
+
// so we use a flag to define it.
|
|
109
76
|
search: /MAJOR_VERSION/g,
|
|
110
77
|
replace: '2',
|
|
111
78
|
},
|
|
@@ -128,11 +95,6 @@ export default defineConfig({
|
|
|
128
95
|
output: {
|
|
129
96
|
dataUriLimit: 0,
|
|
130
97
|
},
|
|
131
|
-
server: {
|
|
132
|
-
publicDir: {
|
|
133
|
-
name: staticPath,
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
98
|
dev: {
|
|
137
99
|
lazyCompilation: process.env.LAZY !== 'false',
|
|
138
100
|
},
|
|
@@ -147,15 +109,15 @@ export default defineConfig({
|
|
|
147
109
|
pluginSass(),
|
|
148
110
|
pluginOpenGraph({
|
|
149
111
|
// Note, title is page-specific
|
|
150
|
-
title: '
|
|
112
|
+
title: 'Modern.js Home Page',
|
|
151
113
|
// While site name is site wide
|
|
152
114
|
siteName: siteTitle,
|
|
153
115
|
type: 'website',
|
|
154
|
-
url:
|
|
116
|
+
url: 'https://modernjs.dev/',
|
|
155
117
|
image: socialImage,
|
|
156
118
|
description: socialDescription,
|
|
157
119
|
twitter: {
|
|
158
|
-
site: '@
|
|
120
|
+
site: '@_Modern_JS',
|
|
159
121
|
card: 'summary_large_image',
|
|
160
122
|
},
|
|
161
123
|
}),
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Navigate,
|
|
3
|
+
useLocation,
|
|
4
|
+
useNavigate,
|
|
5
|
+
} from '@modern-js/plugin-tanstack/runtime';
|
|
2
6
|
import React from 'react';
|
|
3
7
|
import { fakeAuthProvider } from './fakeAuth';
|
|
4
8
|
|
|
@@ -49,7 +53,7 @@ export function AuthStatus() {
|
|
|
49
53
|
<button
|
|
50
54
|
type="button"
|
|
51
55
|
onClick={() => {
|
|
52
|
-
auth.signout(() => navigate('/'));
|
|
56
|
+
auth.signout(() => void navigate({ to: '/' }));
|
|
53
57
|
}}
|
|
54
58
|
>
|
|
55
59
|
Sign out
|
|
@@ -67,7 +71,13 @@ export function RequireAuth({ children }: { children: JSX.Element }) {
|
|
|
67
71
|
// trying to go to when they were redirected. This allows us to send them
|
|
68
72
|
// along to that page after they login, which is a nicer user experience
|
|
69
73
|
// than dropping them off on the home page.
|
|
70
|
-
return
|
|
74
|
+
return (
|
|
75
|
+
<Navigate
|
|
76
|
+
replace
|
|
77
|
+
search={{ redirect: location.pathname }}
|
|
78
|
+
to="/login"
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
return children;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Link, Outlet } from '@modern-js/runtime
|
|
1
|
+
import { Link, Outlet } from '@modern-js/plugin-tanstack/runtime';
|
|
2
2
|
import { AuthProvider, AuthStatus } from './Auth';
|
|
3
3
|
|
|
4
4
|
export default function Layout() {
|
|
@@ -8,10 +8,10 @@ export default function Layout() {
|
|
|
8
8
|
|
|
9
9
|
<ul>
|
|
10
10
|
<li>
|
|
11
|
-
<Link to="/">Public Page</Link>
|
|
11
|
+
<Link prefetch="render" to="/">Public Page</Link>
|
|
12
12
|
</li>
|
|
13
13
|
<li>
|
|
14
|
-
<Link to="/protected">Protected Page</Link>
|
|
14
|
+
<Link prefetch="render" to="/protected">Protected Page</Link>
|
|
15
15
|
</li>
|
|
16
16
|
</ul>
|
|
17
17
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useLocation,
|
|
3
|
+
useNavigate,
|
|
4
|
+
} from '@modern-js/plugin-tanstack/runtime';
|
|
2
5
|
import { useAuth } from '../Auth';
|
|
3
6
|
|
|
4
7
|
export default function Login() {
|
|
@@ -6,7 +9,8 @@ export default function Login() {
|
|
|
6
9
|
const location = useLocation();
|
|
7
10
|
const auth = useAuth();
|
|
8
11
|
|
|
9
|
-
const from =
|
|
12
|
+
const from =
|
|
13
|
+
new URLSearchParams(location.searchStr).get('redirect') || '/';
|
|
10
14
|
|
|
11
15
|
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
|
|
12
16
|
event.preventDefault();
|
|
@@ -21,7 +25,7 @@ export default function Login() {
|
|
|
21
25
|
// when they get to the protected page and click the back button, they
|
|
22
26
|
// won't end up back on the login page, which is also really nice for the
|
|
23
27
|
// user experience.
|
|
24
|
-
navigate(
|
|
28
|
+
void navigate({ replace: true, to: from });
|
|
25
29
|
});
|
|
26
30
|
}
|
|
27
31
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="48" viewBox="0 0 220 48" role="img" aria-labelledby="title">
|
|
2
|
+
<title id="title">UltraModern.js</title>
|
|
3
|
+
<rect width="48" height="48" rx="12" fill="#020617"/>
|
|
4
|
+
<path fill="#14b8a6" d="M13 13h7v13c0 5 2.6 8 7 8s7-3 7-8V13h7v13c0 8.8-5.6 14-14 14s-14-5.2-14-14V13z"/>
|
|
5
|
+
<path fill="#38bdf8" d="M31 13h8v27h-8V13z"/>
|
|
6
|
+
<text x="60" y="31" fill="#f8fafc" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif" font-size="23" font-weight="700">UltraModern.js</text>
|
|
7
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modern-js/ultramodern-docs-preset",
|
|
3
|
+
"version": "3.8.3",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "node --test tests/*.test.ts"
|
|
8
|
+
},
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=26.7.0"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"rsbuild-plugin-open-graph": "1.1.3"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@rspress/core": "2.0.17",
|
|
17
|
+
"@types/node": "^26.2.0"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { defineConfig, type UserConfig } from '@rspress/core';
|
|
4
|
+
import { pluginOpenGraph } from 'rsbuild-plugin-open-graph';
|
|
5
|
+
|
|
6
|
+
const siteTitle = 'UltraModern.js 3.0';
|
|
7
|
+
const siteDescription =
|
|
8
|
+
'UltraModern.js 3.0 is a SuperApp framework forked from Modern.js for Effect, TanStack Router, SSR, BFF, and independently deployable Micro Verticals.';
|
|
9
|
+
const socialDescription =
|
|
10
|
+
'A SuperApp framework for Effect, TanStack Router, SSR, BFF, and Micro Verticals.';
|
|
11
|
+
const defaultOrigin = 'https://bleedingdev.github.io';
|
|
12
|
+
const githubUrl = 'https://github.com/BleedingDev/ultramodern.js';
|
|
13
|
+
|
|
14
|
+
export const ultraModernDocsAssets = new URL('../assets/', import.meta.url);
|
|
15
|
+
|
|
16
|
+
export type UltraModernDocsPresetOptions = {
|
|
17
|
+
base?: string;
|
|
18
|
+
origin?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const normalizeBase = (base = '/') => {
|
|
22
|
+
const trimmed = base.trim();
|
|
23
|
+
const withLeadingSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
24
|
+
return withLeadingSlash.endsWith('/')
|
|
25
|
+
? withLeadingSlash
|
|
26
|
+
: `${withLeadingSlash}/`;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const asPublicDirectories = (
|
|
30
|
+
publicDir: NonNullable<
|
|
31
|
+
NonNullable<UserConfig['builderConfig']>['server']
|
|
32
|
+
>['publicDir'],
|
|
33
|
+
) => {
|
|
34
|
+
if (!publicDir) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
return Array.isArray(publicDir) ? publicDir : [publicDir];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const applyUltraModernDocsPreset = (
|
|
41
|
+
config: UserConfig,
|
|
42
|
+
options: UltraModernDocsPresetOptions = {},
|
|
43
|
+
): UserConfig => {
|
|
44
|
+
const base = normalizeBase(options.base ?? process.env.DOCS_BASE);
|
|
45
|
+
const origin = (options.origin ?? process.env.DOCS_ORIGIN ?? defaultOrigin)
|
|
46
|
+
.trim()
|
|
47
|
+
.replace(/\/+$/, '');
|
|
48
|
+
const siteUrl = new URL(base, `${origin || defaultOrigin}/`).toString();
|
|
49
|
+
const publicAsset = (assetPath: string) =>
|
|
50
|
+
`${base}${assetPath.replace(/^\//, '')}`;
|
|
51
|
+
const absoluteAsset = (assetPath: string) =>
|
|
52
|
+
new URL(assetPath.replace(/^\//, ''), siteUrl).toString();
|
|
53
|
+
const builderConfig = config.builderConfig ?? {};
|
|
54
|
+
const server = builderConfig.server ?? {};
|
|
55
|
+
const themeConfig = config.themeConfig ?? {};
|
|
56
|
+
const documentStatic = config.root
|
|
57
|
+
? { name: path.resolve(config.root, '..', 'static') }
|
|
58
|
+
: undefined;
|
|
59
|
+
const presetAssets = { name: fileURLToPath(ultraModernDocsAssets) };
|
|
60
|
+
const publicDirectories = [
|
|
61
|
+
...asPublicDirectories(server.publicDir),
|
|
62
|
+
...(documentStatic ? [documentStatic] : []),
|
|
63
|
+
presetAssets,
|
|
64
|
+
].filter(
|
|
65
|
+
(candidate, index, all) =>
|
|
66
|
+
all.findIndex(entry => entry.name === candidate.name) === index,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
...config,
|
|
71
|
+
title: siteTitle,
|
|
72
|
+
description: siteDescription,
|
|
73
|
+
base,
|
|
74
|
+
logo: {
|
|
75
|
+
light: publicAsset('/img/ultramodern-logo-light.svg'),
|
|
76
|
+
dark: publicAsset('/img/ultramodern-logo-dark.svg'),
|
|
77
|
+
},
|
|
78
|
+
icon: absoluteAsset('/img/favicon.ico'),
|
|
79
|
+
themeConfig: {
|
|
80
|
+
...themeConfig,
|
|
81
|
+
locales: (themeConfig.locales ?? []).map(locale => ({
|
|
82
|
+
...locale,
|
|
83
|
+
title: siteTitle,
|
|
84
|
+
description: socialDescription,
|
|
85
|
+
})),
|
|
86
|
+
editLink: {
|
|
87
|
+
docRepoBaseUrl: `${githubUrl}/tree/main-ultramodern/packages/document/docs`,
|
|
88
|
+
text: 'Edit this page on GitHub',
|
|
89
|
+
},
|
|
90
|
+
socialLinks: [
|
|
91
|
+
...(themeConfig.socialLinks ?? []).filter(
|
|
92
|
+
link => link.icon !== 'github',
|
|
93
|
+
),
|
|
94
|
+
{ icon: 'github', mode: 'link', content: githubUrl },
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
builderConfig: {
|
|
98
|
+
...builderConfig,
|
|
99
|
+
server: {
|
|
100
|
+
...server,
|
|
101
|
+
publicDir: publicDirectories,
|
|
102
|
+
},
|
|
103
|
+
plugins: [
|
|
104
|
+
...(builderConfig.plugins ?? []).filter(
|
|
105
|
+
plugin => plugin.name !== 'rsbuild-plugin-open-graph',
|
|
106
|
+
),
|
|
107
|
+
pluginOpenGraph({
|
|
108
|
+
title: siteTitle,
|
|
109
|
+
siteName: siteTitle,
|
|
110
|
+
type: 'website',
|
|
111
|
+
url: siteUrl,
|
|
112
|
+
image: absoluteAsset('/img/ultramodern-social-card.png'),
|
|
113
|
+
description: socialDescription,
|
|
114
|
+
twitter: {
|
|
115
|
+
card: 'summary_large_image',
|
|
116
|
+
title: siteTitle,
|
|
117
|
+
image: absoluteAsset('/img/ultramodern-social-card.png'),
|
|
118
|
+
description: socialDescription,
|
|
119
|
+
},
|
|
120
|
+
}),
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const defineUltraModernConfig = (config: UserConfig): UserConfig =>
|
|
127
|
+
defineConfig(applyUltraModernDocsPreset(config));
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630" role="img" aria-labelledby="title desc">
|
|
2
|
-
<title id="title">UltraModern.js 3.0</title>
|
|
3
|
-
<desc id="desc">A SuperApp framework for Effect, TanStack Router, SSR, BFF, and Micro Verticals.</desc>
|
|
4
|
-
<rect width="1200" height="630" fill="#0f172a"/>
|
|
5
|
-
<path fill="#14b8a6" opacity=".22" d="M0 360c180-92 330-116 498-48 173 70 310 61 480-22 77-38 149-58 222-62v402H0V360z"/>
|
|
6
|
-
<path fill="#38bdf8" opacity=".18" d="M0 438c160-54 316-49 468 15 160 67 337 67 531 0 74-26 141-39 201-40v217H0V438z"/>
|
|
7
|
-
<rect x="86" y="90" width="96" height="96" rx="24" fill="#020617"/>
|
|
8
|
-
<path fill="#14b8a6" d="M111 116h15v35c0 13 7 21 18 21s18-8 18-21v-35h15v35c0 22-13 35-33 35s-33-13-33-35v-35z"/>
|
|
9
|
-
<path fill="#38bdf8" d="M157 116h18v70h-18v-70z"/>
|
|
10
|
-
<text x="86" y="284" fill="#f8fafc" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif" font-size="76" font-weight="800">UltraModern.js 3.0</text>
|
|
11
|
-
<text x="90" y="360" fill="#cbd5e1" font-family="Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif" font-size="35" font-weight="500">Effect, TanStack Router, SSR, BFF, and Micro Verticals.</text>
|
|
12
|
-
</svg>
|
|
File without changes
|