@modern-js/main-doc 2.65.4 → 2.66.0

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.
Files changed (87) hide show
  1. package/docs/en/apis/app/hooks/config/_meta.json +1 -0
  2. package/docs/en/apis/app/hooks/config/favicon.mdx +29 -0
  3. package/docs/en/apis/app/hooks/config/icon.mdx +3 -30
  4. package/docs/en/community/blog/v2-release-note.mdx +1 -1
  5. package/docs/en/configure/app/plugins.mdx +2 -2
  6. package/docs/en/configure/app/tools/esbuild.mdx +1 -1
  7. package/docs/en/configure/app/tools/swc.mdx +1 -1
  8. package/docs/en/plugin/_meta.json +8 -7
  9. package/docs/en/plugin/cli-plugins/_meta.json +1 -1
  10. package/docs/en/plugin/cli-plugins/api.mdx +617 -0
  11. package/docs/en/plugin/cli-plugins/life-cycle.mdx +139 -0
  12. package/docs/en/plugin/cli-plugins/migration.mdx +98 -0
  13. package/docs/en/plugin/introduction.mdx +119 -47
  14. package/docs/en/plugin/official/_meta.json +12 -0
  15. package/docs/en/plugin/official/cli-plugins/_meta.json +1 -0
  16. package/docs/en/plugin/official/cli-plugins.mdx +6 -0
  17. package/docs/en/plugin/official/rsbuild-plugins.mdx +3 -0
  18. package/docs/en/plugin/plugin-system.mdx +237 -0
  19. package/docs/en/plugin/runtime-plugins/_meta.json +1 -0
  20. package/docs/en/plugin/runtime-plugins/api.mdx +165 -0
  21. package/docs/en/plugin/runtime-plugins/life-cycle.mdx +29 -0
  22. package/docs/en/plugin/runtime-plugins/migration.mdx +101 -0
  23. package/docs/en/plugin/server-plugins/api.mdx +3 -0
  24. package/docs/en/plugin/server-plugins/life-cycle.mdx +3 -0
  25. package/docs/zh/apis/app/hooks/config/_meta.json +1 -0
  26. package/docs/zh/apis/app/hooks/config/favicon.mdx +29 -0
  27. package/docs/zh/apis/app/hooks/config/icon.mdx +3 -30
  28. package/docs/zh/community/blog/v2-release-note.mdx +1 -1
  29. package/docs/zh/configure/app/plugins.mdx +2 -2
  30. package/docs/zh/configure/app/tools/esbuild.mdx +1 -1
  31. package/docs/zh/configure/app/tools/swc.mdx +1 -1
  32. package/docs/zh/plugin/_meta.json +8 -7
  33. package/docs/zh/plugin/cli-plugins/_meta.json +1 -1
  34. package/docs/zh/plugin/cli-plugins/api.mdx +617 -0
  35. package/docs/zh/plugin/cli-plugins/life-cycle.mdx +139 -0
  36. package/docs/zh/plugin/cli-plugins/migration.mdx +98 -0
  37. package/docs/zh/plugin/introduction.mdx +92 -20
  38. package/docs/zh/plugin/official/_meta.json +12 -0
  39. package/docs/zh/plugin/official/cli-plugins/_meta.json +1 -0
  40. package/docs/zh/plugin/official/cli-plugins.mdx +6 -0
  41. package/docs/zh/plugin/official/rsbuild-plugins.mdx +3 -0
  42. package/docs/zh/plugin/plugin-system.mdx +239 -0
  43. package/docs/zh/plugin/runtime-plugins/_meta.json +1 -0
  44. package/docs/zh/plugin/runtime-plugins/api.mdx +166 -0
  45. package/docs/zh/plugin/runtime-plugins/life-cycle.mdx +29 -0
  46. package/docs/zh/plugin/runtime-plugins/migration.mdx +101 -0
  47. package/docs/zh/plugin/server-plugins/api.mdx +3 -0
  48. package/docs/zh/plugin/server-plugins/life-cycle.mdx +3 -0
  49. package/i18n.json +4 -0
  50. package/package.json +4 -4
  51. package/src/components/Footer/index.tsx +1 -1
  52. package/src/components/Mermaid/index.tsx +60 -0
  53. package/src/components/Mermaid/style.scss +221 -0
  54. package/docs/en/plugin/cli-plugins.mdx +0 -6
  55. package/docs/en/plugin/plugin-system/_meta.json +0 -10
  56. package/docs/en/plugin/plugin-system/extend.mdx +0 -163
  57. package/docs/en/plugin/plugin-system/hook-list.mdx +0 -711
  58. package/docs/en/plugin/plugin-system/hook.mdx +0 -188
  59. package/docs/en/plugin/plugin-system/implement.mdx +0 -243
  60. package/docs/en/plugin/plugin-system/introduction.mdx +0 -95
  61. package/docs/en/plugin/plugin-system/lifecycle.mdx +0 -16
  62. package/docs/en/plugin/plugin-system/plugin-api.mdx +0 -138
  63. package/docs/en/plugin/plugin-system/relationship.mdx +0 -119
  64. package/docs/en/plugin/rsbuild-plugins.mdx +0 -3
  65. package/docs/zh/plugin/cli-plugins.mdx +0 -6
  66. package/docs/zh/plugin/plugin-system/_meta.json +0 -10
  67. package/docs/zh/plugin/plugin-system/extend.mdx +0 -163
  68. package/docs/zh/plugin/plugin-system/hook-list.mdx +0 -715
  69. package/docs/zh/plugin/plugin-system/hook.mdx +0 -173
  70. package/docs/zh/plugin/plugin-system/implement.mdx +0 -250
  71. package/docs/zh/plugin/plugin-system/introduction.mdx +0 -94
  72. package/docs/zh/plugin/plugin-system/lifecycle.mdx +0 -16
  73. package/docs/zh/plugin/plugin-system/plugin-api.mdx +0 -138
  74. package/docs/zh/plugin/plugin-system/relationship.mdx +0 -119
  75. package/docs/zh/plugin/rsbuild-plugins.mdx +0 -4
  76. /package/docs/en/plugin/{cli-plugins → official/cli-plugins}/plugin-bff.mdx +0 -0
  77. /package/docs/en/plugin/{cli-plugins → official/cli-plugins}/plugin-ssg.mdx +0 -0
  78. /package/docs/en/plugin/{cli-plugins → official/cli-plugins}/plugin-swc.mdx +0 -0
  79. /package/docs/en/plugin/{cli-plugins → official/cli-plugins}/plugin-tailwind.mdx +0 -0
  80. /package/docs/en/plugin/{rsbuild-plugins → official/rsbuild-plugins}/_meta.json +0 -0
  81. /package/docs/en/plugin/{rsbuild-plugins → official/rsbuild-plugins}/plugin-esbuild.mdx +0 -0
  82. /package/docs/zh/plugin/{cli-plugins → official/cli-plugins}/plugin-bff.mdx +0 -0
  83. /package/docs/zh/plugin/{cli-plugins → official/cli-plugins}/plugin-ssg.mdx +0 -0
  84. /package/docs/zh/plugin/{cli-plugins → official/cli-plugins}/plugin-swc.mdx +0 -0
  85. /package/docs/zh/plugin/{cli-plugins → official/cli-plugins}/plugin-tailwind.mdx +0 -0
  86. /package/docs/zh/plugin/{rsbuild-plugins → official/rsbuild-plugins}/_meta.json +0 -0
  87. /package/docs/zh/plugin/{rsbuild-plugins → official/rsbuild-plugins}/plugin-esbuild.mdx +0 -0
