@modern-js/main-doc 2.6.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/README.md +2 -2
- package/en/apis/app/commands.mdx +2 -0
- package/en/apis/app/hooks/config/upload.mdx +10 -0
- package/en/apis/app/runtime/model/connect.mdx +1 -1
- package/en/apis/app/runtime/model/model_.mdx +1 -1
- package/en/apis/app/runtime/model/use-model.mdx +1 -1
- package/en/apis/app/runtime/web-server/hook.mdx +2 -2
- package/en/apis/app/runtime/web-server/middleware.mdx +33 -9
- package/en/components/enable-bff.mdx +4 -4
- package/en/components/init-rspack-app.mdx +7 -0
- package/en/configure/app/bff/enable-handle-web.mdx +24 -0
- package/en/configure/app/server/enable-framework-ext.mdx +1 -1
- package/en/configure/app/server/ssr.mdx +18 -0
- package/en/guides/advanced-features/bff/_category_.json +1 -1
- package/en/guides/advanced-features/eslint.mdx +30 -32
- package/en/guides/advanced-features/low-level.mdx +1 -1
- package/en/guides/advanced-features/rspack-start.mdx +13 -17
- package/en/guides/advanced-features/ssr.mdx +210 -5
- package/en/guides/advanced-features/web-server.mdx +87 -20
- package/en/guides/{css/tailwindcss.mdx → basic-features/css.mdx} +60 -3
- package/en/guides/basic-features/env-vars.mdx +4 -0
- package/en/guides/concept/builder.mdx +1 -1
- package/en/guides/topic-detail/framework-plugin/extend.mdx +20 -19
- package/en/guides/topic-detail/framework-plugin/hook-list.mdx +156 -155
- package/en/guides/topic-detail/framework-plugin/hook.mdx +58 -43
- package/en/guides/topic-detail/framework-plugin/implement.mdx +47 -49
- package/en/guides/topic-detail/framework-plugin/introduction.mdx +22 -23
- package/en/guides/topic-detail/framework-plugin/plugin-api.mdx +13 -13
- package/en/guides/topic-detail/framework-plugin/relationship.mdx +30 -30
- package/en/guides/topic-detail/generator/plugin/develop.mdx +1 -1
- package/en/guides/topic-detail/micro-frontend/c01-introduction.mdx +17 -17
- package/en/guides/topic-detail/micro-frontend/c02-development.mdx +76 -78
- package/en/guides/topic-detail/micro-frontend/c03-main-app.mdx +57 -51
- package/en/guides/topic-detail/micro-frontend/c04-communicate.mdx +11 -11
- package/en/guides/topic-detail/micro-frontend/c05-mixed-stack.mdx +13 -13
- package/en/guides/topic-detail/model/auto-actions.mdx +18 -21
- package/en/guides/topic-detail/model/computed-state.mdx +27 -25
- package/en/guides/topic-detail/model/define-model.mdx +14 -14
- package/en/guides/topic-detail/model/faq.mdx +12 -13
- package/en/guides/topic-detail/model/manage-effects.mdx +43 -52
- package/en/guides/topic-detail/model/model-communicate.mdx +47 -45
- package/en/guides/topic-detail/model/performance.mdx +22 -23
- package/en/guides/topic-detail/model/quick-start.mdx +29 -28
- package/en/guides/topic-detail/model/redux-integration.mdx +7 -7
- package/en/guides/topic-detail/model/test-model.mdx +11 -11
- package/en/guides/topic-detail/model/typescript-best-practice.mdx +16 -15
- package/en/guides/topic-detail/model/use-model.mdx +40 -45
- package/en/guides/topic-detail/model/use-out-of-modernjs.mdx +16 -16
- package/en/guides/troubleshooting/cli.mdx +2 -2
- package/en/tutorials/first-app/c03-css.mdx +1 -1
- package/package.json +5 -5
- package/zh/apis/app/commands.mdx +2 -0
- package/zh/apis/app/hooks/config/upload.mdx +12 -2
- package/zh/apis/app/runtime/model/connect.mdx +1 -1
- package/zh/apis/app/runtime/model/model_.mdx +1 -1
- package/zh/apis/app/runtime/model/use-model.mdx +1 -1
- package/zh/apis/app/runtime/web-server/hook.mdx +2 -4
- package/zh/apis/app/runtime/web-server/middleware.mdx +30 -10
- package/zh/apis/monorepo/commands/gen-release-note.mdx +3 -3
- package/zh/components/enable-bff.mdx +4 -4
- package/zh/components/init-rspack-app.mdx +7 -0
- package/zh/components/release-note.mdx +1 -1
- package/zh/configure/app/bff/enable-handle-web.mdx +24 -0
- package/zh/configure/app/server/enable-framework-ext.mdx +1 -1
- package/zh/configure/app/server/ssr.mdx +19 -1
- package/zh/guides/advanced-features/bff/_category_.json +1 -1
- package/zh/guides/advanced-features/rspack-start.mdx +13 -17
- package/zh/guides/advanced-features/ssr.mdx +210 -4
- package/zh/guides/advanced-features/web-server.mdx +81 -16
- package/zh/guides/{css/tailwindcss.mdx → basic-features/css.mdx} +60 -3
- package/zh/guides/basic-features/env-vars.mdx +4 -0
- package/zh/guides/concept/builder.mdx +1 -1
- package/zh/guides/topic-detail/changesets/github.mdx +2 -2
- package/zh/guides/topic-detail/changesets/release-note.mdx +1 -1
- package/zh/guides/topic-detail/framework-plugin/plugin-api.mdx +2 -2
- package/zh/guides/topic-detail/generator/plugin/develop.mdx +1 -1
- package/zh/guides/topic-detail/model/faq.mdx +1 -1
- package/zh/guides/topic-detail/model/manage-effects.mdx +1 -1
- package/zh/guides/topic-detail/model/model-communicate.mdx +1 -1
- package/zh/guides/topic-detail/model/performance.mdx +1 -1
- package/zh/guides/topic-detail/model/quick-start.mdx +2 -2
- package/zh/guides/topic-detail/model/use-model.mdx +3 -3
- package/zh/tutorials/first-app/c03-css.mdx +1 -1
- package/en/guides/css/_category_.json +0 -5
- package/en/guides/css/css-in-js.mdx +0 -40
- package/en/guides/css/css-modules.mdx +0 -87
- package/en/guides/css/less-sass.mdx +0 -17
- package/en/guides/css/postcss.mdx +0 -79
- package/zh/guides/css/_category_.json +0 -5
- package/zh/guides/css/css-in-js.mdx +0 -40
- package/zh/guides/css/css-modules.mdx +0 -87
- package/zh/guides/css/less-sass.mdx +0 -17
- package/zh/guides/css/postcss.mdx +0 -80
@@ -1,24 +1,25 @@
|
|
1
1
|
---
|
2
|
-
title: Hook
|
2
|
+
title: Hook Model
|
3
3
|
sidebar_position: 2
|
4
4
|
---
|
5
|
-
# Hook
|
5
|
+
# Hook Model
|
6
6
|
|
7
|
-
|
7
|
+
First, let's introduce some content about the basic plugin system in Modern.js, including the working mode of the Hook model, the operating mode of each Hook model, and the working mode of the Manager.
|
8
8
|
|
9
|
-
|
9
|
+
Each Hook model is independent and can manage running functions independently.
|
10
10
|
|
11
|
-
##
|
11
|
+
## Basic Working Mode
|
12
|
+
|
13
|
+
Taking the Pipeline as an example, let's briefly introduce the working mode of the Hook model. Let's take a look at a simple example:
|
12
14
|
|
13
|
-
先以 Pipeline 为例,简单介绍一下 Hook 模型的工作方式。先看一个简单的例子:
|
14
15
|
|
15
16
|
```ts
|
16
17
|
import { createPipeline } from '@modern-js/plugin';
|
17
18
|
|
18
|
-
// 1.
|
19
|
+
// 1. create
|
19
20
|
const pipeline = createPipeline<number, number>();
|
20
21
|
|
21
|
-
// 2.
|
22
|
+
// 2. add function
|
22
23
|
pipeline.use((count, next) => {
|
23
24
|
return next(count + 1);
|
24
25
|
});
|
@@ -26,32 +27,38 @@ pipeline.use((count, next) => {
|
|
26
27
|
return count * 2;
|
27
28
|
});
|
28
29
|
|
29
|
-
// 3.
|
30
|
+
// 3. exec
|
30
31
|
pipeline.run(1); // 4
|
31
32
|
pipeline.run(5); // 12
|
32
33
|
```
|
33
34
|
|
34
|
-
|
35
|
+
In this example, a `Pipeline<number, number>` is created on line 3. This means that when you run it, you need to pass in a `number`, and you will get a `number` as a result,the type is:
|
35
36
|
|
36
37
|
```ts
|
37
38
|
(count: number, next: (nextCount: number) => number) => number;
|
38
39
|
```
|
39
40
|
|
40
|
-
|
41
|
+
The reason why there are only `number`s here is because we created a `Pipeline<number, number>`. If we had created a `Pipeline<number, string>`, then when we run it, we would pass in a `number` and get back a `string`. the type is:
|
41
42
|
|
42
43
|
```ts
|
43
44
|
(count: number, next: (nextCount: number) => string) => string;
|
44
45
|
```
|
45
46
|
|
46
|
-
|
47
|
+
After creating a Pipeline, you can add functions using the `use` method (lines 5 and 8). It is important to note that the order in which you add the functions is the order in which they will run by default.
|
48
|
+
|
49
|
+
Within these functions, you can manipulate the `count` value and return a value. If you call the `next` function, the next function in the pipeline will run. For example, if you add three functions: `A`, `B`, and `C`, and you call `next` in function `A`, then function `B` will run. Similarly, if you call `next` in function `B`, then function `C` will run.
|
50
|
+
|
51
|
+
In the example above, the first function added on line 5 calls `next`, which causes the second function added on line 8 to run. The return value of this function is the return value of the entire pipeline. If the first function does not call `next` and simply returns a value, then the pipeline will return that value without running any other functions.
|
52
|
+
|
53
|
+
For example:
|
47
54
|
|
48
55
|
```ts
|
49
56
|
import { createPipeline } from '@modern-js/plugin';
|
50
57
|
|
51
|
-
// 1.
|
58
|
+
// 1. create
|
52
59
|
const pipeline = createPipeline<number, number>();
|
53
60
|
|
54
|
-
// 2.
|
61
|
+
// 2. add function
|
55
62
|
pipeline.use((count, next) => {
|
56
63
|
return count + 1;
|
57
64
|
});
|
@@ -64,20 +71,23 @@ pipeline.run(1); // 2
|
|
64
71
|
pipeline.run(5); // 6
|
65
72
|
```
|
66
73
|
|
67
|
-
|
74
|
+
If the first function does not call `next`, the second function will not run and the return value of the pipeline will be the return value of the first function.
|
75
|
+
|
76
|
+
Finally, the way to run the Pipeline is simply to call `pipeline.run()`.
|
68
77
|
|
69
|
-
最后,运行 Pipeline 的方式也显而易见就是调用 `pipeline.run` 。
|
70
78
|
|
71
|
-
##
|
79
|
+
## Differences between different Hook models
|
72
80
|
|
73
|
-
|
81
|
+
The above section describes the general working mode of the Pipeline, and the working modes of other Hook models are similar. The main differences lie in the function type, execution order, and parameters.
|
74
82
|
|
75
83
|
### Pipeline
|
76
84
|
|
77
|
-
|
85
|
+
The example above describes the Pipeline, so we won't go into details here. In the Pipeline category, there are two subcategories: Sync and Async, which manage functions of either Sync or Async type, respectively.
|
78
86
|
|
79
87
|
:::info
|
80
|
-
|
88
|
+
If there are no functions in the Pipeline or all functions have called the `next` function, then you need to provide a value when running the Pipeline.
|
89
|
+
:::
|
90
|
+
|
81
91
|
|
82
92
|
```ts
|
83
93
|
pipeline(
|
@@ -94,15 +104,15 @@ pipeline(
|
|
94
104
|
|
95
105
|
### Waterfall
|
96
106
|
|
97
|
-
|
107
|
+
This model, as the name suggests, is characterized by the sequential passing of parameters, where the return value of the previous function becomes the input parameter of the next function. Let's look at an example::
|
98
108
|
|
99
109
|
```ts
|
100
110
|
import { createWaterfall } from '@modern-js/plugin';
|
101
111
|
|
102
|
-
// 1.
|
112
|
+
// 1. create
|
103
113
|
const waterfall = createWaterfall<number>();
|
104
114
|
|
105
|
-
// 2.
|
115
|
+
// 2. add function
|
106
116
|
waterfall.use(count => {
|
107
117
|
return count + 1;
|
108
118
|
});
|
@@ -110,32 +120,34 @@ waterfall.use(count => {
|
|
110
120
|
return count * 2;
|
111
121
|
});
|
112
122
|
|
113
|
-
// 3.
|
123
|
+
// 3. exec
|
114
124
|
waterfall.run(1); // 4
|
115
125
|
waterfall.run(5); // 12
|
116
126
|
```
|
117
127
|
|
118
|
-
|
128
|
+
In this example, a `Waterfall<number>` type is created, which means that the input and output types of this model are the same. In this case, both the input and output types are `number`, the type is:
|
119
129
|
|
120
130
|
```ts
|
121
131
|
(count: number) => number;
|
122
132
|
```
|
123
133
|
|
124
|
-
|
134
|
+
At first glance, this example may seem to have the same functionality as the Pipeline above, but there are some important differences to note. Firstly, the functions managed by Waterfall do not have a `next` function as the second argument, so they cannot modify the execution order by calling `next` within the function. Secondly, the input and output types of the functions must be the same (unlike in the Pipeline where they can be different).
|
125
135
|
|
126
|
-
|
136
|
+
Similarly to Pipeline, Waterfall has Sync and Async subcategories that respectively manage Sync and Async functions.
|
127
137
|
|
128
138
|
### Workflow
|
129
139
|
|
130
|
-
|
140
|
+
This Hook model is different from the two Hook models above in that there is no strong concept of passing parameters and return values in a sequential order. In this model, each function runs independently based on the same input parameter.
|
141
|
+
|
142
|
+
for example:
|
131
143
|
|
132
144
|
```ts
|
133
145
|
import { createWorkflow } from '@modern-js/plugin';
|
134
146
|
|
135
|
-
// 1.
|
147
|
+
// 1. create
|
136
148
|
const workflow = createWorkflow<number, number>();
|
137
149
|
|
138
|
-
// 2.
|
150
|
+
// 2. add plugin
|
139
151
|
workflow.use(count => {
|
140
152
|
return count + 1;
|
141
153
|
});
|
@@ -148,26 +160,29 @@ workflow.run(1); // [2, 2]
|
|
148
160
|
workflow.run(5); // [6, 10]
|
149
161
|
```
|
150
162
|
|
151
|
-
|
163
|
+
In this example, two functions are added to the Workflow, so the result of running the Workflow is an array of the results of these two functions.
|
164
|
+
|
165
|
+
Although there is no strong concept of passing parameters and return values in a sequential order in this model, there are still differences in the execution order. In the Workflow category, there are three subcategories: Sync, Async, and Parallel.
|
166
|
+
|
167
|
+
The difference between them lies in the execution order of the functions. By default, they are all executed in the order they are added, but in Sync and Async mode, the execution order is strictly based on the order in which they are added, while in Parallel mode, a variant of Async mode, `Promise.all` is used to execute all the functions, while in Async mode, `await` is used to wait for the previous function to finish running.
|
152
168
|
|
153
|
-
|
169
|
+
## Comparison of Hook models
|
154
170
|
|
155
|
-
## Hook 模型对比
|
156
171
|
|
157
172
|
<div style={{ width: "100%", overflowX: "scroll" }}>
|
158
173
|
<div style={{ width: "150%" }}>
|
159
174
|
|
160
|
-
| |
|
161
|
-
| ---------------- |
|
162
|
-
| Pipeline | Sync
|
163
|
-
| AsyncPipeline | Sync/Async
|
164
|
-
|
|
165
|
-
|
|
166
|
-
| Workflow | Sync
|
167
|
-
| AsyncWorkflow | Sync/Async
|
168
|
-
| ParallelWorkFlow | Sync/Async
|
175
|
+
| | Function Type | Execution Order | Source of Function Parameters | Source of Execution Returns | Preferred Task Type | Function TS Type |
|
176
|
+
| ---------------- | ------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------ |
|
177
|
+
| Pipeline | Sync | Executes the first added function by default, can execute subsequent functions through `next` | The parameters of the first function come from the input, while the parameters of subsequent functions come from the parameters passed to `next` | Returns from the first function | <ul><li>Needs to modify initial parameters</li><li>Needs to modify function execution order</li></ul> | `(input: I, next: Next<I, O>) => O` |
|
178
|
+
| AsyncPipeline | Sync/Async | Executes the first added function by default, can execute subsequent functions through `next` | The parameters of the first function come from the input, while the parameters of subsequent functions come from the parameters passed to `next` | Returns from the first function | <ul><li>Needs to modify initial parameters</li><li>Needs to modify function execution order</li></ul> | `(input: I, next: AsyncNext<I, O>) => O | Promise<O>` |
|
179
|
+
| Waterfall | Sync | Executes functions in order | The parameters of the first function come from the input, while the parameters of subsequent functions come from the return value of the previous function | Returns from the last function | <ul><li>Needs to modify initial parameters</li><li>Does not need to modify function execution order</li></ul> | `(I: I) => I` |
|
180
|
+
| AsyncWaterfall | Sync/Async | Executes functions in order | The parameters of the first function come from the input, while the parameters of subsequent functions come from the return value of the previous function | Returns from the last function | <ul><li>Needs to modify initial parameters</li><li>Does not need to modify function execution order</li></ul> | `(I: I) => I | Promise<I>` |
|
181
|
+
| Workflow | Sync | Executes functions in order | All function parameters come from the input | An array of all function returns | <ul><li>Does not need to modify initial parameters</li><li>Does not need to modify function execution order</li></ul> | `(I: I) => O` |
|
182
|
+
| AsyncWorkflow | Sync/Async | Executes functions in order | All function parameters come from the input | An array of all function returns | <ul><li>Does not need to modify initial parameters</li><li>Does not need to modify function execution order</li></ul> | `(I: I) => O | Promise<O>` |
|
183
|
+
| ParallelWorkFlow | Sync/Async | Executes functions asynchronously | All function parameters come from the input | An array of all function returns | <ul><li>Does not need to modify initial parameters</li><li>Does not care about function execution order</li></ul> | `(I: I) => O | Promise<O>` |
|
169
184
|
|
170
185
|
</div>
|
171
186
|
</div>
|
172
187
|
|
173
|
-
Workflow
|
188
|
+
"Workflow" and "Waterfall" are actually variants of the "Pipeline" model. While it's possible to implement "Workflow" and "Waterfall" using a specific writing style with "Pipeline", it can be more complicated with many implicit conventions. To make it easier to use, these two variants are provided to satisfy specific use cases.
|
@@ -1,53 +1,51 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Write Plugins
|
3
3
|
sidebar_position: 3
|
4
4
|
---
|
5
|
-
#
|
5
|
+
# How to Write Plugins
|
6
6
|
|
7
|
-
|
7
|
+
The previous section introduced the Hook models used by Modern.js plugins, while this section describes how to write plugins.
|
8
8
|
|
9
|
-
##
|
9
|
+
## Implementing a Plugin
|
10
10
|
|
11
|
-
Modern.js
|
11
|
+
A Modern.js plugin is an object that includes the following properties:
|
12
12
|
|
13
|
-
- `name`:
|
14
|
-
- `setup`:
|
13
|
+
- `name`: The name of the plugin, a unique identifier.
|
14
|
+
- `setup`: The initialization function for the plugin, which only runs once. The `setup` function can return a Hooks object, which Modern.js executes at specific times.
|
15
15
|
|
16
16
|
```ts
|
17
17
|
const myPlugin = {
|
18
18
|
name: 'my-plugin',
|
19
19
|
|
20
20
|
setup() {
|
21
|
-
// 执行一些初始化逻辑
|
22
21
|
const foo = '1';
|
23
22
|
|
24
|
-
//
|
23
|
+
// return hook object
|
25
24
|
return {
|
26
25
|
afterBuild: () => {
|
27
|
-
// 在构建完成后执行逻辑
|
28
26
|
},
|
29
27
|
};
|
30
28
|
},
|
31
29
|
};
|
32
30
|
```
|
33
31
|
|
34
|
-
|
32
|
+
In addition, plugins allow configuration of the execution order with other plugins. For more information, please refer to [Plugin Relationship](/guides/topic-detail/framework-plugin/relationship).
|
35
33
|
|
36
|
-
###
|
34
|
+
### Plugin Types
|
37
35
|
|
38
|
-
Modern
|
36
|
+
Modern.js supports various types of project development, such as application development (`app-tools`), module development (`module-tools`), etc.
|
39
37
|
|
40
|
-
|
38
|
+
To balance the differences and commonalities between various types of project development, Modern.js organizes plugins as shown in the following figure:
|
41
39
|
|
42
40
|

|
43
41
|
|
44
|
-
|
42
|
+
As shown in the figure, Modern.js roughly divides plugins into two categories:
|
45
43
|
|
46
|
-
1.
|
44
|
+
1. Common plugins: Plugins that only include some basic Hooks.
|
47
45
|
|
48
|
-
2.
|
46
|
+
2. Project plugins: Different project developments will extend their own Hooks, Config, etc. on the basis of common plugins.
|
49
47
|
|
50
|
-
|
48
|
+
When using TypeScript, you can import built-in types such as `CliPlugin` to provide correct type inference for plugins.
|
51
49
|
|
52
50
|
```ts
|
53
51
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -60,14 +58,13 @@ const myPlugin: CliPlugin = {
|
|
60
58
|
|
61
59
|
return {
|
62
60
|
afterBuild: () => {
|
63
|
-
// 在构建完成后执行逻辑
|
64
61
|
},
|
65
62
|
};
|
66
63
|
},
|
67
64
|
};
|
68
65
|
```
|
69
66
|
|
70
|
-
|
67
|
+
The above code is a general-purpose plugin, containing only some basic Hooks. Modern.js supports extending the definition of plugins through generics:
|
71
68
|
|
72
69
|
```ts
|
73
70
|
import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
@@ -80,14 +77,13 @@ const myPlugin: CliPlugin<AppTools> = {
|
|
80
77
|
|
81
78
|
return {
|
82
79
|
afterBuild: () => {
|
83
|
-
// 在构建完成后执行逻辑
|
84
80
|
},
|
85
81
|
};
|
86
82
|
},
|
87
83
|
};
|
88
84
|
```
|
89
85
|
|
90
|
-
|
86
|
+
If you look closely at the type `AppTools`, you can see that `AppTools` consists of 3 types.
|
91
87
|
|
92
88
|
```ts
|
93
89
|
type AppTools = {
|
@@ -97,10 +93,10 @@ type AppTools = {
|
|
97
93
|
};
|
98
94
|
```
|
99
95
|
|
100
|
-
|
96
|
+
When writing plugins, plugins extend their own types like Hooks on different bases through generic extensions:
|
101
97
|
|
102
98
|
```ts
|
103
|
-
//
|
99
|
+
// common plugin
|
104
100
|
import type { CliPlugin } from '@modern-js/core';
|
105
101
|
import type { MyPluginHook } from 'xxx';
|
106
102
|
|
@@ -108,18 +104,18 @@ const myPlugin: CliPlugin<{ hooks: MyPluginHook }> = {};
|
|
108
104
|
```
|
109
105
|
|
110
106
|
```ts
|
111
|
-
//
|
107
|
+
// extend from app-tools hook
|
112
108
|
import type { CliPlugin, AppTools } from '@modern-js/app-tools';
|
113
109
|
import type { MyPluginHook } from 'xxx';
|
114
110
|
|
115
111
|
const myPlugin: CliPlugin<AppTools & { hooks: MyPluginHook }> = {};
|
116
112
|
```
|
117
113
|
|
118
|
-
|
114
|
+
Please refer to [Extending Hooks](/guides/topic-detail/framework-plugin/extend) for detailed explanations.
|
119
115
|
|
120
|
-
###
|
116
|
+
### Plugin Configuration
|
121
117
|
|
122
|
-
|
118
|
+
**It is recommended to write plugins in the form of functions**, so that plugins can receive configuration options through function parameters:
|
123
119
|
|
124
120
|
```ts
|
125
121
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -137,9 +133,10 @@ const myPlugin = (options: MyPluginOptions): CliPlugin => ({
|
|
137
133
|
});
|
138
134
|
```
|
139
135
|
|
140
|
-
###
|
136
|
+
### Plugin API
|
137
|
+
|
138
|
+
The `setup` function of a plugin receives an `api` parameter, and you can call some methods provided on the `api` to get configuration, application context, and other information.
|
141
139
|
|
142
|
-
插件的 `setup` 函数会接收一个 api 入参,你可以调用 api 上提供的一些方法来获取到配置、应用上下文等信息。
|
143
140
|
|
144
141
|
```ts
|
145
142
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -148,21 +145,22 @@ export default (): CliPlugin => ({
|
|
148
145
|
name: 'my-plugin',
|
149
146
|
|
150
147
|
setup(api) {
|
151
|
-
//
|
148
|
+
// get user set config
|
152
149
|
const config = api.useConfigContext();
|
153
|
-
//
|
150
|
+
// get context
|
154
151
|
const appContext = api.useAppContext();
|
155
|
-
//
|
152
|
+
// get final config
|
156
153
|
const resolvedConfig = api.useResolvedConfigContext();
|
157
154
|
},
|
158
155
|
});
|
159
156
|
```
|
160
157
|
|
161
|
-
|
158
|
+
For more detail [Plugin API](/guides/topic-detail/framework-plugin/plugin-api)。
|
159
|
+
|
160
|
+
### Async setup
|
162
161
|
|
163
|
-
|
162
|
+
The `setup` function of a CLI plugin can be an asynchronous function, which can execute asynchronous logic during the initialization process.
|
164
163
|
|
165
|
-
CLI 插件的 setup 可以是一个异步函数,在初始化过程中执行异步逻辑。
|
166
164
|
|
167
165
|
```ts
|
168
166
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -176,13 +174,13 @@ export default (): CliPlugin => ({
|
|
176
174
|
});
|
177
175
|
```
|
178
176
|
|
179
|
-
##
|
177
|
+
## Adding Plugins
|
180
178
|
|
181
|
-
|
179
|
+
Custom plugins can be used by following the instructions in the [plugins](/configure/app/plugins) section of the documentation. Below is the recommended way to implement plugins in Modern.js.
|
182
180
|
|
183
|
-
###
|
181
|
+
### Developing Local Plugins
|
184
182
|
|
185
|
-
|
183
|
+
It is recommended to write local plugins in the `config/plugin` directory and export them using `export default`:
|
186
184
|
|
187
185
|
```ts title=config/plugin/myPlugin.ts
|
188
186
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -191,12 +189,12 @@ export default (): CliPlugin => ({
|
|
191
189
|
name: 'my-plugin',
|
192
190
|
|
193
191
|
setup() {
|
194
|
-
//
|
192
|
+
// init plugin
|
195
193
|
},
|
196
194
|
});
|
197
195
|
```
|
198
196
|
|
199
|
-
|
197
|
+
register plugin in `modern.config.ts`:
|
200
198
|
|
201
199
|
```ts title="modern.config.ts"
|
202
200
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -207,11 +205,11 @@ export default defineConfig({
|
|
207
205
|
});
|
208
206
|
```
|
209
207
|
|
210
|
-
###
|
208
|
+
### Publishing a Plugin on npm
|
211
209
|
|
212
|
-
|
210
|
+
If you want to publish your Modern.js plugin on npm, it's recommended to use the module project solution provided by Modern.js to manage and build the plugin.
|
213
211
|
|
214
|
-
|
212
|
+
First, create an empty module project solution and adjust the package name:
|
215
213
|
|
216
214
|
```json
|
217
215
|
{
|
@@ -220,7 +218,7 @@ export default defineConfig({
|
|
220
218
|
}
|
221
219
|
```
|
222
220
|
|
223
|
-
|
221
|
+
create plugin main file:
|
224
222
|
|
225
223
|
```ts title=src/index.ts
|
226
224
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -229,12 +227,12 @@ export default (): CliPlugin => ({
|
|
229
227
|
name: 'my-plugin',
|
230
228
|
|
231
229
|
setup() {
|
232
|
-
//
|
230
|
+
// plugin init
|
233
231
|
},
|
234
232
|
});
|
235
233
|
```
|
236
234
|
|
237
|
-
|
235
|
+
After publishing, install it to the project you need to use `pnpm add my-plugin`, take an application project as an example, and then add it in `modern.config.ts`:
|
238
236
|
|
239
237
|
```ts title="modern.config.ts"
|
240
238
|
import { defineConfig } from '@modern-js/app-tools';
|
@@ -245,4 +243,4 @@ export default defineConfig({
|
|
245
243
|
});
|
246
244
|
```
|
247
245
|
|
248
|
-
|
246
|
+
If you find that there are currently unsatisfactory scenarios in Modern.js, welcome to build the Modern.js ecosystem together by **writing custom plugins**.
|
@@ -1,16 +1,16 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Introduction
|
3
3
|
sidebar_position: 1
|
4
4
|
---
|
5
|
-
#
|
5
|
+
# Introduction
|
6
6
|
|
7
|
-
## Modern.js
|
7
|
+
## Modern.js Plugin System
|
8
8
|
|
9
|
-
Modern.js
|
9
|
+
Modern.js is a system used for extending the functionality of a project at different stages such as running, requesting, and rendering. It mainly consists of three parts: the Hook model, the Manager, and the Context Sharing mechanism.
|
10
10
|
|
11
|
-
Hook
|
11
|
+
The Hook model is used to determine the execution method of the current Hook, and functions with different Hook models have different execution logics. The Manager is used to control the execution and scheduling of Hooks. The Context Sharing mechanism is used to pass information between different Hooks.
|
12
12
|
|
13
|
-
|
13
|
+
Currently, Modern.js provides several different Hook models:
|
14
14
|
|
15
15
|
- Pipeline
|
16
16
|
- Sync
|
@@ -24,28 +24,27 @@ Hook 模型用于确定当前 Hook 的执行方式,不同 Hook 模型的函数
|
|
24
24
|
- Parallel(Async)
|
25
25
|
|
26
26
|
:::note
|
27
|
-
|
28
|
-
|
27
|
+
Subsequent chapters will introduce the execution methods of each model in detail.
|
29
28
|
:::
|
30
29
|
|
31
|
-
|
30
|
+
Based on the Hook model and Manager, Modern.js exposes three sets of plugins: CLI, Runtime, and Server.
|
32
31
|
|
33
|
-
|
32
|
+
Among them, the CLI plugin is the main running flow control model in Modern.js, and most of the features in Modern.js are mainly run through this set of models. The Runtime plugin is mainly responsible for processing the rendering logic of React components. The Server plugin is mainly used for controlling the server lifecycle and user requests.
|
34
33
|
|
35
|
-
##
|
34
|
+
## What Plugins Can Do
|
36
35
|
|
37
|
-
Modern.js
|
36
|
+
All of Modern.js's features are implemented through this set of plugins, which means that all of Modern.js's capabilities are open to developers. Developers can write plugins to extend more functionality and adapt to complex scenarios, including but not limited to:
|
38
37
|
|
39
|
-
-
|
40
|
-
-
|
41
|
-
-
|
42
|
-
-
|
43
|
-
-
|
44
|
-
-
|
45
|
-
-
|
46
|
-
-
|
47
|
-
-
|
48
|
-
-
|
38
|
+
- Registering commands
|
39
|
+
- Modifying Modern.js configuration and validation schema
|
40
|
+
- Modifying compilation configurations for Webpack/Babel/Less/Sass/Tailwind CSS/...
|
41
|
+
- Modifying the React components/elements to be rendered at runtime
|
42
|
+
- Modifying page routing
|
43
|
+
- Modifying server routing
|
44
|
+
- Customizing console output
|
45
|
+
- Customizing dynamic HTML templates
|
46
|
+
- Customizing Node.js server frameworks
|
47
|
+
- Customizing React component client/server rendering
|
49
48
|
- ...
|
50
49
|
|
51
|
-
|
50
|
+
When Modern.js does not currently cover the functionality or scenario that you need, you can develop a custom plugin to implement the related functionality for adapting to special scenarios.
|
@@ -1,10 +1,10 @@
|
|
1
1
|
---
|
2
|
-
title:
|
2
|
+
title: Plugin API
|
3
3
|
sidebar_position: 6
|
4
4
|
---
|
5
|
-
#
|
5
|
+
# Plugin API
|
6
6
|
|
7
|
-
|
7
|
+
The `setup` function of the plugin will receive an `api` imported parameter, and you can call some methods provided on the api to obtain information such as configuration and application context.
|
8
8
|
|
9
9
|
```ts
|
10
10
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -13,11 +13,11 @@ export default (): CliPlugin => ({
|
|
13
13
|
name: 'my-plugin',
|
14
14
|
|
15
15
|
setup(api) {
|
16
|
-
//
|
16
|
+
// get user config
|
17
17
|
const config = api.useConfigContext();
|
18
|
-
//
|
18
|
+
// get plugin context
|
19
19
|
const appContext = api.useAppContext();
|
20
|
-
//
|
20
|
+
// get resolved config
|
21
21
|
const resolvedConfig = api.useResolvedConfigContext();
|
22
22
|
},
|
23
23
|
});
|
@@ -27,7 +27,7 @@ export default (): CliPlugin => ({
|
|
27
27
|
|
28
28
|
### useConfigContext
|
29
29
|
|
30
|
-
|
30
|
+
Used to retrieve the original configuration of the application.
|
31
31
|
|
32
32
|
```ts
|
33
33
|
const useConfigContext: () => UserConfig;
|
@@ -45,11 +45,11 @@ interface UserConfig {
|
|
45
45
|
}
|
46
46
|
```
|
47
47
|
|
48
|
-
|
48
|
+
Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
|
49
49
|
|
50
50
|
### useAppContext
|
51
51
|
|
52
|
-
|
52
|
+
Used to retrieve the runtime context of the application.
|
53
53
|
|
54
54
|
```ts
|
55
55
|
const useAppContext: () => IAppContext;
|
@@ -77,7 +77,7 @@ interface IAppContext {
|
|
77
77
|
|
78
78
|
### useResolvedConfigContext
|
79
79
|
|
80
|
-
|
80
|
+
Used to retrieve the final configuration after parsing.
|
81
81
|
|
82
82
|
```ts
|
83
83
|
const useResolvedConfigContext: () => NormalizedConfig;
|
@@ -96,11 +96,11 @@ interface NormalizedConfig {
|
|
96
96
|
}
|
97
97
|
```
|
98
98
|
|
99
|
-
|
99
|
+
Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
|
100
100
|
|
101
101
|
### useHookRunners
|
102
102
|
|
103
|
-
|
103
|
+
Used to retrieve the executor of Hooks and trigger the execution of specific Hooks.
|
104
104
|
|
105
105
|
```ts
|
106
106
|
import type { CliPlugin } from '@modern-js/core';
|
@@ -110,7 +110,7 @@ export default (): CliPlugin => ({
|
|
110
110
|
|
111
111
|
async setup(api) {
|
112
112
|
const hookRunners = api.useHookRunners();
|
113
|
-
//
|
113
|
+
// invoke afterBuild Hook
|
114
114
|
await hookRunners.afterBuild();
|
115
115
|
},
|
116
116
|
});
|