@modern-js/main-doc 2.51.0 → 2.53.0
Sign up to get free protection for your applications and to get access to all the features.
- package/docs/en/apis/app/runtime/web-server/unstable_middleware.mdx +30 -4
- package/docs/en/guides/advanced-features/web-server.mdx +4 -2
- package/docs/en/guides/basic-features/data/data-fetch.mdx +28 -0
- package/docs/en/guides/basic-features/deploy.mdx +143 -33
- package/docs/en/guides/basic-features/routes.mdx +2 -2
- package/docs/en/guides/get-started/tech-stack.mdx +0 -6
- package/docs/en/guides/topic-detail/framework-plugin/plugin-api.mdx +1 -1
- package/docs/en/guides/topic-detail/generator/create/option.md +0 -5
- package/docs/en/guides/topic-detail/generator/create/use.mdx +1 -10
- package/docs/en/guides/topic-detail/generator/new/config.md +0 -29
- package/docs/en/guides/topic-detail/generator/new/use.md +0 -20
- package/docs/zh/apis/app/runtime/web-server/unstable_middleware.mdx +30 -4
- package/docs/zh/guides/advanced-features/web-server.mdx +1 -1
- package/docs/zh/guides/basic-features/data/data-fetch.mdx +27 -2
- package/docs/zh/guides/basic-features/deploy.mdx +140 -36
- package/docs/zh/guides/basic-features/routes.mdx +2 -2
- package/docs/zh/guides/get-started/tech-stack.mdx +0 -6
- package/docs/zh/guides/topic-detail/framework-plugin/plugin-api.mdx +1 -1
- package/docs/zh/guides/topic-detail/generator/create/option.md +0 -5
- package/docs/zh/guides/topic-detail/generator/create/use.mdx +1 -10
- package/docs/zh/guides/topic-detail/generator/new/config.md +0 -31
- package/docs/zh/guides/topic-detail/generator/new/use.md +0 -20
- package/package.json +5 -5
- package/docs/en/apis/app/runtime/testing/_category_.json +0 -4
- package/docs/en/apis/app/runtime/testing/act.mdx +0 -35
- package/docs/en/apis/app/runtime/testing/cleanup.mdx +0 -40
- package/docs/en/apis/app/runtime/testing/render.mdx +0 -71
- package/docs/en/apis/app/runtime/testing/renderApp.mdx +0 -34
- package/docs/en/configure/app/testing/_category_.json +0 -4
- package/docs/en/configure/app/testing/transformer.mdx +0 -17
- package/docs/en/configure/app/tools/jest.mdx +0 -40
- package/docs/en/guides/advanced-features/testing.mdx +0 -47
- package/docs/en/guides/topic-detail/changesets/_category_.json +0 -4
- package/docs/en/guides/topic-detail/changesets/add.mdx +0 -125
- package/docs/en/guides/topic-detail/changesets/changelog.mdx +0 -238
- package/docs/en/guides/topic-detail/changesets/commit.mdx +0 -269
- package/docs/en/guides/topic-detail/changesets/config.mdx +0 -147
- package/docs/en/guides/topic-detail/changesets/github.mdx +0 -175
- package/docs/en/guides/topic-detail/changesets/introduce.mdx +0 -56
- package/docs/en/guides/topic-detail/changesets/release-note.mdx +0 -274
- package/docs/en/guides/topic-detail/changesets/release-pre.mdx +0 -49
- package/docs/en/guides/topic-detail/changesets/release.mdx +0 -229
- package/docs/en/guides/topic-detail/model/test-model.mdx +0 -45
- package/docs/zh/apis/app/runtime/testing/_category_.json +0 -4
- package/docs/zh/apis/app/runtime/testing/act.mdx +0 -35
- package/docs/zh/apis/app/runtime/testing/cleanup.mdx +0 -40
- package/docs/zh/apis/app/runtime/testing/render.mdx +0 -71
- package/docs/zh/apis/app/runtime/testing/renderApp.mdx +0 -32
- package/docs/zh/configure/app/testing/_category_.json +0 -4
- package/docs/zh/configure/app/testing/transformer.mdx +0 -19
- package/docs/zh/configure/app/tools/jest.mdx +0 -40
- package/docs/zh/guides/advanced-features/testing.mdx +0 -47
- package/docs/zh/guides/topic-detail/changesets/_category_.json +0 -4
- package/docs/zh/guides/topic-detail/changesets/add.mdx +0 -126
- package/docs/zh/guides/topic-detail/changesets/changelog.mdx +0 -238
- package/docs/zh/guides/topic-detail/changesets/commit.mdx +0 -269
- package/docs/zh/guides/topic-detail/changesets/config.mdx +0 -147
- package/docs/zh/guides/topic-detail/changesets/github.mdx +0 -175
- package/docs/zh/guides/topic-detail/changesets/introduce.mdx +0 -56
- package/docs/zh/guides/topic-detail/changesets/release-note.mdx +0 -274
- package/docs/zh/guides/topic-detail/changesets/release-pre.mdx +0 -50
- package/docs/zh/guides/topic-detail/changesets/release.mdx +0 -231
- package/docs/zh/guides/topic-detail/model/test-model.mdx +0 -45
- package/docs/zh/guides/topic-detail/monorepo/_category_.json +0 -4
- package/docs/zh/guides/topic-detail/monorepo/create-sub-project.mdx +0 -53
- package/docs/zh/guides/topic-detail/monorepo/intro.mdx +0 -14
- package/docs/zh/guides/topic-detail/monorepo/publish.mdx +0 -69
- package/docs/zh/guides/topic-detail/monorepo/sub-project-interface.mdx +0 -143
@@ -12,7 +12,7 @@ UnstableMiddleware will replace [Middleware](/apis/app/runtime/web-server/middle
|
|
12
12
|
```ts title="server/index.ts"
|
13
13
|
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
14
14
|
|
15
|
-
export const
|
15
|
+
export const unstableMiddleware: UnstableMiddleware[] = [];
|
16
16
|
```
|
17
17
|
|
18
18
|
## Types
|
@@ -74,7 +74,7 @@ const time: UnstableMiddleware = async (c, next) => {
|
|
74
74
|
console.log(`${end - start}`);
|
75
75
|
};
|
76
76
|
|
77
|
-
export const
|
77
|
+
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
78
78
|
```
|
79
79
|
|
80
80
|
### Injecting Server Data for DataLoader Consumption
|
@@ -101,7 +101,7 @@ const setPayload: UnstableMiddleware = async (
|
|
101
101
|
await next();
|
102
102
|
};
|
103
103
|
|
104
|
-
export const
|
104
|
+
export const unstableMiddleware: UnstableMiddleware[] = [setPayload];
|
105
105
|
```
|
106
106
|
|
107
107
|
```ts title="src/routes/page.data.ts"
|
@@ -130,5 +130,31 @@ const auth: UnstableMiddleware = async (c, next) => {
|
|
130
130
|
await next();
|
131
131
|
};
|
132
132
|
|
133
|
-
export const
|
133
|
+
export const unstableMiddleware: UnstableMiddleware[] = [auth];
|
134
|
+
```
|
135
|
+
|
136
|
+
### Modify Response
|
137
|
+
|
138
|
+
```ts
|
139
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
140
|
+
|
141
|
+
const modifier: UnstableMiddleware = async (c, next) => {
|
142
|
+
await next();
|
143
|
+
|
144
|
+
const { response } = c;
|
145
|
+
|
146
|
+
const text = await response.text();
|
147
|
+
|
148
|
+
const newText = text.replace('<html>', `<html lang="${language}">`);
|
149
|
+
|
150
|
+
const newheaders = response.headers;
|
151
|
+
newheaders.set('x-custom-value', 'modern');
|
152
|
+
|
153
|
+
c.response = c.body(newText, {
|
154
|
+
status: response.status,
|
155
|
+
headers: newheaders,
|
156
|
+
});
|
157
|
+
};
|
158
|
+
|
159
|
+
export const unstableMiddleware: UnstableMiddleware[] = [modifier];
|
134
160
|
```
|
@@ -90,7 +90,9 @@ Modern.js provides a set of APIs by default for projects to use:
|
|
90
90
|
import { Middleware } from '@modern-js/runtime/server';
|
91
91
|
|
92
92
|
export const middleware: Middleware = (context, next) => {
|
93
|
-
const {
|
93
|
+
const {
|
94
|
+
source: { req, res },
|
95
|
+
} = context;
|
94
96
|
console.log(req.url);
|
95
97
|
next();
|
96
98
|
};
|
@@ -108,7 +110,7 @@ Projects should follow these best practices when using Middleware:
|
|
108
110
|
|
109
111
|
**In general, in CSR projects, using Hook can basically meet all the needs of simple scenarios. In SSR projects, Middleware can be used for more complex Node extensions.**
|
110
112
|
|
111
|
-
###
|
113
|
+
### Unstable Middleware
|
112
114
|
|
113
115
|
Modern.js will provide new Middleware to add pre-processing middleware to the Web Server, supporting the execution of custom logic before and after handling the page.
|
114
116
|
|
@@ -155,6 +155,8 @@ function loader() {
|
|
155
155
|
|
156
156
|
### Error Handling
|
157
157
|
|
158
|
+
#### Basic Usage
|
159
|
+
|
158
160
|
In the `loader` function, errors can be handled by throwing an `error` or a `response`. When an error is thrown in the `loader` function, Modern.js will stop executing the code in the current `loader` and switch the front-end UI to the defined [`ErrorBoundary`](/guides/basic-features/routes#error-handling) component:
|
159
161
|
|
160
162
|
```tsx
|
@@ -182,6 +184,32 @@ const ErrorBoundary = () => {
|
|
182
184
|
export default ErrorBoundary;
|
183
185
|
```
|
184
186
|
|
187
|
+
#### Practice
|
188
|
+
|
189
|
+
In an SSR project you can control the status code of a page and display the corresponding UI by `throw response` in the data loader, as in the following example, where there is one loader for the entire routing route
|
190
|
+
|
191
|
+
For example, if there is a loader in the entire routing route that throws a response, the status code of the page will be consistent with this `response` and the UI of the page will switch to `ErrorBoundary`.
|
192
|
+
|
193
|
+
```ts
|
194
|
+
// routes/user/profile/page.data.ts
|
195
|
+
export async function loader() {
|
196
|
+
const user = await fetchUser();
|
197
|
+
if(!user){
|
198
|
+
throw new Response('The user was not found', { status: 404 });
|
199
|
+
}
|
200
|
+
return user;
|
201
|
+
}
|
202
|
+
|
203
|
+
// routes/error.tsx
|
204
|
+
import { useRouteError } from '@modern-js/runtime/router';
|
205
|
+
const ErrorBoundary = () => {
|
206
|
+
const error = useRouteError() as { data: string };
|
207
|
+
return <div className="error">{error.data}</div>;
|
208
|
+
};
|
209
|
+
|
210
|
+
export default ErrorBoundary;
|
211
|
+
```
|
212
|
+
|
185
213
|
### Get data from parent component
|
186
214
|
|
187
215
|
In many cases, child components need to access data in the parent component `loader`. You can easily get the data from the parent component using `useRouteLoaderData`:
|
@@ -2,18 +2,20 @@
|
|
2
2
|
sidebar_position: 15
|
3
3
|
---
|
4
4
|
|
5
|
-
# Deploy
|
5
|
+
# Deploy Application
|
6
6
|
|
7
|
-
Currently, Modern.js
|
7
|
+
Currently, Modern.js offers two deployment way:
|
8
|
+
- You can host your application in a container that includes a Node.js environment on your own, which provides flexibility for the deployment of the application.
|
9
|
+
- You can also deploy your application through a platform. Currently, Modern.js supports the [Netlify](https://www.netlify.com/) and [Vercel](https://vercel.com/).
|
8
10
|
|
9
11
|
:::info
|
10
|
-
Currently Modern.js only supports running in
|
12
|
+
Currently, Modern.js only supports running in a Node.js environment. Support for more runtime environments will be provided in the future.
|
11
13
|
:::
|
12
14
|
|
13
15
|
|
14
|
-
##
|
16
|
+
## Build Deployment Products
|
15
17
|
|
16
|
-
Running the `modern deploy` command will automatically
|
18
|
+
Running the `modern deploy` command will automatically produce deployment products. This process includes optimizing Bundler build products and their dependencies, detecting the current deployment platform, and automatically generating deployment products that can run on that platform.
|
17
19
|
|
18
20
|
If you want to generate and test the output locally for a specific deployment platform, you can specify the platform by setting the environment variable: `modern deploy`:
|
19
21
|
|
@@ -33,11 +35,12 @@ When deploying on the deployment platforms officially supported by Modern.js, th
|
|
33
35
|
By default, Modern.js outputs builds that can be run in a Node.js environment when no Modern.js-supported deployment platform is detected.
|
34
36
|
|
35
37
|
Use the following command to build the project:
|
38
|
+
|
36
39
|
```bash
|
37
40
|
npx modern deploy
|
38
41
|
```
|
39
42
|
|
40
|
-
When running the `modern deploy` command, Modern.js will generate runnable products and output the following content:
|
43
|
+
When running the `modern deploy` command, Modern.js will generate runnable products and output the following content in terminal:
|
41
44
|
|
42
45
|
```bash
|
43
46
|
Static directory: `.output/static`
|
@@ -56,35 +59,35 @@ PORT=3000 node .output/index
|
|
56
59
|
|
57
60
|
### Monorepo
|
58
61
|
|
59
|
-
For
|
62
|
+
For Monorepo projects, in addition to building the current project, it is also necessary to build other sub-projects in the repository that the current project depends on.
|
60
63
|
|
61
|
-
|
64
|
+
Assume that the name in the `package.json` of the current project is `app`. Taking pnpm as an example of a monorepo management tool, you can add the following command to the `package.json` of the current project to build products for the current project:
|
62
65
|
|
63
66
|
```json title="app/package.json"
|
64
67
|
{
|
65
68
|
"scripts": {
|
66
|
-
"
|
67
|
-
"deploy
|
69
|
+
"build:packages": "pnpm --filter 'app^...' run build",
|
70
|
+
"deploy": "pnpm run build:packages && modern deploy",
|
68
71
|
}
|
69
72
|
}
|
70
73
|
```
|
71
74
|
|
72
|
-
If you use
|
75
|
+
If you use Rush as your Monorepo management tool, you can add the following commands to your `package.json`:
|
73
76
|
|
74
77
|
```json
|
75
78
|
{
|
76
79
|
"scripts": {
|
77
|
-
"
|
78
|
-
"deploy
|
80
|
+
"build:packages": "rush rebuild --to-except app",
|
81
|
+
"deploy": "rushx build:packages && modern deploy",
|
79
82
|
}
|
80
83
|
}
|
81
84
|
```
|
82
85
|
|
83
|
-
After the build is completed, Modern.js will generate all dependencies in the `.output/node_modules` directory of the project. Similarly, you can run the
|
86
|
+
After the build is completed, Modern.js will generate all dependencies in the `.output/node_modules` directory of the project. Similarly, you can run the Modern.js server using `node .output/index`.
|
84
87
|
|
85
88
|
## Netlify
|
86
89
|
|
87
|
-
Netlify is a popular
|
90
|
+
Netlify is a popular Web development platform designed for building, deploying, and maintaining modern web projects. Deploying on Netlify mainly requires configuring the `netlify.toml` file.
|
88
91
|
|
89
92
|
Depending on the complexity of your project, you can configure it incrementally by this doc.
|
90
93
|
|
@@ -93,31 +96,31 @@ Depending on the complexity of your project, you can configure it incrementally
|
|
93
96
|
Add the `netlify.toml` file to the root directory of the current project:
|
94
97
|
|
95
98
|
```bash
|
96
|
-
|
97
|
-
├── src
|
99
|
+
.
|
100
|
+
├── src
|
98
101
|
├── modern.config.ts
|
99
102
|
├── netlify.toml
|
100
|
-
|
103
|
+
└── package.json
|
101
104
|
```
|
102
105
|
|
103
106
|
Add the following content to `netlify.toml`:
|
107
|
+
|
104
108
|
```toml
|
105
109
|
[build]
|
106
110
|
publish = "dist"
|
107
|
-
command = "
|
111
|
+
command = "modern deploy"
|
108
112
|
```
|
109
113
|
|
110
|
-
|
114
|
+
Now, add a project to the Netlify platform and deploy it!
|
111
115
|
|
112
116
|
### Full Stack Project
|
113
117
|
|
114
|
-
Full-stack projects refer to projects that use
|
115
|
-
add the following configuration:
|
118
|
+
Full-stack projects refer to projects that use Custom Web Server, SSR or BFF. These projects need to be deployed on **Netlify Functions**. Based on the `netlify.toml` file mentioned above, add the following configuration:
|
116
119
|
|
117
120
|
```toml title="netlify.toml"
|
118
121
|
[build]
|
119
122
|
publish = "dist"
|
120
|
-
command = "
|
123
|
+
command = "modern deploy"
|
121
124
|
|
122
125
|
[functions]
|
123
126
|
directory = ".netlify/functions"
|
@@ -133,31 +136,40 @@ Currently, Modern.js does not support deployment on Netlify Edge Functions. We w
|
|
133
136
|
|
134
137
|
### Monorepo
|
135
138
|
|
136
|
-
|
137
|
-
|
139
|
+
:::info
|
140
|
+
The following guide is mainly for full-stack projects, for pure CSR projects, just follow [Pure Frontend Project](#Pure Frontend Project) to deploy.
|
141
|
+
:::
|
142
|
+
|
143
|
+
For Monorepo projects, in addition to building our current project, you also need to build other sub-projects in the repository that the current project depends on.
|
138
144
|
|
139
|
-
|
145
|
+
We take a pnpm Monorepo repository as an example and deploy the Monorepo project on Netlify.
|
146
|
+
|
147
|
+
Assuming the directory structure of the Monorepo repository is as follows:
|
140
148
|
|
141
149
|
```
|
142
|
-
|
143
|
-
├── packages
|
144
|
-
│ ├── app
|
150
|
+
.
|
151
|
+
├── packages
|
152
|
+
│ ├── app
|
145
153
|
│ └── app-dep1
|
146
154
|
├── package.json
|
147
155
|
├── pnpm-lock.yaml
|
148
156
|
└── pnpm-workspace.yaml
|
149
157
|
```
|
150
158
|
|
151
|
-
|
159
|
+
You need to configure Base directory on the netlify platform as `packages/app`:
|
152
160
|
|
153
161
|
<img src="https://sf16-sg.tiktokcdn.com/obj/eden-sg/lmeh7nuptpfnuhd/netlify-monorepo-basedir.png?x-resource-account=public" />
|
154
162
|
|
155
163
|
Add the following script in `packages/app/package.json`, before executing the deployment command of the `app` repository, first execute the build of other repositories in the workspace:
|
156
164
|
|
157
165
|
```json
|
158
|
-
|
159
|
-
"
|
166
|
+
{
|
167
|
+
"scripts": {
|
168
|
+
"build:packages": "pnpm --filter 'app^...' run build",
|
169
|
+
"deploy": "pnpm run build:packages && modern deploy",
|
170
|
+
}
|
160
171
|
}
|
172
|
+
|
161
173
|
```
|
162
174
|
|
163
175
|
Configure the build command in `netlify.toml`:
|
@@ -165,7 +177,7 @@ Configure the build command in `netlify.toml`:
|
|
165
177
|
```toml
|
166
178
|
[build]
|
167
179
|
publish = "dist"
|
168
|
-
command = "npm run deploy
|
180
|
+
command = "npm run deploy"
|
169
181
|
|
170
182
|
[functions]
|
171
183
|
directory = ".netlify/functions"
|
@@ -174,3 +186,101 @@ Configure the build command in `netlify.toml`:
|
|
174
186
|
```
|
175
187
|
|
176
188
|
Just submit your code and deploy it using the Netlify platform.
|
189
|
+
|
190
|
+
## Vercel
|
191
|
+
|
192
|
+
Vercel is a deployment platform for modern web applications that provides a rich set of features to support deploying static websites, server-side rendered applications, and more. To deploy on Vercel, you usually need to configure the `vercel.json` file, which you can configure incrementally depending on the complexity of your project.
|
193
|
+
|
194
|
+
### Pure Front-end Project
|
195
|
+
|
196
|
+
Add the `vercel.json` file to the root directory of the current project:
|
197
|
+
```bash
|
198
|
+
./
|
199
|
+
├── src
|
200
|
+
├── modern.config.ts
|
201
|
+
├── vercel.json
|
202
|
+
└── package.json
|
203
|
+
```
|
204
|
+
|
205
|
+
Add the following content to `vercel.json`:
|
206
|
+
```json title="vercel.json"
|
207
|
+
{
|
208
|
+
"buildCommand": "modern deploy",
|
209
|
+
"outputDirectory": ".vercel/output"
|
210
|
+
}
|
211
|
+
```
|
212
|
+
|
213
|
+
Commit your project to git, select Framework Preset as `Other` on the Vercel platform and deploy.
|
214
|
+
|
215
|
+
<img src="https://sf16-sg.tiktokcdn.com/obj/eden-sg/lmeh7nuptpfnuhd/vercel-framework-preset.png" />
|
216
|
+
|
217
|
+
### Full Stack Project
|
218
|
+
|
219
|
+
Full-stack projects refer to projects that use Custom Web Server, SSR or BFF. These projects need to be deployed on **Vercel Functions**.
|
220
|
+
|
221
|
+
In addition to configuring `vercel.json` in the same way as a [pure front-end project](#pure-front-end-project), there are two points to note for full-stack projects:
|
222
|
+
|
223
|
+
1. Currently, Modern.js does not support deploying BFF projects on the Vercel platform. We will support it in future versions.
|
224
|
+
2. When deploying on Vercel platform, the default node runtime is `20.x`, it is recommended to choose `18.x` when deploying full-stack projects,
|
225
|
+
see [Serverless Function contains invalid runtime error](https://vercel.com/guides/serverless-function-contains-invalid-runtime-error), you can modify `package.json` to specify the version:
|
226
|
+
```json title="package.json"
|
227
|
+
"engines": {
|
228
|
+
"node": "18.x"
|
229
|
+
}
|
230
|
+
```
|
231
|
+
|
232
|
+
|
233
|
+
### Monorepo
|
234
|
+
|
235
|
+
:::info
|
236
|
+
The following guide is mainly for full-stack projects, for pure CSR projects, just follow [Pure Frontend Project](#pure-front-end-project-1) to deploy.
|
237
|
+
:::
|
238
|
+
|
239
|
+
For Monorepo projects, in addition to building our current project, you also need to build other sub-projects in the repository that the current project depends on.
|
240
|
+
|
241
|
+
We take a pnpm Monorepo repository as an example and deploy the Monorepo project on Vercel.
|
242
|
+
|
243
|
+
Assuming the directory structure of the Monorepo repository is as follows:
|
244
|
+
|
245
|
+
```
|
246
|
+
.
|
247
|
+
├── packages
|
248
|
+
│ ├── app
|
249
|
+
│ └── app-dep1
|
250
|
+
├── package.json
|
251
|
+
├── pnpm-lock.yaml
|
252
|
+
└── pnpm-workspace.yaml
|
253
|
+
```
|
254
|
+
|
255
|
+
First, you need to configure the **Root Directory** as `packages/app` on the Vercel platform:
|
256
|
+
|
257
|
+
<img src="https://sf16-sg.tiktokcdn.com/obj/eden-sg/lmeh7nuptpfnuhd/vercel-root-directory.png" />
|
258
|
+
|
259
|
+
Specify Node.js runtime as `18.x`:
|
260
|
+
|
261
|
+
```json title="package.json"
|
262
|
+
"engines": {
|
263
|
+
"node": "18.x"
|
264
|
+
}
|
265
|
+
````
|
266
|
+
|
267
|
+
Add the following script to `packages/app/package.json` to run `build` command of the other repositories in the workspace before run the `deploy` command for the `app` repository:
|
268
|
+
|
269
|
+
```json
|
270
|
+
{
|
271
|
+
"scripts": {
|
272
|
+
"build:packages": "pnpm --filter 'app^...' run build",
|
273
|
+
"deploy": "pnpm run build:packages && modern deploy",
|
274
|
+
}
|
275
|
+
}
|
276
|
+
```
|
277
|
+
|
278
|
+
Add the following content to the `packages/app/vercel.json` file:
|
279
|
+
```json title="vercel.json"
|
280
|
+
{
|
281
|
+
"buildCommand": "npm run deploy",
|
282
|
+
"outputDirectory": ".vercel/output"
|
283
|
+
}
|
284
|
+
```
|
285
|
+
|
286
|
+
Just submit your code and deploy it using the Vercel platform.
|
@@ -455,8 +455,8 @@ export const init = (context: RuntimeContext) => {
|
|
455
455
|
import { useRuntimeContext } from '@modern-js/runtime';
|
456
456
|
|
457
457
|
export default () => {
|
458
|
-
const
|
459
|
-
const { message } = context.
|
458
|
+
const context = useRuntimeContext();
|
459
|
+
const { message } = context.initialData;
|
460
460
|
|
461
461
|
return <div>{message}</div>;
|
462
462
|
};
|
@@ -83,12 +83,6 @@ Modern.js supports the use of [styled-components](https://styled-components.com/
|
|
83
83
|
|
84
84
|
If you need to use other CSS-in-JS solutions, you can integrate them into your project on your own.
|
85
85
|
|
86
|
-
## Testing Framework
|
87
|
-
|
88
|
-
Modern.js supports the use of [Jest](https://jestjs.io/) for unit testing or integration testing. This feature is optional. Please refer to ["Using Jest"](/en/guides/advanced-features/testing) to enable it.
|
89
|
-
|
90
|
-
If you need to use [Vitest](https://vitest.dev/) or other testing frameworks, you can integrate them into your project on your own.
|
91
|
-
|
92
86
|
## UI Components
|
93
87
|
|
94
88
|
Modern.js can be used with any React UI component library from the community, such as [MUI](https://mui.com/), [Ant Design](https://ant.design/), [Arco Design](https://github.com/arco-design/arco-design), [Semi Design](https://semi.design/), [Radix UI](https://www.radix-ui.com/), and more.
|
@@ -105,7 +105,7 @@ interface IAppContext {
|
|
105
105
|
/** Information for server routes */
|
106
106
|
serverRoutes: ServerRoute[];
|
107
107
|
/** Tools type of the current project */
|
108
|
-
toolsType?: 'app-tools' | 'module-tools'
|
108
|
+
toolsType?: 'app-tools' | 'module-tools';
|
109
109
|
/** Type of the bundler being used */
|
110
110
|
bundlerType?: 'webpack' | 'rspack' | 'esbuild';
|
111
111
|
}
|
@@ -20,7 +20,6 @@ Options:
|
|
20
20
|
-d,--debug using debug mode to log something (default: false)
|
21
21
|
--mwa create mwa application using default config (default: false)
|
22
22
|
--module create module application using default config (default: false)
|
23
|
-
--monorepo create monorepo application using default config (default: false)
|
24
23
|
--generator <generator> run custom generator
|
25
24
|
-p, --plugin <plugin> use generator plugin to create new solution or customize Modern.js solution (default: [])
|
26
25
|
--dist-tag <distTag> use specified tag version for it\'s generator (default: "")
|
@@ -89,10 +88,6 @@ Quickly create a Web App project.
|
|
89
88
|
|
90
89
|
Quickly create a Npm Module project.
|
91
90
|
|
92
|
-
## --monorepo
|
93
|
-
|
94
|
-
Quickly create a Monorepo project.
|
95
|
-
|
96
91
|
## -p, --plugin \<plugin>
|
97
92
|
|
98
93
|
Specify a generator plugin.
|
@@ -4,7 +4,7 @@ sidebar_position: 1
|
|
4
4
|
|
5
5
|
# Usage
|
6
6
|
|
7
|
-
Modern.js provides `@modern-js/create` tool for creating project templates provided by Modern.js, including [Web App](https://modernjs.dev/), [Npm Module](https://modernjs.dev/module-tools)
|
7
|
+
Modern.js provides `@modern-js/create` tool for creating project templates provided by Modern.js, including [Web App](https://modernjs.dev/), [Npm Module](https://modernjs.dev/module-tools).
|
8
8
|
|
9
9
|
The following will introduce how to use `@modern-js/create`.
|
10
10
|
|
@@ -47,12 +47,3 @@ npx @modern-js/create@latest npm-module
|
|
47
47
|
? Please select the programming language: TS
|
48
48
|
? Please select the package manager: pnpm
|
49
49
|
```
|
50
|
-
|
51
|
-
### Create Monorepo Project
|
52
|
-
|
53
|
-
```bash
|
54
|
-
npx @modern-js/create@latest monorepo
|
55
|
-
? Please select the type of project you want to create: Monorepo
|
56
|
-
? Please select the package manager: pnpm
|
57
|
-
```
|
58
|
-
|
@@ -117,32 +117,3 @@ Options:
|
|
117
117
|
- Enable Storybook -- storybook
|
118
118
|
|
119
119
|
- Enable Runtime API -- runtime_api
|
120
|
-
|
121
|
-
## Monorepo
|
122
|
-
|
123
|
-
### sub_solution
|
124
|
-
|
125
|
-
Question: Please select the type of project you want to create.
|
126
|
-
|
127
|
-
Options:
|
128
|
-
|
129
|
-
- Web App -- mwa
|
130
|
-
- Npm Module -- module
|
131
|
-
|
132
|
-
### packageName
|
133
|
-
|
134
|
-
Question: Please fill in the project name
|
135
|
-
|
136
|
-
:::info
|
137
|
-
The value of the `name` field in the `package.json` file of the sub-project, which is a string type.
|
138
|
-
|
139
|
-
:::
|
140
|
-
|
141
|
-
### packagePath
|
142
|
-
|
143
|
-
Question: Please fill in the sub-project directory name
|
144
|
-
|
145
|
-
:::info
|
146
|
-
The name of the subdirectory in the `apps` or `packages` directory on which the sub-project is based, which is a string type.
|
147
|
-
|
148
|
-
:::
|
@@ -73,23 +73,3 @@ npm run new
|
|
73
73
|
```
|
74
74
|
|
75
75
|
After running, Storybook plugin dependencies will be installed in the project, and the `storybook` command will be added. A `stories` directory will be created for Storybook module development, along with prompt information for registering Storybook plugins.
|
76
|
-
|
77
|
-
## Monorepo
|
78
|
-
|
79
|
-
Monorepo projects use the `new` command provided by `@modern-js/monorepo-tools`.
|
80
|
-
|
81
|
-
The `new` command provides the ability to create sub-project.
|
82
|
-
|
83
|
-
For example:
|
84
|
-
|
85
|
-
Create Web App Sub-project:
|
86
|
-
|
87
|
-
```bash
|
88
|
-
? Please select the type of project you want to create: Web App
|
89
|
-
? Please fill in the sub-project name: web_app
|
90
|
-
? Please fill in the sub-project directory name: web_app
|
91
|
-
? Please select the programming language: TS
|
92
|
-
? Please select the bundler: webpack
|
93
|
-
```
|
94
|
-
|
95
|
-
After running, a sub-project named `web_app` will be created in the `apps` directory of the project. In the sub-project directory, you can still run the `new` command to create project elements and enable features.
|
@@ -11,7 +11,7 @@ title: Unstable Middleware
|
|
11
11
|
```ts title="server/index.ts"
|
12
12
|
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
13
13
|
|
14
|
-
export const
|
14
|
+
export const unstableMiddleware: UnstableMiddleware[] = [];
|
15
15
|
```
|
16
16
|
|
17
17
|
## 类型
|
@@ -73,7 +73,7 @@ const time: UnstableMiddleware = async (c, next) => {
|
|
73
73
|
console.log(`${end - start}`);
|
74
74
|
};
|
75
75
|
|
76
|
-
export const
|
76
|
+
export const unstableMiddleware: UnstableMiddleware[] = [time];
|
77
77
|
```
|
78
78
|
|
79
79
|
### 注入服务端数据,供页面 dataLoader 消费
|
@@ -100,7 +100,7 @@ const setPayload: UnstableMiddleware = async (
|
|
100
100
|
await next();
|
101
101
|
};
|
102
102
|
|
103
|
-
export const
|
103
|
+
export const unstableMiddleware: UnstableMiddleware[] = [setPayload];
|
104
104
|
```
|
105
105
|
|
106
106
|
```ts title="src/routes/page.data.ts"
|
@@ -129,5 +129,31 @@ const auth: UnstableMiddleware = async (c, next) => {
|
|
129
129
|
await next();
|
130
130
|
};
|
131
131
|
|
132
|
-
export const
|
132
|
+
export const unstableMiddleware: UnstableMiddleware[] = [auth];
|
133
|
+
```
|
134
|
+
|
135
|
+
### 修改响应体
|
136
|
+
|
137
|
+
```ts
|
138
|
+
import { UnstableMiddleware } from '@modern-js/runtime/server';
|
139
|
+
|
140
|
+
const modifier: UnstableMiddleware = async (c, next) => {
|
141
|
+
await next();
|
142
|
+
|
143
|
+
const { response } = c;
|
144
|
+
|
145
|
+
const text = await response.text();
|
146
|
+
|
147
|
+
const newText = text.replace('<html>', `<html lang="${language}">`);
|
148
|
+
|
149
|
+
const newheaders = response.headers;
|
150
|
+
newheaders.set('x-custom-value', 'modern');
|
151
|
+
|
152
|
+
c.response = c.body(newText, {
|
153
|
+
status: response.status,
|
154
|
+
headers: newheaders,
|
155
|
+
});
|
156
|
+
};
|
157
|
+
|
158
|
+
export const unstableMiddleware: UnstableMiddleware[] = [modifier];
|
133
159
|
```
|
@@ -108,7 +108,7 @@ export const middleware: Middleware = (context, next) => {
|
|
108
108
|
|
109
109
|
**总的来说,CSR 项目中,使用 Hook 基本能满足简单场景的所有需求。SSR 项目中,可以使用 Middleware 做更复杂的 Node 扩展。**
|
110
110
|
|
111
|
-
###
|
111
|
+
### Unstable Middleware
|
112
112
|
|
113
113
|
Modern.js 将提供新 Middleware 为 Web Server 添加前置中间件,支持在处理页面的前后执行自定义逻辑。
|
114
114
|
|
@@ -155,6 +155,8 @@ export async function loader() {
|
|
155
155
|
|
156
156
|
### 错误处理
|
157
157
|
|
158
|
+
#### 基本用法
|
159
|
+
|
158
160
|
在 `loader` 函数中,可以通过 `throw error` 或者 `throw response` 的方式处理错误,当 `loader` 函数中有错误被抛出时,Modern.js 会停止执行当前 `loader` 中的代码,并将前端 UI 切换到定义的 [`ErrorBoundary`](/guides/basic-features/routes#错误处理) 组件:
|
159
161
|
|
160
162
|
```tsx
|
@@ -182,6 +184,31 @@ const ErrorBoundary = () => {
|
|
182
184
|
export default ErrorBoundary;
|
183
185
|
```
|
184
186
|
|
187
|
+
#### 实践
|
188
|
+
|
189
|
+
在 SSR 项目中你可以通过在 data loader 中 `throw response` 的方式,控制页面的状态码,展示对应的 UI,如以下示例,整条路由路线中有一个 loader
|
190
|
+
throw response,页面的状态码将与这个 `response` 保持一致,页面的 UI 也会切换为 `ErrorBoundary`:
|
191
|
+
|
192
|
+
```ts
|
193
|
+
// routes/user/profile/page.data.ts
|
194
|
+
export async function loader() {
|
195
|
+
const user = await fetchUser();
|
196
|
+
if(!user){
|
197
|
+
throw new Response('The user was not found', { status: 404 });
|
198
|
+
}
|
199
|
+
return user;
|
200
|
+
}
|
201
|
+
|
202
|
+
// routes/error.tsx
|
203
|
+
import { useRouteError } from '@modern-js/runtime/router';
|
204
|
+
const ErrorBoundary = () => {
|
205
|
+
const error = useRouteError() as { data: string };
|
206
|
+
return <div className="error">{error.data}</div>;
|
207
|
+
};
|
208
|
+
|
209
|
+
export default ErrorBoundary;
|
210
|
+
```
|
211
|
+
|
185
212
|
### 获取上层组件的数据
|
186
213
|
|
187
214
|
很多场景下,子组件需要获取到祖先组件 `loader` 中的数据,你可以通过 `useRouteLoaderData` 方便地获取到祖先组件的数据:
|
@@ -385,8 +412,6 @@ export const loader = () => {}
|
|
385
412
|
```
|
386
413
|
|
387
414
|
|
388
|
-
|
389
|
-
|
390
415
|
### 错误用法
|
391
416
|
|
392
417
|
1. `loader` 中只能返回可序列化的数据,在 SSR 环境下,`loader` 函数的返回值会被序列化为 JSON 字符串,然后在客户端被反序列化为对象。因此,`loader` 函数中不能返回不可序列化的数据(如函数)。
|