@modern-js/main-doc 2.17.0 → 2.17.2-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/en/apis/app/hooks/src/index_.mdx +1 -1
  3. package/docs/en/apis/app/runtime/core/bootstrap.mdx +1 -1
  4. package/docs/en/community/blog/_category_.json +6 -0
  5. package/docs/en/{blog/index.md → community/blog/overview.md} +3 -1
  6. package/docs/en/components/convention-routing-movitation.mdx +0 -0
  7. package/docs/en/components/routes-practice.mdx +0 -0
  8. package/docs/en/configure/app/output/ssg.mdx +3 -1
  9. package/docs/en/configure/app/source/entries.mdx +2 -0
  10. package/docs/en/configure/app/tools/tailwindcss.mdx +30 -2
  11. package/docs/en/configure/app/usage.mdx +35 -0
  12. package/docs/en/guides/advanced-features/rspack-start.mdx +1 -2
  13. package/docs/en/guides/advanced-features/ssg.mdx +1 -1
  14. package/docs/en/guides/advanced-features/testing.mdx +1 -1
  15. package/docs/en/guides/basic-features/routes.mdx +20 -1
  16. package/docs/en/guides/concept/entries.mdx +35 -13
  17. package/docs/en/guides/topic-detail/framework-plugin/hook-list.mdx +18 -12
  18. package/docs/en/guides/topic-detail/generator/plugin/api/info/isFileExit.mdx +2 -2
  19. package/docs/zh/apis/app/hooks/src/index_.mdx +1 -1
  20. package/docs/zh/apis/app/runtime/core/bootstrap.mdx +1 -1
  21. package/docs/zh/community/blog/_category_.json +6 -0
  22. package/docs/zh/{blog/index.md → community/blog/overview.md} +6 -4
  23. package/docs/zh/components/convention-routing-motivation.mdx +0 -0
  24. package/docs/zh/components/routes-practice.mdx +0 -0
  25. package/docs/zh/configure/app/output/ssg.mdx +3 -1
  26. package/docs/zh/configure/app/source/entries.mdx +2 -0
  27. package/docs/zh/configure/app/tools/tailwindcss.mdx +31 -3
  28. package/docs/zh/configure/app/usage.mdx +35 -0
  29. package/docs/zh/guides/advanced-features/rspack-start.mdx +1 -2
  30. package/docs/zh/guides/advanced-features/ssg.mdx +1 -1
  31. package/docs/zh/guides/advanced-features/testing.mdx +1 -1
  32. package/docs/zh/guides/basic-features/data-fetch.mdx +9 -0
  33. package/docs/zh/guides/basic-features/routes.mdx +19 -17
  34. package/docs/zh/guides/concept/entries.mdx +41 -21
  35. package/docs/zh/guides/topic-detail/framework-plugin/hook-list.mdx +18 -12
  36. package/docs/zh/guides/topic-detail/generator/plugin/api/info/isFileExit.mdx +2 -2
  37. package/modern.config.ts +9 -10
  38. package/package.json +5 -5
  39. package/docs/zh/blog/updates/_category_.json +0 -5
  40. /package/docs/en/{about → community}/contributing-guide.mdx +0 -0
  41. /package/docs/en/{about → community}/releases.mdx +0 -0
  42. /package/docs/en/{about → community}/showcase.mdx +0 -0
  43. /package/docs/en/{about → community}/team.mdx +0 -0
  44. /package/docs/zh/{blog/updates → community/blog}/2022-0708-updates.md +0 -0
  45. /package/docs/zh/{blog/updates → community/blog}/2022-0910-updates.md +0 -0
  46. /package/docs/zh/{blog/updates → community/blog}/v2-release-note.mdx +0 -0
  47. /package/docs/zh/{about → community}/contributing-guide.mdx +0 -0
  48. /package/docs/zh/{about → community}/releases.mdx +0 -0
  49. /package/docs/zh/{about → community}/showcase.mdx +0 -0
  50. /package/docs/zh/{about → community}/team.mdx +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @modern-js/main-doc
2
2
 
3
+ ## 2.17.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fc76194: chore: comment the doc for runtime and server plugin hooks
8
+ chore: 注释 runtime 和 server 插件钩子文档
9
+ - 7d899fb: fix: typo isFileExist
10
+
11
+ fix: isFileExist 拼写错误
12
+
13
+ - @modern-js/builder-doc@2.17.1
14
+
3
15
  ## 2.17.0
4
16
 
5
17
  ### Patch Changes
@@ -4,7 +4,7 @@ sidebar_position: 4
4
4
  ---
5
5
  # index.[tj]s
6
6
 
7
- Entry identifier if App want use custom entry. In most case, [`App.[tj]sx`](/apis/app/hooks/src/app) hook file can already meet our needs.
7
+ Entry identifier if App want use custom bootstrap. In most case, [`App.[tj]sx`](/apis/app/hooks/src/app) hook file can already meet our needs.
8
8
 
9
9
  When we need to add custom behavior before `bootstrap` or completely take over the webpack entry, we can place `index.[tj]s` in `src/` or entry directory. The following are discussed in two cases:
10
10
 
@@ -3,7 +3,7 @@ title: bootstrap
3
3
  ---
4
4
  # bootstrap
5
5
 