@@ -1,188 +0,0 @@
1
- ---
2
- sidebar_position: 2
3
- ---
4
-
5
- # Hook Model
6
-
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
-
9
- Each Hook model is independent and can manage running functions independently.
10
-
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:
14
-
15
-
16
- ```ts
17
- import { createPipeline } from '@modern-js/plugin';
18
-
19
- // 1. create
20
- const pipeline = createPipeline<number, number>();
21
-
22
- // 2. add function
23
- pipeline.use((count, next) => {
24
- return next(count + 1);
25
- });
26
- pipeline.use((count, next) => {
27
- return count * 2;
28
- });
29
-
30
- // 3. exec
31
- pipeline.run(1); // 4
32
- pipeline.run(5); // 12
33
- ```
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:
36
-
37
- ```ts
38
- (count: number, next: (nextCount: number) => number) => number;
39
- ```
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:
42
-
43
- ```ts
44
- (count: number, next: (nextCount: number) => string) => string;
45
- ```
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:
54
-
55
- ```ts
56
- import { createPipeline } from '@modern-js/plugin';
57
-
58
- // 1. create
59
- const pipeline = createPipeline<number, number>();
60
-
61
- // 2. add function
62
- pipeline.use((count, next) => {
63
- return count + 1;
64
- });
65
- pipeline.use((count, next) => {
66
- return count * 2;
67
- });
68
-
69
- // 3. Run
70
- pipeline.run(1); // 2
71
- pipeline.run(5); // 6
72
- ```
73
-
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()`.
77
-
78
-
79
- ## Differences between different Hook models
80
-
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.
82
-
83
- ### Pipeline
84
-
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.
86
-
87
- :::info
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
-
91
-
92
- ```ts
93
- pipeline(
94
- {},
95
- {
96
- onLast: () => {
97
- // do something
98
- },
99
- },
100
- );
101
- ```
102
-
103
- :::
104
-
105
- ### Waterfall
106
-
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::
108
-
109
- ```ts
110
- import { createWaterfall } from '@modern-js/plugin';
111
-
112
- // 1. create
113
- const waterfall = createWaterfall<number>();
114
-
115
- // 2. add function
116
- waterfall.use(count => {
117
- return count + 1;
118
- });
119
- waterfall.use(count => {
120
- return count * 2;
121
- });
122
-
123
- // 3. exec
124
- waterfall.run(1); // 4
125
- waterfall.run(5); // 12
126
- ```
127
-
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:
129
-
130
- ```ts
131
- (count: number) => number;
132
- ```
133
-
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).
135
-
136
- Similarly to Pipeline, Waterfall has Sync and Async subcategories that respectively manage Sync and Async functions.
137
-
138
- ### Workflow
139
-
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:
143
-
144
- ```ts
145
- import { createWorkflow } from '@modern-js/plugin';
146
-
147
- // 1. create
148
- const workflow = createWorkflow<number, number>();
149
-
150
- // 2. add plugin
151
- workflow.use(count => {
152
- return count + 1;
153
- });
154
- workflow.use(count => {
155
- return count * 2;
156
- });
157
-
158
- // 3. Run
159
- workflow.run(1); // [2, 2]
160
- workflow.run(5); // [6, 10]
161
- ```
162
-
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.
168
-
169
- ## Comparison of Hook models
170
-
171
-
172
- <div style={{ width: "100%", overflowX: "scroll" }}>
173
- <div style={{ width: "150%" }}>
174
-
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>` |
184
-
185
- </div>
186
- </div>
187
-
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,243 +0,0 @@
1
- ---
2
- sidebar_position: 3
3
- ---
4
-
5
- # Develop Plugins
6
-
7
- The previous section introduced the Hook models used by Modern.js plugins, while this section describes how to develop plugins.
8
-
9
- ## Implementing a Plugin
10
-
11
- A Modern.js plugin is an object that includes the following properties:
12
-
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
-
16
- ```ts
17
- const myPlugin = {
18
- name: 'my-plugin',
19
-
20
- setup() {
21
- const foo = '1';
22
-
23
- // return hook object
24
- return {
25
- afterBuild: () => {},
26
- };
27
- },
28
- };
29
- ```
30
-
31
- In addition, plugins allow configuration of the execution order with other plugins. For more information, please refer to [Plugin Relationship](/plugin/plugin-system/relationship).
32
-
33
- ### Plugin Types
34
-
35
- Modern.js supports various types of project development, such as application development (Modern.js Framework), module development (Modern.js Module), etc.
36
-
37
- To balance the differences and commonalities between various types of project development, Modern.js organizes plugins as shown in the following figure:
38
-
39
- ![plugin-relationship](https://lf3-static.bytednsdoc.com/obj/eden-cn/eeeh7uhbepxlpe/modern-website/plugin-relationship.jpg)
40
-
41
- As shown in the figure, Modern.js roughly divides plugins into two categories:
42
-
43
- 1. Common plugins: Plugins that only include some basic Hooks.
44
-
45
- 2. Project plugins: Different project developments will extend their own Hooks, Config, etc. on the basis of common plugins.
46
-
47
- When using TypeScript, you can import built-in types such as `CliPlugin` to provide correct type inference for plugins.
48
-
49
- ```ts
50
- import type { CliPlugin } from '@modern-js/core';
51
-
52
- const myPlugin: CliPlugin = {
53
- name: 'my-plugin',
54
-
55
- setup() {
56
- const foo = '1';
57
-
58
- return {
59
- afterBuild: () => {},
60
- };
61
- },
62
- };
63
- ```
64
-
65
- The above code is a general-purpose plugin, containing only some basic Hooks. Modern.js supports extending the definition of plugins through generics:
66
-
67
- ```ts
68
- import type { CliPlugin, AppTools } from '@modern-js/app-tools';
69
-
70
- const myPlugin: CliPlugin<AppTools> = {
71
- name: 'my-plugin',
72
-
73
- setup() {
74
- const foo = '1';
75
-
76
- return {
77
- afterBuild: () => {},
78
- };
79
- },
80
- };
81
- ```
82
-
83
- If you look closely at the type `AppTools`, you can see that `AppTools` consists of 3 types.
84
-
85
- ```ts
86
- type AppTools = {
87
- hooks: AppToolsHooks;
88
- userConfig: AppToolsUserConfig;
89
- normalizedConfig: AppToolsNormalizedConfig;
90
- };
91
- ```
92
-
93
- When writing plugins, plugins extend their own types like Hooks on different bases through generic extensions:
94
-
95
- ```ts
96
- // common plugin
97
- import type { CliPlugin } from '@modern-js/core';
98
- import type { MyPluginHook } from 'xxx';
99
-
100
- const myPlugin: CliPlugin<{ hooks: MyPluginHook }> = {};
101
- ```
102
-
103
- ```ts
104
- // extend from app-tools hook
105
- import type { CliPlugin, AppTools } from '@modern-js/app-tools';
106
- import type { MyPluginHook } from 'xxx';
107
-
108
- const myPlugin: CliPlugin<AppTools & { hooks: MyPluginHook }> = {};
109
- ```
110
-
111
- Please refer to [Extending Hooks](/plugin/plugin-system/extend) for detailed explanations.
112
-
113
- ### Plugin Configuration
114
-
115
- **It is recommended to develop plugins in the form of functions**, so that plugins can receive configuration options through function parameters:
116
-
117
- ```ts
118
- import type { CliPlugin } from '@modern-js/core';
119
-
120
- type MyPluginOptions = {
121
- foo: string;
122
- };
123
-
124
- const myPlugin = (options: MyPluginOptions): CliPlugin => ({
125
- name: 'my-plugin',
126
-
127
- setup() {
128
- console.log(options.foo);
129
- },
130
- });
131
- ```
132
-
133
- ### Plugin API
134
-
135
- 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.
136
-
137
- ```ts
138
- import type { CliPlugin } from '@modern-js/core';
139
-
140
- export const myPlugin = (): CliPlugin => ({
141
- name: 'my-plugin',
142
-
143
- setup(api) {
144
- // get user set config
145
- const config = api.useConfigContext();
146
- // get context
147
- const appContext = api.useAppContext();
148
- // get final config
149
- const resolvedConfig = api.useResolvedConfigContext();
150
- },
151
- });
152
- ```
153
-
154
- For more detail [Plugin API](/plugin/plugin-system/plugin-api).
155
-
156
- ### Async setup
157
-
158
- The `setup` function of a CLI plugin can be an asynchronous function, which can execute asynchronous logic during the initialization process.
159
-
160
- ```ts
161
- import type { CliPlugin } from '@modern-js/core';
162
-
163
- export const myPlugin = (): CliPlugin => ({
164
- name: 'my-plugin',
165
-
166
- async setup(api) {
167
- await doSomething();
168
- },
169
- });
170
- ```
171
-
172
- Note that the setup function of the next plugin is not executed until the async setup function of the current plugin has finished. Therefore, you should avoid performing time-consuming asynchronous operations in the setup function to avoid slowing down the startup performance of the CLI.
173
-
174
- ## Adding Plugins
175
-
176
- 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.
177
-
178
- ### Developing Local Plugins
179
-
180
- It is recommended to write local plugins in the `config/plugin` directory and export them using `export default`:
181
-
182
- ```ts title=config/plugin/myPlugin.ts
183
- import type { CliPlugin } from '@modern-js/core';
184
-
185
- export const myPlugin = (): CliPlugin => ({
186
- name: 'my-plugin',
187
-
188
- setup() {
189
- // init plugin
190
- },
191
- });
192
- ```
193
-
194
- register plugin in `modern.config.ts`:
195
-
196
- ```ts title="modern.config.ts"
197
- import { defineConfig } from '@modern-js/app-tools';
198
- import { myPlugin } from './config/plugin/myPlugin';
199
-
200
- export default defineConfig({
201
- plugins: [myPlugin()],
202
- });
203
- ```
204
-
205
- ### Publishing a Plugin on npm
206
-
207
- If you want to publish your Modern.js plugin on npm, it's recommended to use the [Modern.js Module](https://modernjs.dev/module-tools) to manage and build the plugin.
208
-
209
- First, create an empty Modern.js Module project and adjust the package name:
210
-
211
- ```json
212
- {
213
- "name": "my-plugin"
214
- ...
215
- }
216
- ```
217
-
218
- Create plugin main file:
219
-
220
- ```ts title=src/index.ts
221
- import type { CliPlugin } from '@modern-js/core';
222
-
223
- export const myPlugin = (): CliPlugin => ({
224
- name: 'my-plugin',
225
-
226
- setup() {
227
- // plugin init
228
- },
229
- });
230
- ```
231
-
232
- 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`:
233
-
234
- ```ts title="modern.config.ts"
235
- import { defineConfig } from '@modern-js/app-tools';
236
- import { myPlugin } from 'my-plugin';
237
-
238
- export default defineConfig({
239
- plugins: [myPlugin()],
240
- });
241
- ```
242
-
243
- 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,95 +0,0 @@
1
- ---
2
- sidebar_position: 1
3
- ---
4
-
5
- # Introduction
6
-
7
- ## Modern.js Plugin System
8
-
9
- Modern.js offers a comprehensive plugin system with a complete lifecycle. Plugins can be used to extend different stages of project operation, request handling, rendering, and more.
10
-
11
- ## Usage
12
-
13
- Plugins must be explicitly registered in the configuration file to be effective. When you need to add plugins to Modern.js, you can configure them in the `[plugins](/configure/app/plugins.html)` field:
14
-
15
- ```ts title="edenx.config.ts"
16
- // an example for bff
17
- import { appTools, defineConfig } from '@modern-js/app-tools';
18
- import { bffPlugin } from '@modern-js/plugin-bff';
19
-
20
- export default defineConfig({
21
- plugins: [appTools(), bffPlugin()],
22
- });
23
- ```
24
-
25
- :::note
26
- Note that this configuration only supports adding Modern.js plugins and does not support adding Webpack plugins.
27
- :::
28
-
29
- ## Official Plugins
30
-
31
- Modern.js offers a range of official plugins, which are integrated with the Modern.js generator. All the functionalities of the official plugins can be enabled by executing the `new` command. For instance, to enable the BFF (Backend For Frontend) feature:
32
-
33
- ```bash
34
- $ npx modern new
35
- ? Please select the operation you want: Enable Features
36
- ? Please select the feature name: (Use arrow keys)
37
- Enable Tailwind CSS
38
- ❯ Enable BFF
39
- Enable SSG
40
- Enable Micro Frontend
41
- ```
42
-
43
- After the selection is completed, the Modern.js generator will automatically install the corresponding plugins and third-party dependencies. Upon completion of the installation, you will see:
44
-
45
- ```bash
46
- [INFO] Dependency automatic installation succeeded
47
-
48
- [INFO] install plugin dependencies success!add follow code to modern.config.ts :
49
-
50
- import { bffPlugin } from '@modern-js/plugin-bff';
51
- import { expressPlugin } from '@modern-js/plugin-express';
52
-
53
- export default defineConfig({
54
- ...,
55
- plugins: [..., bffPlugin(), expressPlugin()],
56
- });
57
- ```
58
-
59
- At this point, you can add the plugin to the configuration file according to the output in the console.
60
-
61
- ## Composition
62
-
63
- The Modern.js plugin system is mainly divided into three parts: Hook model, Manager, and Context Sharing Mechanism.
64
-
65
- - The Hook model is used to determine the execution logic of the current Hook.
66
- - The Manager controls the execution and scheduling of Hooks.
67
- - The Context Sharing Mechanism is used to pass information between different Hooks.
68
-
69
- Currently, Modern.js offers several different Hook models: **Pipeline, Waterfall, Workflow**.
70
-
71
- :::note
72
- Subsequent chapters will introduce the execution methods of each model in detail.
73
- :::
74
-
75
- Based on the Hook model and Manager, Modern.js exposes three sets of plugins: CLI, Runtime, and Server.
76
-
77
- 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.
78
-
79
- ## What Plugins Can Do
80
-
81
- 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 develop plugins to extend more functionality and adapt to complex scenarios, including but not limited to:
82
-
83
- - Registering commands
84
- - Modifying Modern.js configuration and validation schema
85
- - Modifying compilation configurations for Webpack/Babel/Less/Sass/Tailwind CSS/...
86
- - Modifying the React components/elements to be rendered at runtime
87
- - Modifying page routing
88
- - Modifying server routing
89
- - Customizing console output
90
- - Customizing dynamic HTML templates
91
- - Customizing Node.js server frameworks
92
- - Customizing React component client/server rendering
93
- - ...
94
-
95
- 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,16 +0,0 @@
1
- ---
2
- sidebar_position: 1
3
- ---
4
-
5
- # Lifecycle
6
-
7
- Modern.js application has a complete lifecycle, including CLI, Server Side and Runtime three stages.
8
-
9
- Modern.js lifecycle is as follows:
10
-
11
- :::note
12
- The rectangle of the pink box represents the plugin hook provided by the Modern.js, and the light yellow base color ellipse represents the linkage point with the next stage.
13
-
14
- :::
15
-
16
- ![lifecycle](https://lf3-static.bytednsdoc.com/obj/eden-cn/nuvjhpqnuvr/modern-website/life-cycle.svg)
@@ -1,138 +0,0 @@
1
- ---
2
- sidebar_position: 6
3
- ---
4
-
5
- # Plugin API
6
-
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
-
9
- ```ts
10
- import type { CliPlugin } from '@modern-js/core';
11
-
12
- export const myPlugin = (): CliPlugin => ({
13
- name: 'my-plugin',
14
-
15
- setup(api) {
16
- // get user config
17
- const config = api.useConfigContext();
18
- // get plugin context
19
- const appContext = api.useAppContext();
20
- // get resolved config
21
- const resolvedConfig = api.useResolvedConfigContext();
22
- },
23
- });
24
- ```
25
-
26
- ## API
27
-
28
- ### useConfigContext
29
-
30
- Used to retrieve the original configuration of the application.
31
-
32
- ```ts
33
- const useConfigContext: () => UserConfig;
34
-
35
- interface UserConfig {
36
- source?: SourceConfig;
37
- output?: OutputConfig;
38
- server?: ServerConfig;
39
- deploy?: DeployConfig;
40
- // ...other fields
41
- }
42
- ```
43
-
44
- Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
45
-
46
- :::tip
47
- This method returns a read-only configuration and cannot be modified. If you need to modify the configuration, please use [config hook](/plugin/plugin-system/hook-list.html#config).
48
- :::
49
-
50
- ### useResolvedConfigContext
51
-
52
- Used to retrieve the final configuration after parsing.
53
-
54
- ```ts
55
- const useResolvedConfigContext: () => NormalizedConfig;
56
-
57
- interface NormalizedConfig {
58
- source: NormalizedSourceConfig;
59
- output: NormalizedOutputConfig;
60
- server: NormalizedServerConfig;
61
- deploy: NormalizedDeployConfig;
62
- _raw: UserConfig; // the original user config
63
- // ...other fields
64
- }
65
- ```
66
-
67
- Please refer to [Configuration](/configure/app/usage) for the specific meanings of configuration fields.
68
-
69
- :::tip
70
- This method returns a read-only configuration and cannot be modified. If you need to modify the configuration, please use [config hook](/plugin/plugin-system/hook-list.html#config).
71
- :::
72
-
73
- ### useAppContext
74
-
75
- Used to retrieve the runtime context of the application.
76
-
77
- ```ts
78
- const useAppContext: () => IAppContext;
79
-
80
- interface IAppContext {
81
- /** Root directory of the current project */
82
- appDirectory: string;
83
- /** Source code directory */
84
- srcDirectory: string;
85
- /** Directory for output files */
86
- distDirectory: string;
87
- /** Directory for shared modules */
88
- sharedDirectory: string;
89
- /** Directory for framework temp files */
90
- internalDirectory: string;
91
- /** node_modules directory */
92
- nodeModulesDirectory: string;
93
- /** Path to the configuration file */
94
- configFile: string | false;
95
- /** IPv4 address of the current machine */
96
- ip?: string;
97
- /** Port number of the development server */
98
- port?: number;
99
- /** Name of the current project's package.json */
100
- packageName: string;
101
- /** Currently registered plugins */
102
- plugins: any[];
103
- /** Information for entry points */
104
- entrypoints: Entrypoint[];
105
- /** Information for server routes */
106
- serverRoutes: ServerRoute[];
107
- /** Tools type of the current project */
108
- toolsType?: 'app-tools' | 'module-tools';
109
- /** Type of the bundler being used */
110
- bundlerType?: 'webpack' | 'rspack' | 'esbuild';
111
- }
112
- ```
113
-
114
- :::tip
115
- Some fields in the AppContext are dynamically set and will change as the program runs. Therefore, when plugins read these fields at different times, they may get different values.
116
- :::
117
-
118
- ### useHookRunners
119
-
120
- Used to retrieve the executor of Hooks and trigger the execution of specific Hooks.
121
-
122
- ```ts
123
- import type { CliPlugin } from '@modern-js/core';
124
-
125
- export const myPlugin = (): CliPlugin => ({
126
- name: 'my-plugin',
127
-
128
- async setup(api) {
129
- const hookRunners = api.useHookRunners();
130
- // invoke afterBuild Hook
131
- await hookRunners.afterBuild();
132
- },
133
- });
134
- ```
135
-
136
- :::tip
137
- Please avoid executing the built-in hooks, as it may break the internal execution logic of the framework.
138
- :::