@modern-js/main-doc 2.54.5 → 2.55.0
Sign up to get free protection for your applications and to get access to all the features.
- package/docs/en/apis/app/hooks/src/entry.mdx +42 -0
- package/docs/en/apis/app/hooks/src/entry.server.mdx +52 -0
- package/docs/en/apis/app/hooks/src/index_.mdx +4 -0
- package/docs/en/apis/app/runtime/core/bootstrap.mdx +4 -0
- package/docs/en/apis/app/runtime/core/create-app.mdx +5 -1
- package/docs/en/apis/app/runtime/core/create-root.mdx +22 -0
- package/docs/en/apis/app/runtime/core/render.mdx +42 -0
- package/docs/en/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
- package/docs/en/apis/app/runtime/ssr/renderString.mdx +62 -0
- package/docs/en/apis/app/runtime/ssr/requestHandler.mdx +47 -0
- package/docs/en/apis/app/runtime/web-server/middleware.mdx +3 -0
- package/docs/en/components/debug-app.mdx +3 -3
- package/docs/en/configure/app/output/ssg.mdx +4 -0
- package/docs/en/configure/app/source/enable-async-entry.mdx +4 -4
- package/docs/en/configure/app/source/enable-custom-entry.mdx +41 -0
- package/docs/en/guides/advanced-features/ssr/cache.mdx +7 -2
- package/docs/en/guides/concept/entries.mdx +50 -36
- package/docs/en/guides/get-started/quick-start.mdx +24 -8
- package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +30 -177
- package/docs/zh/apis/app/hooks/src/entry.mdx +42 -0
- package/docs/zh/apis/app/hooks/src/entry.server.mdx +52 -0
- package/docs/zh/apis/app/hooks/src/index_.mdx +4 -0
- package/docs/zh/apis/app/runtime/core/bootstrap.mdx +4 -0
- package/docs/zh/apis/app/runtime/core/create-app.mdx +5 -1
- package/docs/zh/apis/app/runtime/core/create-root.mdx +22 -0
- package/docs/zh/apis/app/runtime/core/render.mdx +43 -0
- package/docs/zh/apis/app/runtime/ssr/renderStreaming.mdx +69 -0
- package/docs/zh/apis/app/runtime/ssr/renderString.mdx +62 -0
- package/docs/zh/apis/app/runtime/ssr/requestHandler.mdx +47 -0
- package/docs/zh/apis/app/runtime/web-server/middleware.mdx +4 -0
- package/docs/zh/components/debug-app.mdx +3 -2
- package/docs/zh/configure/app/dev/client.mdx +1 -1
- package/docs/zh/configure/app/output/ssg.mdx +4 -0
- package/docs/zh/configure/app/source/enable-async-entry.mdx +4 -4
- package/docs/zh/configure/app/source/enable-custom-entry.mdx +41 -0
- package/docs/zh/guides/advanced-features/ssr/cache.mdx +6 -2
- package/docs/zh/guides/concept/entries.mdx +54 -41
- package/docs/zh/guides/get-started/quick-start.mdx +26 -10
- package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +29 -174
- package/package.json +5 -5
- package/docs/en/apis/app/hooks/src/pages.mdx +0 -186
- package/docs/zh/apis/app/hooks/src/pages.mdx +0 -187
- package/docs/zh/apis/monorepo/commands/deploy.mdx +0 -38
@@ -0,0 +1,47 @@
|
|
1
|
+
---
|
2
|
+
title: createRequestHandler
|
3
|
+
---
|
4
|
+
|
5
|
+
# createRequestHandler
|
6
|
+
|
7
|
+
用于自定义 Server-Side Rendering 入口返回 requestHandler
|
8
|
+
|
9
|
+
## 使用
|
10
|
+
|
11
|
+
```tsx title="src/entry.server.tsx"
|
12
|
+
import {
|
13
|
+
renderString,
|
14
|
+
createRequestHandler,
|
15
|
+
} from '@modern-js/runtime/ssr/server';
|
16
|
+
|
17
|
+
const handleRequest = async (request, ServerRoot, options) => {
|
18
|
+
const body = await renderString(request, <ServerRoot />, options);
|
19
|
+
|
20
|
+
return new Response(body, {
|
21
|
+
headers: {
|
22
|
+
'content-type': 'text/html; charset=utf-8',
|
23
|
+
},
|
24
|
+
});
|
25
|
+
};
|
26
|
+
|
27
|
+
export default createRequestHandler(handleRequest);
|
28
|
+
```
|
29
|
+
|
30
|
+
## 函数签名
|
31
|
+
|
32
|
+
```ts
|
33
|
+
export type HandleRequest = (
|
34
|
+
request: Request,
|
35
|
+
ServerRoot: React.ComponentType
|
36
|
+
options: HandleRequestOptions,
|
37
|
+
) => Promise<Response>;
|
38
|
+
|
39
|
+
export type RequestHandler = (
|
40
|
+
request: Request,
|
41
|
+
options: RequestHandlerOptions,
|
42
|
+
) => Promise<Response>;
|
43
|
+
|
44
|
+
export type CreateRequestHandler = (
|
45
|
+
handleRequest: HandleRequest,
|
46
|
+
) => Promise<RequestHandler>;
|
47
|
+
```
|
@@ -7,13 +7,17 @@ title: Middleware
|
|
7
7
|
用于拓展 Modern.js 内置的 Web Server,与 [Hook](/apis/app/runtime/web-server/hook) 不同的是,Middleware 可以直接操作 Node 原生的请求、响应对象,并且可以使用框架拓展。
|
8
8
|
|
9
9
|
:::note
|
10
|
+
|
10
11
|
在下一个大版本,Modern.js 将会使用新 Middleware 来替代该写法。
|
11
12
|
|
12
13
|
推荐使用 [UnstableMiddleware](/apis/app/runtime/web-server/unstable_middleware) 处理页面请求。
|
14
|
+
|
13
15
|
:::
|
14
16
|
|
15
17
|
:::note
|
18
|
+
|
16
19
|
更多内容可以查看[自定义 Web Server](/guides/advanced-features/web-server)。
|
20
|
+
|
17
21
|
:::
|
18
22
|
|
19
23
|
## 使用姿势
|
@@ -35,15 +35,15 @@ export default defineConfig({
|
|
35
35
|
node_modules
|
36
36
|
└─ .modern-js
|
37
37
|
└─ main
|
38
|
-
├─ bootstrap.jsx #
|
39
|
-
├─ index.js #
|
38
|
+
├─ bootstrap.jsx # 异步入口文件(asynchronous boundary)
|
39
|
+
├─ index.js # 真正的入口代码
|
40
40
|
└─ index.html
|
41
41
|
```
|
42
42
|
|
43
|
-
其中 `
|
43
|
+
其中 `bootstrap.js` 的内容如下:
|
44
44
|
|
45
45
|
```js
|
46
|
-
import('./
|
46
|
+
import('./index.jsx');
|
47
47
|
```
|
48
48
|
|
49
49
|
此时,就可以在当前页面中消费任意的远程模块了。
|
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
sidebar_label: enableCustomEntry
|
3
|
+
---
|
4
|
+
|
5
|
+
# source.enableCustomEntry
|
6
|
+
|
7
|
+
- **类型:** `boolean`
|
8
|
+
- **默认值:** `false`
|
9
|
+
|
10
|
+
该选项用于使用 Modern.js 自定义入口场景。
|
11
|
+
|
12
|
+
开启此选项后,Modern.js 将使用 `src/entry.[jt]sx` 文件作为项目的入口, 具体使用姿势可参考[页面入口](/guides/concept/entries.html)。
|
13
|
+
|
14
|
+
## 示例
|
15
|
+
|
16
|
+
首先,在配置文件中开启此选项:
|
17
|
+
|
18
|
+
```ts title="modern.config.ts"
|
19
|
+
export default defineConfig({
|
20
|
+
source: {
|
21
|
+
enableCustomEntry: true,
|
22
|
+
},
|
23
|
+
});
|
24
|
+
```
|
25
|
+
|
26
|
+
创建 `src/entry.tsx` 文件:
|
27
|
+
|
28
|
+
```tsx
|
29
|
+
import { createRoot } from '@modern-js/runtime/react';
|
30
|
+
import { render } from '@modern-js/runtime/browser';
|
31
|
+
|
32
|
+
const ModernRoot = createRoot();
|
33
|
+
|
34
|
+
async function beforeRender() {
|
35
|
+
// todo
|
36
|
+
}
|
37
|
+
|
38
|
+
beforeRender().then(() => {
|
39
|
+
render(<ModernRoot />);
|
40
|
+
});
|
41
|
+
```
|
@@ -55,10 +55,10 @@ export interface CacheControl {
|
|
55
55
|
```ts
|
56
56
|
export type CacheOptionProvider = (
|
57
57
|
req: IncomingMessage,
|
58
|
-
) => Promise<CacheControl> | CacheControl;
|
58
|
+
) => Promise<CacheControl | false> | CacheControl | false;
|
59
59
|
```
|
60
60
|
|
61
|
-
有时开发者需要通过 req 来自定义缓存 key
|
61
|
+
有时开发者需要通过 req 来自定义缓存 key,或者特定 url 时缓存不生效,可以配置为函数的形式进行处理, 例如以下代码:
|
62
62
|
|
63
63
|
```ts title="server/cache.ts"
|
64
64
|
|
@@ -69,6 +69,10 @@ const provider: CacheOptionProvider = (req) => {
|
|
69
69
|
|
70
70
|
const key = computedKey(url, headers, ...);
|
71
71
|
|
72
|
+
if(url.includes('no-cache=1')) {
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
|
72
76
|
return {
|
73
77
|
maxAge: 500, // ms
|
74
78
|
staleWhileRevalidate: 1000, // ms
|
@@ -81,12 +81,14 @@ import EntryMode from '@site-docs/components/entry-mode.mdx';
|
|
81
81
|
|
82
82
|
:::
|
83
83
|
|
84
|
-
并非 `src/` 下所有的一级目录都会成为项目入口,
|
84
|
+
并非 `src/` 下所有的一级目录都会成为项目入口, 入口所在目录必须满足以下五个条件之一:
|
85
85
|
|
86
86
|
1. 具有 `routes/` 目录。
|
87
87
|
2. 具有 `App.[jt]sx?` 文件。
|
88
|
-
3. 具有 `
|
89
|
-
4. 具有 `
|
88
|
+
3. 具有 `entry.[jt]sx?` 文件 (需要开启 `source.enableCustomEntry` 使用)。
|
89
|
+
4. 具有 `index.[jt]sx?` 文件(即将废弃)。
|
90
|
+
5. 具有 `pages/` 目录(兼容 Modern.js 1.0)(即将废弃)。
|
91
|
+
|
90
92
|
|
91
93
|
当 `src/` 目录满足入口特征时,Modern.js 会认为当前项目为单入口应用。
|
92
94
|
|
@@ -138,8 +140,47 @@ export default () => {
|
|
138
140
|
|
139
141
|
详细内容可以参考[路由方案](/guides/basic-features/routes#自控式路由)。
|
140
142
|
|
143
|
+
#### 自定义入口
|
144
|
+
|
145
|
+
如果入口中存在 `entry.[jt]sx` 文件,需要开发者在 `entry.[jt]sx` 文件中调用 `createRoot` 和 `render` 函数,完成项目入口逻辑。
|
146
|
+
|
147
|
+
:::info
|
148
|
+
使用该文件需要开启 [source.enableCustomEntry](/configure/app/source/enable-custom-entry)。
|
149
|
+
:::
|
150
|
+
|
151
|
+
```tsx
|
152
|
+
import { createRoot } from '@modern-js/runtime/react';
|
153
|
+
import { render } from '@modern-js/runtime/browser';
|
154
|
+
|
155
|
+
const ModernRoot = createRoot();
|
156
|
+
|
157
|
+
render(<ModernRoot />);
|
158
|
+
|
159
|
+
```
|
160
|
+
|
161
|
+
比如在 render 执行前,需要做一些其他操作,可以这样实现:
|
162
|
+
|
163
|
+
```tsx
|
164
|
+
import { createRoot } from '@modern-js/runtime/react';
|
165
|
+
import { render } from '@modern-js/runtime/browser';
|
166
|
+
|
167
|
+
const ModernRoot = createRoot();
|
168
|
+
|
169
|
+
async function beforeRender() {
|
170
|
+
// todo
|
171
|
+
}
|
172
|
+
|
173
|
+
beforeRender().then(() => {
|
174
|
+
render(<ModernRoot />);
|
175
|
+
});
|
176
|
+
```
|
177
|
+
|
141
178
|
#### 自定义 Bootstrap
|
142
179
|
|
180
|
+
:::warning
|
181
|
+
即将废弃,推荐使用自定义入口
|
182
|
+
:::
|
183
|
+
|
143
184
|
如果入口中存在 `index.[jt]sx` 文件,并且当文件默认导出函数时,Modern.js 会将默认的 `bootstrap` 函数作为入参传入,并用导出的函数替代默认的 `bootstrap`,这样开发者可以自定义将组件挂载到 DOM 节点上,或在挂载前添加自定义行为。例如:
|
144
185
|
|
145
186
|
```tsx
|
@@ -151,47 +192,19 @@ export default (App: React.ComponentType, bootstrap: () => void) => {
|
|
151
192
|
};
|
152
193
|
```
|
153
194
|
|
154
|
-
此时,Modern.js 生成的文件内容如下:
|
155
|
-
|
156
|
-
```js
|
157
|
-
import React from 'react';
|
158
|
-
import ReactDOM from 'react-dom/client';
|
159
|
-
import customBootstrap from '@_modern_js_src/index.tsx';
|
160
|
-
import App from '@_modern_js_src/App';
|
161
|
-
import { router, state } from '@modern-js/runtime/plugins';
|
162
|
-
|
163
|
-
const IS_BROWSER = typeof window !== 'undefined' && window.name !== 'nodejs';
|
164
|
-
const MOUNT_ID = 'root';
|
165
|
-
|
166
|
-
let AppWrapper = null;
|
167
|
-
let root = null;
|
168
|
-
|
169
|
-
function render() {
|
170
|
-
AppWrapper = createApp({
|
171
|
-
// runtime 的插件参数...
|
172
|
-
})(App);
|
173
|
-
if (IS_BROWSER) {
|
174
|
-
customBootstrap(AppWrapper, () =>
|
175
|
-
bootstrap(AppWrapper, MOUNT_ID, root, ReactDOM),
|
176
|
-
);
|
177
|
-
}
|
178
|
-
return AppWrapper;
|
179
|
-
}
|
180
|
-
|
181
|
-
AppWrapper = render();
|
182
|
-
|
183
|
-
export default AppWrapper;
|
184
|
-
```
|
185
|
-
|
186
195
|
### 构建模式入口
|
187
196
|
|
188
|
-
构建模式指的是不使用 Modern.js
|
197
|
+
构建模式指的是不使用 Modern.js 提供的 Runtime 能力,而是完全由开发者自行定义页面的入口。
|
198
|
+
|
199
|
+
当入口目录中存在 `index.[jt]sx`(即将废弃) 并且没有通过 `export default` 导出函数或者入口目录存在 `entry.[jt]sx` 并且未安装 `@modern-js/runtime` 依赖时,对应文件就会被识别为 webpack 或 Rspack 的 entry 模块。
|
189
200
|
|
190
|
-
|
201
|
+
:::info
|
202
|
+
使用 `entry.[jt]sx` 文件需要开启 [source.enableCustomEntry](/configure/app/source/enable-custom-entry)。
|
203
|
+
:::
|
191
204
|
|
192
205
|
此时 Modern.js 不会自动生成入口代码,因此需要你自行将组件挂载到 DOM 节点上,例如:
|
193
206
|
|
194
|
-
```js title=src/
|
207
|
+
```js title=src/entry.tsx
|
195
208
|
import React from 'react';
|
196
209
|
import ReactDOM from 'react-dom';
|
197
210
|
import App from './App';
|
@@ -199,9 +212,9 @@ import App from './App';
|
|
199
212
|
ReactDOM.render(<App />, document.getElementById('root'));
|
200
213
|
```
|
201
214
|
|
202
|
-
这种方式等价于开启 Modern.js 的 [source.entries.disableMount](/configure/app/source/entries) 选项。当你使用这种方式时,**将无法使用 Modern.js 框架的运行时能力**,比如 modern.config.js 文件中的 `runtime` 配置将不会再生效。
|
215
|
+
这种方式等价于开启 Modern.js 的 [source.entries.disableMount](/configure/app/source/entries) 选项。当你使用这种方式时,**将无法使用 Modern.js 框架的运行时能力**,比如 `modern.config.js` 文件中的 `runtime` 配置将不会再生效。
|
203
216
|
|
204
|
-
##
|
217
|
+
## 自定义入口配置
|
205
218
|
|
206
219
|
在某些情况下,你可能需要自定义入口配置,而不是使用 Modern.js 提供的入口约定。
|
207
220
|
|
@@ -234,4 +247,4 @@ export default defineConfig({
|
|
234
247
|
});
|
235
248
|
```
|
236
249
|
|
237
|
-
注意,当你开启 `disableMount` 时,**将无法使用 Modern.js 框架的运行时能力**,比如 modern.config.ts 文件中的 `runtime` 配置将不会再生效。
|
250
|
+
注意,当你开启 `disableMount` 时,**将无法使用 Modern.js 框架的运行时能力**,比如 `modern.config.ts` 文件中的 `runtime` 配置将不会再生效。
|
@@ -56,7 +56,11 @@ export default defineConfig({
|
|
56
56
|
server: {
|
57
57
|
ssr: true,
|
58
58
|
},
|
59
|
-
plugins: [
|
59
|
+
plugins: [
|
60
|
+
appTools({
|
61
|
+
bundler: 'webpack', // Set to 'experimental-rspack' to enable rspack ⚡️🦀
|
62
|
+
}),
|
63
|
+
],
|
60
64
|
});
|
61
65
|
```
|
62
66
|
|
@@ -91,15 +95,27 @@ $ pnpm run build
|
|
91
95
|
|
92
96
|
> modern build
|
93
97
|
|
94
|
-
|
95
|
-
|
98
|
+
Modern.js Framework v2.55.0
|
99
|
+
|
100
|
+
info Starting production build...
|
101
|
+
info Type checker is enabled. It may take some time.
|
102
|
+
ready Client compiled in 6.19 s
|
96
103
|
info Production file sizes:
|
97
104
|
|
98
|
-
File
|
99
|
-
dist/
|
100
|
-
dist/
|
101
|
-
dist/static/js/main.
|
102
|
-
dist/
|
105
|
+
File Size Gzipped
|
106
|
+
dist/routes-manifest.json 0.74 kB 0.28 kB
|
107
|
+
dist/static/css/async/page.d7915515.css 1.4 kB 0.69 kB
|
108
|
+
dist/static/js/main.5ae469e7.js 3.0 kB 1.3 kB
|
109
|
+
dist/html/main/index.html 6.0 kB 2.6 kB
|
110
|
+
dist/static/js/async/page.ddc8a4c1.js 19.2 kB 6.7 kB
|
111
|
+
dist/static/js/34.171fffdb.js 21.3 kB 7.1 kB
|
112
|
+
dist/static/js/lib-router.8995a55e.js 55.3 kB 18.1 kB
|
113
|
+
dist/static/js/lib-lodash.53ec3384.js 71.4 kB 24.8 kB
|
114
|
+
dist/static/js/lib-react.b5856db9.js 140.0 kB 45.2 kB
|
115
|
+
dist/static/js/lib-polyfill.86c452b3.js 213.3 kB 69.9 kB
|
116
|
+
|
117
|
+
Total size: 531.8 kB
|
118
|
+
Gzipped size: 176.7 kB
|
103
119
|
```
|
104
120
|
|
105
121
|
构建产物默认生成到 `dist/`,目录结构如下:
|
@@ -125,9 +141,9 @@ dist
|
|
125
141
|
```bash
|
126
142
|
$ pnpm run serve
|
127
143
|
|
128
|
-
|
144
|
+
Modern.js Framework v2.55.0
|
129
145
|
|
130
|
-
Starting production server...
|
146
|
+
info Starting production server...
|
131
147
|
|
132
148
|
> Local: http://localhost:8080/
|
133
149
|
> Network: http://192.168.0.1:8080/
|
@@ -421,12 +421,13 @@ export const myPlugin = (): CliPlugin<AppTools> => ({
|
|
421
421
|
});
|
422
422
|
```
|
423
423
|
|
424
|
-
|
424
|
+
{/*
|
425
|
+
### `checkEntryPoint`
|
425
426
|
|
426
|
-
-
|
427
|
+
- 功能:增加入口类型
|
427
428
|
- 执行阶段:生成入口文件之前,[`prepare`](#prepare) 阶段触发
|
428
429
|
- Hook 模型:`AsyncWaterfall`
|
429
|
-
- 类型:`AsyncWaterfall<{
|
430
|
+
- 类型:`AsyncWaterfall<{ path: string; entry: false | string; }>`
|
430
431
|
- 使用示例:
|
431
432
|
|
432
433
|
```ts
|
@@ -435,57 +436,20 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
|
435
436
|
export const myPlugin = (): CliPlugin<AppTools> => ({
|
436
437
|
setup(api) {
|
437
438
|
return {
|
438
|
-
|
439
|
-
|
440
|
-
imports.push({
|
441
|
-
value: 'react',
|
442
|
-
specifiers: [
|
443
|
-
{
|
444
|
-
imported: 'unmountComponentAtNode',
|
445
|
-
},
|
446
|
-
],
|
447
|
-
});
|
448
|
-
|
449
|
-
return { entrypoint, imports };
|
450
|
-
},
|
451
|
-
};
|
452
|
-
},
|
453
|
-
});
|
454
|
-
```
|
455
|
-
|
456
|
-
### `modifyEntryExport`
|
457
|
-
|
458
|
-
- 功能:用于修改生成入口文件中的 `export` 语句
|
459
|
-
- 执行阶段:生成入口文件之前,[`prepare`](#prepare) 阶段触发
|
460
|
-
- Hook 模型:`AsyncWaterfall`
|
461
|
-
- 类型:`AsyncWaterfall<{ entrypoint: Entrypoint; exportStatement: string; }>`
|
462
|
-
- 使用示例:
|
463
|
-
|
464
|
-
```ts
|
465
|
-
import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
466
|
-
|
467
|
-
export const myPlugin = (): CliPlugin<AppTools> => ({
|
468
|
-
setup(api) {
|
469
|
-
return {
|
470
|
-
modifyEntryExport({ entrypoint, exportStatement }) {
|
471
|
-
return {
|
472
|
-
entrypoint,
|
473
|
-
exportStatement: [`export const foo = 'test'`, exportStatement].join(
|
474
|
-
'\n',
|
475
|
-
),
|
476
|
-
};
|
439
|
+
checkEntryPoint({ path, entry }) {
|
440
|
+
return { path, entry: entry || isNewEntry(path) };
|
477
441
|
},
|
478
442
|
};
|
479
443
|
},
|
480
444
|
});
|
481
445
|
```
|
482
446
|
|
483
|
-
### `
|
447
|
+
### `modifyEntrypoints`
|
484
448
|
|
485
|
-
-
|
449
|
+
- 功能:用于修改入口信息,针对于插件新增的入口,可以通过该钩子修改对应的 entrypoint 信息
|
486
450
|
- 执行阶段:生成入口文件之前,[`prepare`](#prepare) 阶段触发
|
487
451
|
- Hook 模型:`AsyncWaterfall`
|
488
|
-
- 类型:`AsyncWaterfall<{
|
452
|
+
- 类型:`AsyncWaterfall<{ entrypoints: Entrypoint[]; }>`
|
489
453
|
- 使用示例:
|
490
454
|
|
491
455
|
```ts
|
@@ -494,33 +458,23 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
|
494
458
|
export const myPlugin = (): CliPlugin<AppTools> => ({
|
495
459
|
setup(api) {
|
496
460
|
return {
|
497
|
-
|
498
|
-
const
|
499
|
-
|
500
|
-
|
501
|
-
};
|
502
|
-
|
503
|
-
return {
|
504
|
-
plugins: [
|
505
|
-
...plugins,
|
506
|
-
{
|
507
|
-
name,
|
508
|
-
options: JSON.stringify(options),
|
509
|
-
},
|
510
|
-
],
|
511
|
-
};
|
461
|
+
async modifyEntrypoints({ entrypoints }) {
|
462
|
+
const newEntryPoints = entrypoints.map(entrypoint => {
|
463
|
+
...
|
464
|
+
});
|
465
|
+
return { entrypoints: newEntryPoints };
|
512
466
|
},
|
513
467
|
};
|
514
468
|
},
|
515
469
|
});
|
516
470
|
```
|
517
471
|
|
518
|
-
### `
|
472
|
+
### `generateEntryCode`
|
519
473
|
|
520
|
-
-
|
521
|
-
-
|
474
|
+
- 功能:用于修改生成的入口文件
|
475
|
+
- 执行阶段:生成入口文件之后,创建 builder 之前
|
522
476
|
- Hook 模型:`AsyncWaterfall`
|
523
|
-
- 类型:`
|
477
|
+
- 类型:`AsyncWorkflow<{ entrypoints: Entrypoint[] }, void>`
|
524
478
|
- 使用示例:
|
525
479
|
|
526
480
|
```ts
|
@@ -529,18 +483,18 @@ import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
|
529
483
|
export const myPlugin = (): CliPlugin<AppTools> => ({
|
530
484
|
setup(api) {
|
531
485
|
return {
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
486
|
+
async generateEntryCode({ entrypoints }) {
|
487
|
+
await Promise.all(
|
488
|
+
entrypoints.map(async entrypoint => {
|
489
|
+
...
|
490
|
+
})
|
491
|
+
);
|
538
492
|
},
|
539
493
|
};
|
540
494
|
},
|
541
495
|
});
|
542
496
|
```
|
543
|
-
|
497
|
+
*/}
|
544
498
|
### `modifyFileSystemRoutes`
|
545
499
|
|
546
500
|
- 功能:用于修改生成前端页面路由文件中的内容,内容都是需要可序列化的
|
@@ -608,32 +562,6 @@ export const myPlugin = (): CliPlugin<AppTools> => ({
|
|
608
562
|
});
|
609
563
|
```
|
610
564
|
|
611
|
-
### `modifyAsyncEntry`
|
612
|
-
|
613
|
-
- 功能:用于修改包裹入口文件的异步模块,参见 [source.enableAsyncEntry](/configure/app/source/enable-async-entry)
|
614
|
-
- 执行阶段:生成入口文件之前,[`prepare`](#prepare) 阶段触发
|
615
|
-
- Hook 模型:`AsyncWaterfall`
|
616
|
-
- 类型:`AsyncWaterfall<{ entrypoint: Entrypoint; code: string; }>`
|
617
|
-
- 使用示例:
|
618
|
-
|
619
|
-
```ts
|
620
|
-
import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
621
|
-
|
622
|
-
export const myPlugin = (): CliPlugin<AppTools> => ({
|
623
|
-
setup(api) {
|
624
|
-
return {
|
625
|
-
modifyAsyncEntry({ entrypoint, code }) {
|
626
|
-
const customCode = `console.log('hello');`;
|
627
|
-
return {
|
628
|
-
entrypoint,
|
629
|
-
code: `${customCode}${code}`,
|
630
|
-
};
|
631
|
-
},
|
632
|
-
};
|
633
|
-
},
|
634
|
-
});
|
635
|
-
```
|
636
|
-
|
637
565
|
### `htmlPartials`
|
638
566
|
|
639
567
|
- 功能:用于定制生成的 HTML 页面模版
|
@@ -782,7 +710,7 @@ export const myPlugin = (): Plugin => ({
|
|
782
710
|
- 功能:修改需要渲染的组件
|
783
711
|
- 执行阶段:渲染(SSR/CSR)
|
784
712
|
- Hook 模型:`Pipeline`
|
785
|
-
- 类型:`Pipeline<{ App: React.ComponentType<any>; },
|
713
|
+
- 类型:`Pipeline<{ App: React.ComponentType<any>;config: Record<string, any>; },React.ComponentType<any>>`
|
786
714
|
- 使用示例:
|
787
715
|
|
788
716
|
:::note
|
@@ -792,13 +720,12 @@ export const myPlugin = (): Plugin => ({
|
|
792
720
|
```ts
|
793
721
|
import { createContext } from 'react';
|
794
722
|
import type { Plugin } from '@modern-js/runtime';
|
795
|
-
import hoistNonReactStatics from 'hoist-non-react-statics';
|
796
723
|
|
797
724
|
export const myPlugin = (): Plugin => ({
|
798
725
|
setup(api) {
|
799
726
|
const FooContext = createContext('');
|
800
727
|
return {
|
801
|
-
hoc({ App }, next) {
|
728
|
+
hoc({ App, config }, next) {
|
802
729
|
const AppWrapper = (props: any) => {
|
803
730
|
return (
|
804
731
|
<FooContext.Provider store={'test'}>
|
@@ -807,7 +734,8 @@ export const myPlugin = (): Plugin => ({
|
|
807
734
|
);
|
808
735
|
};
|
809
736
|
return next({
|
810
|
-
App:
|
737
|
+
App: AppWrapper,
|
738
|
+
config
|
811
739
|
});
|
812
740
|
},
|
813
741
|
};
|
@@ -815,76 +743,3 @@ export const myPlugin = (): Plugin => ({
|
|
815
743
|
});
|
816
744
|
```
|
817
745
|
|
818
|
-
{/* ### `provide`
|
819
|
-
|
820
|
-
- 功能:修改需要渲染的 Element
|
821
|
-
- 执行阶段:渲染(SSR/CSR)
|
822
|
-
- Hook 模型:`Pipeline`
|
823
|
-
- 类型:`Pipeline<{ element: JSX.Element; props: AppProps; context: RuntimeContext }, JSX.Element>`
|
824
|
-
- 使用示例:
|
825
|
-
|
826
|
-
```ts
|
827
|
-
import { createContext } from 'react';
|
828
|
-
import type { Plugin } from '@modern-js/runtime';
|
829
|
-
|
830
|
-
export const myPlugin = (): Plugin => ({
|
831
|
-
setup(api) {
|
832
|
-
const FooContext = createContext('');
|
833
|
-
|
834
|
-
return {
|
835
|
-
provide: ({ element }) => <div>{element}</div>,
|
836
|
-
};
|
837
|
-
},
|
838
|
-
});
|
839
|
-
```
|
840
|
-
|
841
|
-
### `client`
|
842
|
-
|
843
|
-
- 功能:定制客户端渲染流程
|
844
|
-
- 执行阶段:在浏览器客户端渲染
|
845
|
-
- Hook 模型:`AsyncPipeline`
|
846
|
-
- 类型:`AsyncPipeline<{ App: React.ComponentType<any>; context?: RuntimeContext; rootElement: HTMLElement; }, void>`
|
847
|
-
- 使用示例:
|
848
|
-
|
849
|
-
```ts
|
850
|
-
import ReactDOM from 'react-dom';
|
851
|
-
import type { Plugin } from '@modern-js/runtime';
|
852
|
-
|
853
|
-
export const myPlugin = (): Plugin => ({
|
854
|
-
setup(api) {
|
855
|
-
return {
|
856
|
-
client: async ({ App, rootElement }) => {
|
857
|
-
ReactDOM.render(
|
858
|
-
React.createElement(App, { context: { foo: 'test' } }),
|
859
|
-
rootElement,
|
860
|
-
);
|
861
|
-
},
|
862
|
-
};
|
863
|
-
},
|
864
|
-
});
|
865
|
-
```
|
866
|
-
|
867
|
-
### `server`
|
868
|
-
|
869
|
-
- 功能:定制服务器端渲染流程
|
870
|
-
- 执行阶段:SSR
|
871
|
-
- Hook 模型:`AsyncPipeline`
|
872
|
-
- 类型:`AsyncPipeline<{ App: React.ComponentType<any>; context?: RuntimeContext; }, string>`
|
873
|
-
- 使用示例:
|
874
|
-
|
875
|
-
```ts
|
876
|
-
import ReactDomServer from 'react-dom/server';
|
877
|
-
import type { Plugin } from '@modern-js/runtime';
|
878
|
-
|
879
|
-
export const myPlugin = (): Plugin => ({
|
880
|
-
setup(api) {
|
881
|
-
return {
|
882
|
-
server({ App, context }) {
|
883
|
-
return ReactDomServer.renderToString(
|
884
|
-
React.createElement(App, { context: { foo: 'test' } }),
|
885
|
-
);
|
886
|
-
},
|
887
|
-
};
|
888
|
-
},
|
889
|
-
});
|
890
|
-
```*/}
|