6
- Used to start and mount App, usually without manual calls. This API is only required when using [Custom App](/guides/concept/entries#自定义-app).
6
+ Used to start and mount App, usually without manual calls. This API is only required when using [Custom Bootstrap](/guides/concept/entries#custom-bootstrap).
7
7
 
8
8
  ## Usage
9
9
 
@@ -0,0 +1,6 @@
1
+ {
2
+ "label": "Blog",
3
+ "position": 4,
4
+ "collapsed": false,
5
+ "collapsible": false
6
+ }
@@ -2,7 +2,9 @@
2
2
  sidebar_position: 1
3
3
  ---
4
4
 
5
- # Blog
5
+ # Overview
6
+
7
+ Welcome to the Modern.js blog!
6
8
 
7
9
  You can find the latest news about Modern.js here.
8
10
 
File without changes
@@ -163,7 +163,9 @@ You can set this to disable the default behavior of a client-side route:
163
163
  ```js
164
164
  export default defineConfig({
165
165
  output: {
166
- preventDefault: ['/user'],
166
+ ssg: {
167
+ preventDefault: ['/user'],
168
+ },
167
169
  },
168
170
  });
169
171
  ```
@@ -13,6 +13,7 @@ type Entries = Record<
13
13
  | {
14
14
  entry: string;
15
15
  disableMount?: boolean;
16
+ customBootstrap?: string;
16
17
  }
17
18
  >;
18
19
  ```
@@ -81,6 +82,7 @@ When the value is `Object`, the following properties can be configured:
81
82
 
82
83
  - `entry`: `string`, entry file path.
83
84
  - `disableMount`: `boolean = false`, turn off the entry-scanning behavior of Modern.js.
85
+ - `customBootstrap`: `string = ''`, [Custom Bootstrap](/guides/concept/entries#custom-bootstrap) file path。
84
86
 
85
87
  ```ts title="modern.config.ts"
86
88
  import { defineConfig } from '@modern-js/app-tools';
@@ -24,9 +24,37 @@ const tailwind = {
24
24
  };
25
25
  ```
26
26
 
27
- When the value is of type `Object`, rhe configuration corresponding to [TailwindCSS](https://tailwindcss.com/docs/configuration) is merged with the default configuration through `Object.assign`.
27
+ ### Function Type
28
28
 
29
- When the value is of type `Function`, the object returned by the function is merged with the default configuration by `Object.assign`.
29
+ When `tools.tailwindcss`'s type is Function, the default tailwindcss config will be passed in as the first parameter, the config object can be modified directly, or a value can be returned as the final result.
30
+
31
+ ```ts title="modern.config.ts"
32
+ export default {
33
+ tools: {
34
+ tailwindcss(config) {
35
+ config.content.push('./some-folder/**/*.{js,ts}');
36
+ },
37
+ },
38
+ };
39
+ ```
40
+
41
+ ### Object Type
42
+
43
+ When `tools.tailwindcss`'s type is `Object`, the config will be shallow merged with default config by `Object.assign`.
44
+
45
+ ```ts title="modern.config.ts"
46
+ export default {
47
+ tools: {
48
+ tailwindcss: {
49
+ plugins: [
50
+ require('@tailwindcss/forms'),
51
+ require('@tailwindcss/aspect-ratio'),
52
+ require('@tailwindcss/typography'),
53
+ ],
54
+ },
55
+ },
56
+ };
57
+ ```
30
58
 
31
59
  ### Limitations
32
60
 
@@ -43,6 +43,15 @@ export default defineConfig({
43
43
  });
44
44
  ```
45
45
 
46
+ When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify `<'rspack'>` generic type for `defineConfig`:
47
+
48
+ ```diff title=modern.config.ts
49
+ - export default defineConfig({
50
+ + export default defineConfig<'rspack'>({
51
+ //...
52
+ });
53
+ ```
54
+
46
55
  ### modern.config.js
47
56
 
48
57
  If you are developing a non-TypeScript project, you can use the configuration file in .js format:
@@ -242,3 +251,29 @@ const mergedConfig = {
242
251
  },
243
252
  };
244
253
  ```
254
+
255
+ ## Configuration Type
256
+
257
+ Modern.js exports `AppUserConfig` type, which corresponds to the type of Modern.js configuration object:
258
+
259
+ ```ts title="modern.config.ts"
260
+ import type { AppUserConfig } from '@modern-js/app-tools';
261
+
262
+ const config: AppUserConfig = {
263
+ tools: {
264
+ webpack: {},
265
+ },
266
+ };
267
+ ```
268
+
269
+ When using Rspack as the bundler, due to some differences in configuration types between webpack and Rspack, you need to specify `<'rspack'>` generic type for `defineConfig`:
270
+
271
+ ```ts title="modern.config.ts"
272
+ import type { AppUserConfig } from '@modern-js/app-tools';
273
+
274
+ const config: AppUserConfig<'rspack'> = {
275
+ tools: {
276
+ rspack: {},
277
+ },
278
+ };
279
+ ```
@@ -27,8 +27,7 @@ When using Rspack as the bundler, the following Features are temporarily unavail
27
27
 
28
28
  - Micro Frontend
29
29
  - Storybook Devtool
30
- - Server Side Rendering + Conventional Routing
31
- - Static Site Generation + Conventional Routing
30
+ - The usage of [useLoader](/guides/basic-features/data-fetch.html) in Client Side Rendering
32
31
 
33
32
  :::
34
33
 
@@ -86,7 +86,7 @@ After executing `pnpm run serve` to start the project, visit the page in the Net
86
86
 
87
87
  ### Self-controlled Routing
88
88
 
89
- **Self-controlled routing** is a custom routing through component code, which requires the application to run to obtain accurate routing information. Therefore, the SSG function cannot be used out of the box. At this time, the user needs to inform the Modern.js framework in advance which routes need to enable the SSG.
89
+ **Self-controlled routing** is a routing through component code, which requires the application to run to obtain accurate routing information. Therefore, the SSG function cannot be used out of the box. At this time, the user needs to inform the Modern.js framework in advance which routes need to enable the SSG.
90
90
 
91
91
  For example, there is the following code, which contains multiple routes. When setting `output.ssg` to `true`, only the entry route '/' will be rendered by default:
92
92
 
@@ -4,7 +4,7 @@ title: Testing
4
4
  ---
5
5
  # Testing
6
6
 
7
- Modern.js inherits the testing capabilities of [Jest](https://jestjs.io/) by default.
7
+ Modern.js integrates the testing capabilities of [Jest](https://jestjs.io/) by default.
8
8
 
9
9
  First need to execute `pnpm run new` enable [unit test/integration test] features:
10
10
 
@@ -367,6 +367,22 @@ To further improve the user experience and reduce time of loading, Modern.js sup
367
367
  - `intent`, the value we recommend for most scenarios, will automatically start loading the corresponding resources and the data defined in the data loader when you mouse over the Link, and will automatically unload it when the mouse is moved away. In our tests, even a direct click can reduce the loading time by about 200ms.
368
368
  - `render`, when the Link component renders, it will load the corresponding resources and the data defined in the data loader.
369
369
 
370
+ #### FAQ
371
+
372
+ 1. What is the difference between using `render` and not split chunks based on routes?
373
+
374
+ - With `render` you can specify which routes are loaded on the first screen, and you can control the rendering so that Link components are rendered only when they are in the visible area.
375
+ - With `render`, static resources are loaded only when they are idle and do not hog the network with first-screen static resources.
376
+ - When using server side rendering, data is also prefetched.
377
+
378
+ import Motivation from '@site-docs/components/convention-routing-motivation'
379
+
380
+ <Motivation/>
381
+
382
+ import Practice from '@site-docs/components/routes-practice'
383
+
384
+ <Practice/>
385
+
370
386
  ## Self-controlled routing
371
387
 
372
388
  With `src/App.tsx` as the agreed entry, Modern.js will not do additional operations with multiple routes, developers can use the React Router 6 API for development by themselves, for example:
@@ -388,9 +404,12 @@ export default () => {
388
404
 
389
405
  :::note
390
406
  Modern.js has a series of resource loading and rendering optimizations to the default convention-based routing, and provides out-of-the-box SSR capabilities, when using self-directed routing, need to be packaged by the developer, and it is recommended that developers use convention-based routing.
391
-
392
407
  :::
393
408
 
409
+ use self-controller routing, if the developer turns off the [`runtime.router`](/configure/app/runtime/router) configuration and uses `react-router-dom` directly, then you need to wrap the `Provider` according to the React Router documentation.
410
+
411
+ ```tsx title="src/App.tsx"
412
+
394
413
  ## Other
395
414
 
396
415
  By default, Modern.js turn on the built-in routing scheme, React Router.
@@ -98,27 +98,49 @@ Framework mode refers to the need to use the capabilities of the Modern.js frame
98
98
 
99
99
  #### Conventional Routing
100
100
 
101
- If there is a `routes/` directory in the entry, Modern.js will scan the files under `routes/` at startup, and automatically generate client-side routes (react-router) based on file conventions.
101
+ If there is a `routes/` directory in the entry, Modern.js will scan the files under `routes/` at startup, and automatically generate client-side routes (react-router) based on file conventions. For example:
102
102
 
103
- For details, please refer to [routing](/guides/basic-features/routes).
103
+ ```bash
104
+ .
105
+ ├── src
106
+ │ └── routes
107
+ │ ├── layout.tsx
108
+ │ └── page.tsx
109
+ ```
104
110
 
105
- #### Custom Routing
111
+ For details, please refer to [routing](/guides/basic-features/routes#conventional-routing).
112
+
113
+ #### Self-controlled Routing
106
114
 
107
115
  If there is an `App.[jt]sx?` file in the entry, the developer can freely set the client route in this file, or not set the client route.
108
116
 
109
- For details, please refer to [routing](/guides/basic-features/routes).
117
+ ```tsx
118
+ import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
119
+
120
+ export default () => {
121
+ return (
122
+ <BrowserRouter>
123
+ <Routes>
124
+ <Route index element={<div>index</div>} />
125
+ <Route path="about" element={<div>about</div>} />
126
+ </Routes>
127
+ </BrowserRouter>
128
+ );
129
+ };
130
+ ```
110
131
 
111
- #### Custom App
132
+ For details, please refer to [routing](/guides/basic-features/routes#self-controlled-routing).
112
133
 
113
- If there is an `index.[jt]sx` file in the entry, and when the file exports functions by default, Modern.js will still generate the code wrapped by createApp according to the runtime settings. In the rendering process, the component wrapped by createApp is passed as a parameter to the function exported by the index file, so that developers can customize the component to be mounted on the DOM node, or add custom behavior before mounting. For example:
134
+ #### Custom Bootstrap
114
135
 
115
- ```tsx
116
- import ReactDOM from 'react-dom/client';
117
- import { bootstrap } from '@modern-js/runtime';
136
+ If there is an `index.[jt]sx` file in the entry, and when the file defaults to exporting functions, Modern.js will pass the default bootstrap function as an imported parameter, and replace the default bootstrap with the exported function, so that developers can customize Mounting components to DOM nodes, or adding custom behavior before mounting. E.g:
118
137
 
119
- export default (App: React.ComponentType) => {
138
+ ```tsx
139
+ export default (App: React.ComponentType, bootstrap: () => void) => {
120
140
  // do something before bootstrap...
121
- bootstrap(App, 'root', undefined, ReactDOM);
141
+ initSomething().then(() => {
142
+ bootstrap();
143
+ })
122
144
  };
123
145
  ```
124
146
 
@@ -170,9 +192,9 @@ import App from './App';
170
192
  ReactDOM.render(<App />, document.getElementById('root'));
171
193
  ```
172
194
 
173
- Modern.js **not recommended** to use this method, this method loses some capabilities of the framework, such as the `runtime` configuration in the **`modern.config.js` file will no longer take effect**. But this method will be very useful when the project is migrated from other frameworks to Modern.js, such as CRA, or webpack that is manually built by yourself.
195
+ Modern.js **not recommended** new project to use this method, this method loses some capabilities of the framework, such as the `runtime` configuration in the **`modern.config.js` file will no longer take effect**. But this method will be very useful when the project is migrated from other frameworks to Modern.js, such as CRA, or webpack that is manually built by yourself.
174
196
 
175
- ## Custom Entry
197
+ ## Specify Entry Using Configuration
176
198
 
177
199
  Most existing projects are not built according to the directory convention of Modern.js. If you want to change to the directory structure agreed by Modern.js, there will be a certain migration cost.
178
200
 
@@ -611,7 +611,7 @@ export default (): CliPlugin => ({
611
611
 
612
612
  This adds a new Script tag to the HTML template.
613
613
 
614
- ## Server
614
+ {/* ## Server
615
615
 
616
616
  :::note
617
617
  The Server plugin is currently not fully opened, and the API is not guaranteed to be stable. Use with caution.
@@ -691,7 +691,7 @@ export default (): ServerPlugin => ({
691
691
  };
692
692
  },
693
693
  });
694
- ```
694
+ ```*/}
695
695
 
696
696
  ## Runtime
697
697
 
@@ -699,7 +699,7 @@ export default (): ServerPlugin => ({
699
699
  The Runtime plugin is currently not fully opened, and the API is not guaranteed to be stable. Use with caution.
700
700
  :::
701
701
 
702
- The Runtime plugin is mainly used for developers to modify the components and elements that need to be rendered, and customize the rendering process on the server and client side.
702
+ The Runtime plugin is mainly used for developers to modify the component that need to be rendered.
703
703
 
704
704
  ### `init`
705
705
 
@@ -732,23 +732,29 @@ export default (): Plugin => ({
732
732
  - Type: `Pipeline<{ App: React.ComponentType<any>; }, React.ComponentType<any>>`
733
733
  - Usage Example:
734
734
 
735
+ :::note
736
+ When using the hoc hook, you need to copy the static properties of the original App component to the new component and pass through the props.
737
+ :::
738
+
735
739
  ```ts
736
740
  import { createContext } from 'react';
737
741
  import type { Plugin } from '@modern-js/runtime';
742
+ import hoistNonReactStatics from 'hoist-non-react-statics';
738
743
 
739
744
  export default (): Plugin => ({
740
745
  setup(api) {
741
746
  const FooContext = createContext('');
742
747
  return {
743
748
  hoc({ App }, next) {
749
+ const AppWrapper = (props: any) => {
750
+ return (
751
+ <FooContext.Provider store={'test'}>
752
+ <App {...props} />
753
+ </FooContext.Provider>
754
+ );
755
+ };
744
756
  return next({
745
- App: (props: any) => {
746
- return (
747
- <FooContext.Provider store={'test'}>
748
- <App {...props} />
749
- </FooContext.Provider>
750
- );
751
- },
757
+ App: hoistNonReactStatics(AppWrapper, App)
752
758
  });
753
759
  },
754
760
  };
@@ -756,7 +762,7 @@ export default (): Plugin => ({
756
762
  });
757
763
  ```
758
764
 
759
- ### `provide`
765
+ {/* ### `provide`
760
766
 
761
767
  - Function: Modifies the Elements that need to be rendered.
762
768
  - Execution Stage: Rendering (SSR/CSR).
@@ -828,4 +834,4 @@ export default (): Plugin => ({
828
834
  };
829
835
  },
830
836
  });
831
- ```
837
+ ``` */}
@@ -2,7 +2,7 @@
2
2
  sidebar_position: 2
3
3
  ---
4
4
 
5
- # isFileExit
5
+ # isFileExist
6
6
 
7
7
  Determine if the file exists.
8
8
 
@@ -12,7 +12,7 @@ Its type is defined as:
12
12
 
13
13
  ```ts
14
14
  export interface IPluginContext {
15
- isFileExit: (fileName: string) => Promise<boolean>;
15
+ isFileExist: (fileName: string) => Promise<boolean>;
16
16
  ...
17
17
  }
18
18
  ```
@@ -4,7 +4,7 @@ sidebar_position: 4
4
4
  ---
5
5
  # index.[tj]s
6
6
 
7
- 应用项目自定义路由入口标识。
7
+ 应用项目入口标识。
8
8
 
9
9
  通常情况下 [`src/App.[tj]sx, src/[entry]/App.[tj]sx`](/apis/app/hooks/src/app) 钩子文件已经能满足我们的需求,当我们需要在 `bootstrap` 之前添加自定义行为或者完全接管 webpack 打包入口时,可以在 `src` 或者入口目录下放置 `index.[tj]s`。 下面有分两种情况进行讨论:
10
10
 
@@ -3,7 +3,7 @@ title: bootstrap
3
3
  ---
4
4
  # bootstrap
5
5
 
6
- 用于启动和挂载应用,通常情况下不做手动调用。只有在使用[自定义 App](/guides/concept/entries#自定义-app) 时,才需要使用该 API。
6
+ 用于启动和挂载应用,通常情况下不做手动调用。只有在使用[自定义 Bootstrap](/guides/concept/entries#自定义-bootstrap) 时,才需要使用该 API。
7
7
 
8
8
  ## 使用姿势
9
9
 
@@ -0,0 +1,6 @@
1
+ {
2
+ "label": "博客",
3
+ "position": 4,
4
+ "collapsed": false,
5
+ "collapsible": false
6
+ }
@@ -2,7 +2,9 @@
2
2
  sidebar_position: 1
3
3
  ---
4
4
 
5
- # 博客
5
+ # 总览
6
+
7
+ 欢迎来到 Modern.js 博客频道!
6
8
 
7
9
  在这里,你可以了解到 Modern.js 的最新进展和技术分享。
8
10
 
@@ -18,7 +20,7 @@ Modern.js 是字节跳动 Web Infra 团队开源的一套 Web 工程体系。在
18
20
 
19
21
  在这篇文章里,我们会和大家一起聊一聊 Modern.js 在过去一年多时间里的变化。
20
22
 
21
- [了解更多 →](/blog/updates/v2-release-note)
23
+ [了解更多 →](/community/blog/v2-release-note)
22
24
 
23
25
  ---
24
26
 
@@ -56,7 +58,7 @@ Modern.js 9 ~ 10 月的最新版本为 v1.21.0,本双月的主要更新有:
56
58
  - **支持 pnpm v7**:完成框架对 pnpm v7 的支持。
57
59
  - **服务端增加 Typescript 作为 ts 文件编译器**。
58
60
 
59
- [了解更多 →](/blog/updates/2022-0910-updates)
61
+ [了解更多 →](/community/blog/2022-0910-updates)
60
62
 
61
63
  ---
62
64
 
@@ -71,4 +73,4 @@ Modern.js 7 ~ 8 月的最新版本为 v1.17.0,本双月的主要更新有:
71
73
  - **模块工程支持 bundle 构建**:模块工程类型的项目,支持对产物做 bundle 构建。
72
74
  - **Reduck v1.1**:发布 Reduck v1.1,使用文档全面更新。
73
75
 
74
- [了解更多 →](/blog/updates/2022-0708-updates)
76
+ [了解更多 →](/community/blog/2022-0708-updates)
File without changes
@@ -163,7 +163,9 @@ export default defineConfig({
163
163
  ```js
164
164
  export default defineConfig({
165
165
  output: {
166
- preventDefault: ['/user'],
166
+ ssg: {
167
+ preventDefault: ['/user'],
168
+ },
167
169
  },
168
170
  });
169
171
  ```
@@ -13,6 +13,7 @@ type Entries = Record<
13
13
  | {
14
14
  entry: string;
15
15
  disableMount?: boolean;
16
+ customBootstrap?: string;
16
17
  }
17
18
  >;
18
19
  ```
@@ -83,6 +84,7 @@ export default defineConfig({
83
84
 
84
85
  - `entry`:`string`,入口文件路径。
85
86
  - `disableMount`:`boolean = false`,关闭 Modern.js 自动生成入口代码的行为。
87
+ - `customBootstrap`: `string = ''`,指定[自定义 Bootstrap](/guides/concept/entries#自定义-bootstrap) 的文件路径。
86
88
 
87
89
  ```ts title="modern.config.ts"
88
90
  import { defineConfig } from '@modern-js/app-tools';
@@ -26,12 +26,40 @@ const tailwind = {
26
26
 
27
27
  对应 [TailwindCSS](https://tailwindcss.com/docs/configuration) 的配置。
28
28
 
29
- 当值为 `Object` 类型时,与默认配置通过 `Object.assign` 合并。
29
+ ### Function 类型
30
30
 
31
- 当值为 `Function` 类型时,函数返回的对象与默认配置通过 `Object.assign` 合并。
31
+ `tools.tailwindcss` Function 类型时,默认配置会作为第一个参数传入,你可以直接修改配置对象,也可以返回一个值作为最终结果:
32
+
33
+ ```ts title="modern.config.ts"
34
+ export default {
35
+ tools: {
36
+ tailwindcss(config) {
37
+ config.content.push('./some-folder/**/*.{js,ts}');
38
+ },
39
+ },
40
+ };
41
+ ```
42
+
43
+ ### Object 类型
44
+
45
+ 当 `tools.tailwindcss` 的值为 `Object` 类型时,会与默认配置通过 `Object.assign` 浅合并。
46
+
47
+ ```ts title="modern.config.ts"
48
+ export default {
49
+ tools: {
50
+ tailwindcss: {
51
+ plugins: [
52
+ require('@tailwindcss/forms'),
53
+ require('@tailwindcss/aspect-ratio'),
54
+ require('@tailwindcss/typography'),
55
+ ],
56
+ },
57
+ },
58
+ };
59
+ ```
32
60
 
33
61
  ### 限制
34
62
 
35
63
  注意,该配置中不允许使用 `theme` 配置项,否则会构建失败。在 Modern.js 中,请使用 [source.designSystem](/configure/app/source/design-system) 作为 `Tailwind CSS Theme` 配置。
36
64
 
37
- 其他的使用方式和 Tailwind CSS 一致: [快速传送门](https://tailwindcss.com/docs/configuration)。
65
+ 其他配置的使用方式和 Tailwind CSS 一致,请参考 [tailwindcss - Configuration](https://tailwindcss.com/docs/configuration)。
@@ -43,6 +43,15 @@ export default defineConfig({
43
43
  });
44
44
  ```
45
45
 
46
+ 当你使用 Rspack 作为打包工具时,由于 webpack 和 Rspack 的配置类型存在一些差异,需要为 `defineConfig` 指定 `<'rspack'>` 泛型:
47
+
48
+ ```diff title=modern.config.ts
49
+ - export default defineConfig({
50
+ + export default defineConfig<'rspack'>({
51
+ // ...
52
+ });
53
+ ```
54
+
46
55
  ### modern.config.js
47
56
 
48
57
  如果你在开发一个非 TypeScript 项目,可以使用 .js 格式的配置文件:
@@ -242,3 +251,29 @@ const mergedConfig = {
242
251
  },
243
252
  };
244
253
  ```
254
+
255
+ ## 配置类型定义
256
+
257
+ Modern.js 导出了 `AppUserConfig` 类型,对应 Modern.js 配置对象的类型:
258
+
259
+ ```ts title="modern.config.ts"
260
+ import type { AppUserConfig } from '@modern-js/app-tools';
261
+
262
+ const config: AppUserConfig = {
263
+ tools: {
264
+ webpack: {},
265
+ },
266
+ };
267
+ ```
268
+
269
+ 当你使用 Rspack 作为打包工具时,由于 webpack 和 Rspack 的配置类型存在一些差异,需要为 `AppUserConfig` 指定 `<'rspack'>` 泛型:
270
+
271
+ ```ts title="modern.config.ts"
272
+ import type { AppUserConfig } from '@modern-js/app-tools';
273
+
274
+ const config: AppUserConfig<'rspack'> = {
275
+ tools: {
276
+ rspack: {},
277
+ },
278
+ };
279
+ ```
@@ -28,8 +28,7 @@ import InitRspackApp from '@site-docs/components/init-rspack-app';
28
28
 
29
29
  - 微前端(Micro Frontend)
30
30
  - Storybook 调试
31
- - 同时使用服务端渲染(SSR)和约定式路由的场景
32
- - 同时使用静态站点生成(SSG)和约定式路由的场景
31
+ - 客户端渲染(CSR)使用 [useLoader](/guides/basic-features/data-fetch.html)
33
32
 
34
33
  :::
35
34
 
@@ -86,7 +86,7 @@ export default defineConfig({
86
86
 
87
87
  ### 在自控式路由中使用
88
88
 
89
- **自控式路由**是通过组件代码自定义路由,需要应用运行起来才能获取准确的路由信息。因此,无法开箱即用的使用 SSG 功能。此时需要用户提前告知 Modern.js 框架,哪些路由需要开启 SSG 功能。
89
+ **自控式路由**是通过组件代码定义路由,需要应用运行起来才能获取准确的路由信息。因此,无法开箱即用的使用 SSG 功能。此时需要用户提前告知 Modern.js 框架,哪些路由需要开启 SSG 功能。
90
90
 
91
91
  例如有以下代码,包含多条路由,设置 `output.ssg` 为 `true` 时,默认只会渲染入口路由即 `/`:
92
92
 
@@ -4,7 +4,7 @@ sidebar_position: 10
4
4
 
5
5
  # 测试
6
6
 
7
- Modern.js 默认继承了 [Jest](https://jestjs.io/) 的测试能力。
7
+ Modern.js 默认集成了 [Jest](https://jestjs.io/) 的测试能力。
8
8
 
9
9
  我们首先需要执行 `pnpm run new` 启用「单元测试 / 集成测试」功能:
10
10
 
@@ -339,6 +339,15 @@ export default async (): Promise<ProfileData> => {
339
339
 
340
340
  4. 在服务端运行时,`loader` 函数会被打包为一个统一的 bundle,所以我们不推荐服务端的代码使用 `__filename` 和 `__dirname`。
341
341
 
342
+ ### 常见问题
343
+
344
+ 1. loader 和 bff 的关系
345
+
346
+ 在 CSR 项目中,loader 在客户端执行,在 loader 可以直接调用 bff 函数进行接口请求。
347
+
348
+ 在 SSR 项目中,每个 loader 也是一个服务端接口,我们推荐使用 loader 替代 http method 为 `get` 的 BFF 函数,作为接口层,避免多一层转发和执行。
349
+
350
+
342
351
  ## useLoader(旧版)
343
352
 
344
353
  **`useLoader`** 是 Modern.js 老版本中的 API。该 API 是一个 React Hook,专门提供给 SSR 应用使用,让开发者能同构的在组件中获取数据。
@@ -444,7 +444,7 @@ export const init = (context: RuntimeContext) => {
444
444
  };
445
445
  ```
446
446
 
447
- ### Prefetch
447
+ ### 预加载
448
448
 
449
449
  在约定式路由下, Modern.js 会根据路由,自动地对路由进行分片,当用户访问具体的路由时,会自动加载对应的分片,这样可以有效地减少首屏加载的时间。但这也带来了一个问题,当用户访问一个路由时,如果该路由对应的分片还未加载完成,就会出现白屏的情况。
450
450
  这种情况下你可以通过定义 `loading` 组件,在静态资源加载完成前,展示一个自定义的 `loading` 组件。
@@ -462,9 +462,24 @@ export const init = (context: RuntimeContext) => {
462
462
  :::
463
463
 
464
464
  - `none`, 默认值,不会做 prefetch,没有任何额外的行为。
465
- - `intent`,这是我们推荐大多数场景下使用的值,当你把鼠标放在 Link 上时,会自动开始加载对应的分片和 data loader 中定义的数据,当鼠标移开时,会自动取消加载。在我们的测试中,即使是直接点击,也能减少大约 200ms 的加载时间。
465
+ - `intent`,这是我们推荐大多数场景下使用的值,当你把鼠标放在 Link 上时,会自动开始加载对应的分片和 data loader 中定义的数据,当鼠标移开时,会自动取消加载。在我们的测试中,即使是快速点击,也能减少大约 200ms 的加载时间。
466
466
  - `render`,当 Link 组件渲染时,就会加载对应的分片和 data loader 中定义的数据。
467
467
 
468
+ #### 常见问题
469
+
470
+ 1. 使用 `render` 和不根据路由做静态资源分片的区别?
471
+
472
+ - 使用 `render` 可以指定哪些路由在首屏时,进行加载,同时你可以通过对渲染的控制,仅当 Link 组件进入到可视区域时,才对 Link 组件进行渲染。
473
+ - 使用 `render`,仅在空闲时对静态资源进行加载,不会与首屏静态资源抢占网络。
474
+ - 在 SSR 场景下,也会对数据进行预取。
475
+
476
+ import Motivation from '@site-docs/components/convention-routing-motivation'
477
+
478
+ <Motivation/>
479
+
480
+ import Practice from '@site-docs/components/routes-practice'
481
+
482
+ <Practice/>
468
483
 
469
484
 
470
485
  ## 自控式路由
@@ -488,9 +503,10 @@ export default () => {
488
503
 
489
504
  :::note
490
505
  Modern.js 默认对约定式路由做了一系列资源加载及渲染上的优化,并且提供了开箱即用的 SSR 能力,而这些能力,在使用自控路由时,都需要开发者自行封装,推荐开发者使用约定式路由。
491
-
492
506
  :::
493
507
 
508
+ 使用自控式路由时,如果开发者关闭了 [`runtime.router`](/configure/app/runtime/router) 配置,并直接使用 `react-router-dom`,那还需要根据 React Router 文档自行包裹 `Provider`。
509
+
494
510
  ## 其他路由方案
495
511
 
496
512
  默认情况下,Modern.js 会开启内置的路由方案,即 React Router。
@@ -513,19 +529,5 @@ export default defineConfig({
513
529
  });
514
530
  ```
515
531
 
516
- ### 常见问题
517
-
518
- 1. 产物中的代码是 es2015+ 的,期望产物中是 es5 的代码
519
-
520
- react-router^6 的目前默认产物是 es2020 的,如果需要产物中是 es5 的代码,可以配置 `source.include`,让 react-router 相关包经过 bundler 编译 :
521
-
522
- ```
523
- source: {
524
- source: {
525
- include: [/@remix-run\/router/, /react-router-dom/, /react-router/],
526
- }
527
- }
528
- ```
529
-
530
532
 
531
533
 
@@ -98,36 +98,55 @@ Modern.js 会将与 package.json 文件中 `name` 字段同名的入口作为主
98
98
 
99
99
  #### 约定式路由
100
100
 
101
- 如果入口中存在 `routes/` 目录,Modern.js 会在启动时扫描 `routes/` 下的文件,基于文件约定,自动生成客户端路由(react-router)。
101
+ 如果入口中存在 `routes/` 目录,Modern.js 会在启动时扫描 `routes/` 下的文件,基于文件约定,自动生成客户端路由(react-router)。例如:
102
102
 
103
- 详细内容可以参考[路由](/guides/basic-features/routes)。
104
-
105
- #### 自定义路由
103
+ ```bash
104
+ .
105
+ ├── src
106
+ │ └── routes
107
+ │ ├── layout.tsx
108
+ │ └── page.tsx
109
+ ```
106
110
 
107
- 如果入口中存在 `App.[jt]sx?` 文件,开发者可以在这个文件中自由的设置客户端路由,或者不设置客户端路由。
111
+ 上述目录中,`layout.tsx` 中导出的组件会作为最外层的组件,`page.tsx` 中导出的组件会作为 `/` 路由的组件。
108
112
 
109
- 详细内容可以参考[路由](/guides/basic-features/routes)。
113
+ 详细内容可以参考[路由](/guides/basic-features/routes#约定式路由)。
110
114
 
111
- #### 自定义 App
115
+ #### 自控式路由
112
116
 
113
- 如果入口中存在 `index.[jt]sx` 文件,并且当文件默认导出函数时,Modern.js 还是会根据 runtime 的设置情况生成 createApp 包裹后的代码。在渲染过程中,将 createApp 包裹后的组件作为参数传递给 index 文件导出的函数,这样开发者可以自定义将组件挂载到 DOM 节点上,或在挂载前添加自定义行为。例如:
117
+ 如果入口中存在 `App.[jt]sx?` 文件,开发者可以在这个文件中通过代码的方式,设置客户端路由,或者不设置客户端路由。
114
118
 
115
119
  ```tsx
116
- import ReactDOM from 'react-dom/client';
117
- import { bootstrap } from '@modern-js/runtime';
118
-
119
- export default (App: React.ComponentType) => {
120
- // do something before bootstrap...
121
- bootstrap(App, 'root', undefined, ReactDOM);
120
+ import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
121
+
122
+ export default () => {
123
+ return (
124
+ <BrowserRouter>
125
+ <Routes>
126
+ <Route index element={<div>index</div>} />
127
+ <Route path="about" element={<div>about</div>} />
128
+ </Routes>
129
+ </BrowserRouter>
130
+ );
122
131
  };
123
132
  ```
124
133
 
125
- :::warning
126
- 由于 bootstrap 函数需要兼容 React17 和 React18 的用法,调用 bootstrap 函数时需要手动传入 ReactDOM 参数。
134
+ 详细内容可以参考[路由](/guides/basic-features/routes#自控式路由)。
127
135
 
128
- :::
136
+ #### 自定义 Bootstrap
137
+
138
+ 如果入口中存在 `index.[jt]sx` 文件,并且当文件默认导出函数时,Modern.js 会将默认的 bootstrap 函数作为入参传入,并用导出的函数替代默认的 bootstrap,这样开发者可以自定义将组件挂载到 DOM 节点上,或在挂载前添加自定义行为。例如:
139
+
140
+ ```tsx
141
+ export default (App: React.ComponentType, bootstrap: () => void) => {
142
+ // do something before bootstrap...
143
+ initSomething().then(() => {
144
+ bootstrap();
145
+ })
146
+ };
147
+ ```
129
148
 
130
- Modern.js 生成的文件内容如下:
149
+ 此时,Modern.js 生成的文件内容如下:
131
150
 
132
151
  ```js
133
152
  import React from 'react';
@@ -140,13 +159,14 @@ const IS_BROWSER = typeof window !== 'undefined' && window.name !== 'nodejs';
140
159
  const MOUNT_ID = 'root';
141
160
 
142
161
  let AppWrapper = null;
162
+ let root = null;
143
163
 
144
164
  function render() {
145
165
  AppWrapper = createApp({
146
166
  // runtime 的插件参数...
147
167
  })(App);
148
168
  if (IS_BROWSER) {
149
- customBootstrap(AppWrapper);
169
+ customBootstrap(AppWrapper, () => bootstrap(AppWrapper, MOUNT_ID, root, ReactDOM));
150
170
  }
151
171
  return AppWrapper;
152
172
  }
@@ -170,9 +190,9 @@ import App from './App';
170
190
  ReactDOM.render(<App />, document.getElementById('root'));
171
191
  ```
172
192
 
173
- Modern.js **不推荐**使用这种方式,这种方式丧失了框架的一些能力,如 **`modern.config.js` 文件中的 `runtime` 配置将不会再生效**。但是在项目从其他框架迁移到 Modern.js,例如 CRA,或是自己手动搭建的 webpack 时,这种方式会非常有用。
193
+ Modern.js **不推荐**新项目使用这种方式,这种方式丧失了框架的一些能力,如 **`modern.config.js` 文件中的 `runtime` 配置将不会再生效**。但是在项目从其他框架迁移到 Modern.js,例如 CRA,或是自己手动搭建的 webpack 时,这种方式会非常有用。
174
194
 
175
- ## 自定义入口
195
+ ## 使用配置指定入口
176
196
 
177
197
  大部分存量项目并不是按照 Modern.js 的目录结构来搭建的。如果要改成 Modern.js 约定的目录结构,会存在一定的迁移成本。
178
198
 
@@ -611,7 +611,7 @@ export default (): CliPlugin => ({
611
611
 
612
612
  这样就为 HTML 模版中新增了一个 Script 标签。
613
613
 
614
- ## Server
614
+ {/* ## Server
615
615
 
616
616
  :::note
617
617
  目前 Server 插件还未完全开放,API 不保证稳定,使用需谨慎。
@@ -692,7 +692,7 @@ export default (): ServerPlugin => ({
692
692
  };
693
693
  },
694
694
  });
695
- ```
695
+ ```*/}
696
696
 
697
697
  ## Runtime
698
698
 
@@ -701,7 +701,7 @@ export default (): ServerPlugin => ({
701
701
 
702
702
  :::
703
703
 
704
- Runtime 插件主要用于开发者修改需要渲染的组件与 Element 和定制服务器端、客户端的渲染过程。
704
+ Runtime 插件主要用于开发者修改需要渲染的组件。
705
705
 
706
706
  ### `init`
707
707
 
@@ -734,23 +734,29 @@ export default (): Plugin => ({
734
734
  - 类型:`Pipeline<{ App: React.ComponentType<any>; }, React.ComponentType<any>>`
735
735
  - 使用示例:
736
736
 
737
+ :::note
738
+ 使用 hoc 钩子时,需要把原来的 App 组件的静态属性拷贝到新的组件上,并透传 props.
739
+ :::
740
+
737
741
  ```ts
738
742
  import { createContext } from 'react';
739
743
  import type { Plugin } from '@modern-js/runtime';
744
+ import hoistNonReactStatics from 'hoist-non-react-statics';
740
745
 
741
746
  export default (): Plugin => ({
742
747
  setup(api) {
743
748
  const FooContext = createContext('');
744
749
  return {
745
750
  hoc({ App }, next) {
751
+ const AppWrapper = (props: any) => {
752
+ return (
753
+ <FooContext.Provider store={'test'}>
754
+ <App {...props} />
755
+ </FooContext.Provider>
756
+ );
757
+ };
746
758
  return next({
747
- App: (props: any) => {
748
- return (
749
- <FooContext.Provider store={'test'}>
750
- <App {...props} />
751
- </FooContext.Provider>
752
- );
753
- },
759
+ App: hoistNonReactStatics(AppWrapper, App)
754
760
  });
755
761
  },
756
762
  };
@@ -758,7 +764,7 @@ export default (): Plugin => ({
758
764
  });
759
765
  ```
760
766
 
761
- ### `provide`
767
+ {/* ### `provide`
762
768
 
763
769
  - 功能:修改需要渲染的 Element
764
770
  - 执行阶段:渲染(SSR/CSR)
@@ -830,4 +836,4 @@ export default (): Plugin => ({
830
836
  };
831
837
  },
832
838
  });
833
- ```
839
+ ```*/}
@@ -2,7 +2,7 @@
2
2
  sidebar_position: 2
3
3
  ---
4
4
 
5
- # isFileExit
5
+ # isFileExist
6
6
 
7
7
  判断文件是否存在。
8
8
 
@@ -12,7 +12,7 @@ sidebar_position: 2
12
12
 
13
13
  ```ts
14
14
  export interface IPluginContext {
15
- isFileExit: (fileName: string) => Promise<boolean>;
15
+ isFileExist: (fileName: string) => Promise<boolean>;
16
16
  ...
17
17
  }
18
18
  ```
package/modern.config.ts CHANGED
@@ -7,8 +7,7 @@ const rootCategories = [
7
7
  'guides',
8
8
  'apis/app',
9
9
  'configure/app',
10
- 'blog',
11
- 'about',
10
+ 'community',
12
11
  ];
13
12
 
14
13
  const { version } = require('./package.json');
@@ -42,14 +41,9 @@ const getNavbar = (lang: string): NavItem[] => {
42
41
  activeMatch: '/apis/',
43
42
  },
44
43
  {
45
- text: getText('博客', 'Blog'),
46
- link: getLink('/blog/index'),
47
- activeMatch: '/blog/',
48
- },
49
- {
50
- text: getText('关于', 'About'),
51
- link: getLink('/about/showcase'),
52
- activeMatch: '/about/',
44
+ text: getText('社区', 'Community'),
45
+ link: getLink('/community/showcase'),
46
+ activeMatch: '/community/',
53
47
  },
54
48
  {
55
49
  text: `v${version}`,
@@ -122,6 +116,11 @@ export default defineConfig({
122
116
  label: 'English',
123
117
  },
124
118
  ],
119
+ editLink: {
120
+ docRepoBaseUrl:
121
+ 'https://github.com/web-infra-dev/modern.js/tree/main/packages/document/main-doc/docs',
122
+ text: 'Edit this page on GitHub',
123
+ },
125
124
  socialLinks: [
126
125
  {
127
126
  icon: 'github',
package/package.json CHANGED
@@ -15,13 +15,13 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.17.0",
18
+ "version": "2.17.2-alpha.0",
19
19
  "publishConfig": {
20
20
  "registry": "https://registry.npmjs.org/",
21
21
  "access": "public"
22
22
  },
23
23
  "peerDependencies": {
24
- "@modern-js/builder-doc": "^2.17.0"
24
+ "@modern-js/builder-doc": "^2.17.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "classnames": "^2",
@@ -33,9 +33,9 @@
33
33
  "fs-extra": "^10",
34
34
  "@types/node": "^16",
35
35
  "@types/fs-extra": "^9",
36
- "@modern-js/builder-doc": "2.17.0",
37
- "@modern-js/doc-tools": "2.17.0",
38
- "@modern-js/doc-plugin-auto-sidebar": "2.17.0"
36
+ "@modern-js/doc-tools": "2.17.1",
37
+ "@modern-js/builder-doc": "2.17.1",
38
+ "@modern-js/doc-plugin-auto-sidebar": "2.17.1"
39
39
  },
40
40
  "scripts": {
41
41
  "dev": "modern dev",
@@ -1,5 +0,0 @@
1
- {
2
- "label": "更新内容",
3
- "position": 2,
4
- "collapsed": false
5
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes