@modern-js/main-doc 2.0.0-beta.6 → 2.0.0-canary.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/index_.md +1 -1
  3. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/pages.md +1 -1
  4. package/en/docusaurus-plugin-content-docs/current/apis/app/hooks/src/routes.md +86 -0
  5. package/en/docusaurus-plugin-content-docs/current/components/global-proxy-config.md +74 -0
  6. package/en/docusaurus-plugin-content-docs/current/components/global-proxy.md +28 -0
  7. package/en/docusaurus-plugin-content-docs/current/configure/app/dev/proxy.md +2 -72
  8. package/en/docusaurus-plugin-content-docs/current/configure/app/source/entries.md +0 -2
  9. package/en/docusaurus-plugin-content-docs/current/configure/app/tools/tailwindcss.md +16 -22
  10. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/_category_.json +8 -0
  11. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/bff-proxy.md +27 -0
  12. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/frameworks.md +148 -0
  13. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/function.md +218 -0
  14. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/index.md +20 -0
  15. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/bff/type.md +43 -0
  16. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/code-split.md +77 -0
  17. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/compatibility.md +76 -0
  18. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/eslint.md +145 -0
  19. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/index.md +12 -0
  20. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/low-level.md +46 -0
  21. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssg.md +128 -0
  22. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/ssr.md +306 -0
  23. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/testing.md +46 -0
  24. package/en/docusaurus-plugin-content-docs/current/guides/advanced-features/web-server.md +57 -0
  25. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/alias.md +67 -0
  26. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/css/tailwindcss.md +30 -35
  27. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/data-fetch.md +400 -0
  28. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/env-vars.md +166 -0
  29. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/html.md +235 -0
  30. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/mock.md +78 -0
  31. package/en/docusaurus-plugin-content-docs/current/guides/basic-features/proxy.md +60 -0
  32. package/en/docusaurus-plugin-content-docs/current/guides/get-started/quick-start.md +2 -4
  33. package/package.json +3 -3
  34. package/zh/apis/app/hooks/src/index_.md +1 -1
  35. package/zh/apis/app/hooks/src/pages.md +1 -1
  36. package/zh/apis/app/hooks/src/routes.md +89 -0
  37. package/zh/components/debug-app.md +1 -2
  38. package/zh/components/global-proxy-config.md +70 -0
  39. package/zh/configure/app/dev/proxy.md +2 -70
  40. package/zh/configure/app/source/entries.md +1 -3
  41. package/zh/configure/app/tools/tailwindcss.md +16 -23
  42. package/zh/guides/advanced-features/bff/function.md +37 -19
  43. package/zh/guides/advanced-features/code-split.md +28 -20
  44. package/zh/guides/advanced-features/compatibility.md +24 -14
  45. package/zh/guides/advanced-features/ssg.md +1 -47
  46. package/zh/guides/advanced-features/ssr.md +1 -1
  47. package/zh/guides/advanced-features/testing.md +2 -2
  48. package/zh/guides/basic-features/alias.md +5 -5
  49. package/zh/guides/basic-features/css/tailwindcss.md +31 -35
  50. package/zh/guides/basic-features/data-fetch.md +7 -6
  51. package/zh/guides/basic-features/env-vars.md +2 -2
  52. package/zh/guides/basic-features/html.md +62 -137
  53. package/zh/guides/basic-features/mock.md +8 -9
  54. package/zh/guides/basic-features/proxy.md +2 -2
  55. package/zh/guides/basic-features/routes.md +37 -3
  56. package/zh/guides/get-started/quick-start.md +1 -2
  57. package/zh/guides/topic-detail/framework-plugin/implement.md +54 -6
  58. package/zh/guides/topic-detail/micro-frontend/c02-development.md +1 -1
@@ -0,0 +1,218 @@
1
+ ---
2
+ sidebar_position: 1
3
+ title: Integration
4
+ ---
5
+
6
+ Modern.js allow functions that meet certain conditions in the `api/` directory to be directly called in the React component, which is called **integration**.
7
+
8
+ :::note
9
+ The use of integration calls requires the enable BFF first.
10
+ :::
11
+
12
+ ## BFF Function
13
+
14
+ The functions that are allowed to be called through integration are called **BFF functions**. Here is the simplest BFF function to write, creating an `api/hello.ts` file:
15
+
16
+ ```ts title="api/hello.ts"
17
+ export const get = async () => 'Hello Modern.js';
18
+ ```
19
+
20
+ Then directly import the function in `src/App.tsx` and call:
21
+
22
+ ```tsx title=src/App.tsx
23
+ import { useState, useEffect } from 'react';
24
+ import { get as hello } from '@api/hello';
25
+
26
+ export default () => {
27
+ const [text, setText] = useState('');
28
+
29
+ useEffect(() => {
30
+ hello().then(setText);
31
+ }, []);
32
+ return <div>{text}</div>;
33
+ };
34
+ ```
35
+
36
+ :::info
37
+ Modern.js generator has already configured the `@api` alias in tsconfig.json, so you can import functions directly by aliases.
38
+ :::
39
+
40
+ The functions import in `src/App.tsx` will be automatically converted into interface calls, so there is no need to call the interface through fetch.
41
+
42
+ Execute `pnpm run dev`, then open `http://localhost:8080/` to see that the page has displayed the content returned by the BFF function. In Network, you can see that the page sent a request to `http://localhost:8080/api/hello`.
43
+
44
+ ## Function Route
45
+
46
+ In Modern.js, the BFF function routing system is implemented based on the file system, and it is also a conventional routing system.
47
+
48
+ In **Function Writing**, All files under `api/` will map to an interface. In **Framework Writing**, All files under `api/lambda` will map to an interface
49
+
50
+ :::note
51
+ Function Writing & Framework Writing will introduce soon.
52
+ :::
53
+
54
+ All routes generated by BFF functions have a prefix, and the default value is `/api`. The prefix can be set through [bff.prefix] (/docs/configure/app/bff/prefix).
55
+
56
+ Several routing conventions are described as follow.
57
+
58
+ ### Default Route
59
+
60
+ Files named `index.[jt]s` are mapped to the previous directory.
61
+
62
+ * `api/index.ts` -> `{prefix}/`
63
+ * `api/user/index.ts` -> `{prefix}/user`
64
+
65
+ ### Multi-layer Route
66
+
67
+ Supports parsing nested files, if you create a nested folder structure, the files will still automatically parse routes in the same way.
68
+
69
+ * `api/hello.ts` -> `{prefix}/hello`
70
+ * `api/user/list.ts` -> `{prefix}/user/list`
71
+
72
+ ### Dynamic Route
73
+
74
+ Create folders or files named with `[xxx]` to support dynamic named routing parameters.
75
+
76
+ * `api/user/[username]/info.ts` -> `{prefix}/user/:username/info`
77
+ * `api/user/username/[action].ts` -> `{prefix}/user/username/:action`
78
+
79
+ ### Allow List
80
+
81
+ By default, all files in the'api/'directory will be parsed as BFF function files, but the following files will not be parsed:
82
+
83
+ * file name start with `_`, for example `_utils.ts`.
84
+ * files in directory which name start with `_`, for example `_utils/index.ts`、`_utils/cp.ts`.
85
+ * test files, for example `foo.test.ts`.
86
+ * type files, for example `hello.d.ts`.
87
+ * files in `node_module`.
88
+
89
+ ## RESTful API
90
+
91
+ Modern.js BFF functions need to be defined according to the RESTful API standard, follow the HTTP Method specification, and do not allow free parameter definition.
92
+
93
+ :::info
94
+ Assuming that the function allows free definition of parameters, the resulting route must be called by the **private protocol** (the reason is that the request parameters cannot be distinguished from the request body), and cannot implement any RESTful API.
95
+
96
+ If the service is only used for the application itself, there is no problem. but its **non-standard interface definition** cannot be integrated into the larger system. In the case of multiple systems working together (such as BFF low-code construction), other systems also need to follow the **private protocol**.
97
+ :::
98
+
99
+ ### Function Named Export
100
+
101
+ Modern.js the export name of the BFF function determines the Method of the corresponding interface of the function, such as `get`, `post` and so on.
102
+
103
+ For example, following the example, a `GET` interface can be exported.
104
+
105
+ ```ts
106
+ export const get = async () => {
107
+ return {
108
+ name: 'Modern.js',
109
+ desc: '现代 web 工程方案',
110
+ };
111
+ };
112
+ ```
113
+
114
+ Following the example below, a `POST` interface can be exported.
115
+
116
+ ```ts
117
+ export const post = async () => {
118
+ return {
119
+ name: 'Modern.js',
120
+ desc: '现代 web 工程方案',
121
+ };
122
+ };
123
+ ```
124
+
125
+ * Modern.js supports 9 definitions for HTTP Method: `GET`、`POST`、`PUT`、`DELETE`、`CONNECT`、`TRACE`、`PATCH`、`OPTION`、`HEAD`, can be exported using these methods as functions。
126
+
127
+ * The name is size insensitive,if `GET`,can write `get`、`Get`、`GEt`、`GET`,can be accurately identified. But default export as `export default xxx` will be map to `Get`。
128
+
129
+ * Multiple functions of different Methods can be defined in one file, but if multiple functions of the same Method are defined, only the first will take effect.
130
+
131
+ :::info
132
+ It should be noted that the defined functions should all be asynchronous, which is related to the type when the function is called, which will be mentioned later.
133
+ :::
134
+
135
+ ### Function Parameter Rule
136
+
137
+ As mentioned above, in order to meet the design criteria of RESTful APIs, the BFF function in Modern.js needs to follow certain imported parameter rules.
138
+
139
+ The function parameters are divided into two parts, the dynamic part in the request path and the request option `RequestOption`.
140
+
141
+ #### Dynamic Path
142
+
143
+ Dynamic routing will be used as imported parameters in the first part of the function, and each imported parameter corresponds to a dynamic route. For example, in the following example, uid will be passed into the function as the first two parameters:
144
+
145
+ ```ts title="api/[level]/[id].ts"
146
+ export default async (level: number, id: number) => {
147
+ const userData = await queryUser(level, uid);
148
+ return userData
149
+ }
150
+ ```
151
+
152
+ Pass dynamic parameters directly when calling:
153
+
154
+ ```ts title="App.tsx"
155
+ import { useState, useEffect } from 'react'
156
+ import { get as getUser } from '@api/[level]/[id]'
157
+
158
+ export default () => {
159
+ const [name, setName] = useState('')
160
+
161
+ useEffect(() => {
162
+ getUser(6, 001).then(
163
+ userData => setName(userData.name)
164
+ )
165
+ }, [])
166
+
167
+ return <div>{name}</div>
168
+ }
169
+ ```
170
+
171
+ #### RequestOption
172
+
173
+ The parameter after Dynamic Path is the object `RequestOption` containing querystring and request body, which is used to define the types of `data` and `query`.
174
+
175
+ In normal functions without dynamic routing, the incoming `data` and `query` can be obtained from the first imported parameter, for example:
176
+
177
+ ```ts title="api/hello.ts"
178
+ import type { RequestOption } from '@modern-js/runtime/server'
179
+
180
+ export async function post(
181
+ { query, data }: RequestOption<Record<string, string>, Record<string, string>>
182
+ ) {
183
+ // do somethings
184
+ }
185
+ ```
186
+
187
+ When a function file uses dynamic routing rules, dynamic routing before the `RequestOption` parameter.
188
+
189
+ ```ts title="api/[sku]/[id]/item.ts"
190
+ export async function post(
191
+ sku: string,
192
+ id: string,
193
+ { data, query }: RequestOption<Record<string, string>, Record<string, string>>
194
+ ) {
195
+ // do somethings
196
+ }
197
+ ```
198
+
199
+ Also pass in the parameters according to the function definition:
200
+
201
+ ```ts title="App.tsx"
202
+ import { post } from '@api/[sku]/[id]/item'
203
+
204
+ export default () => {
205
+ const addSku = () => {
206
+ post('0001'/* sku */, '1234' /* id */, {
207
+ query: { /* ... */ },
208
+ data: { /* ... */ },
209
+ })
210
+ }
211
+
212
+ return <div onClick={addSku}>添加 SKU</div>
213
+ }
214
+ ```
215
+
216
+ As mentioned earlier, the defined functions should be asynchronous because they are automatically converted to HTTP interface calls when called by the front end.
217
+
218
+ so in order to keep the type definition consistent with the actual calling, it is necessary to set the BFF function to asynchronous when defining it.
@@ -0,0 +1,20 @@
1
+ ---
2
+ title: BFF
3
+ ---
4
+
5
+ In the development of the concept of **front back separation**, the front-end part can do more and more things, and the front-end needs some UI-oriented data interfaces, so the industry introduced the concept of BFF (Backends for Frontends).
6
+
7
+ The main problems it to solve include:
8
+
9
+ * Aggregation, mapping, clipping, and proxying of lower-level APIs according to their own business needs.
10
+ * Cache data for some specific scenarios to improve performance and thus improve user experience.
11
+ * Quickly development of new products based on existing interfaces.
12
+ * Interface with third-party systems, such as login authentication.
13
+
14
+ Modern.js officially supported the BFF and provided the **Integrated BFF** to further strengthen the BFF's capabilities, mainly including the following capabilities:
15
+
16
+ * Quick development and debugging go live, running, building, and deploying BFF code in the same project.
17
+ * Minimal pure function call, directly import BFF function on the front end, and can be automatically converted into HTTP request when called.
18
+ * No private protocol, follow RESTful API specification, all BFF interfaces are standardized.
19
+ * Full TypeScript support.
20
+ * Meet user preferences and support multi-frame extension writing.
@@ -0,0 +1,43 @@
1
+ ---
2
+ sidebar_position: 2
3
+ title: Writing Type
4
+ ---
5
+
6
+ Runtime framework support is also an important part of **BFF**. Modern.js supports extending BFF's runtime framework through plugins, and provides a series of built-in plugins, developers can directly use the conventions and ecology of the framework.
7
+
8
+ The plugin is compatible with most of the specifications of these frameworks, and each framework needs to provide two types of ways to extend the writing of BFF functions, namely **Function Writing** and **Framework Writing**.
9
+
10
+ :::note
11
+ Whether the current `api/` directory structure is written as a framework is determined by the corresponding plugin, Modern.js don't care.
12
+ :::
13
+
14
+ ## Function Writing
15
+
16
+ When the plugin considers that it is currently written as a function, it must support writing middleware in the `api/_ app.ts` to extend the BFF function.
17
+
18
+ Modern.js collects the middleware in the `api/_app.ts` and passes it to the plugin, which injects the middleware into the runtime, for example:
19
+
20
+ ```ts
21
+ import { hook } from '@modern-js/runtime/server';
22
+
23
+ export default hook(({ addMiddleware }) => {
24
+ addMiddleware(myMiddleware);
25
+ });
26
+ ```
27
+
28
+ :::note
29
+ The writing of middleware for different plugins is not the same, see [Runtime Framework](/docs/guides/advanced-features/bff/frameworks) for details.
30
+ :::
31
+
32
+ ## Framework Writing
33
+
34
+ Framework writing is a way of using frame structure to extend BFF functions. Compared with function writing, although frame writing can use more frame structure and make the entire BFF Server clearer in complex scenarios, it is also more complex and requires more attention to the content at the framework level.
35
+
36
+ In the framework writing method, all BFF functions need to be written in the `api/lambda/` directory, and the hook file `_app.[tj]s` cannot be used.
37
+
38
+ In most cases, the function writing method can cover the customization requirements of most BFF functions. Only when your project server level logic is more complex, the code needs to be layered, or you need to use more elements of the framework, you need to use the framework writing method.
39
+
40
+ :::note
41
+ The directory structure of different plugin frameworks is not the same, see [Runtime Frameworks](/docs/guides/advanced-features/bff/frameworks) for details.
42
+ :::
43
+
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: Code Split
3
+ sidebar_position: 6
4
+ ---
5
+
6
+ Code Split is a common way to optimizing front-end resource loading. This doc will introduce three methods supported by Modern.js:
7
+
8
+ :::info
9
+ When you use Modern.js [Conventional routing](/docs/guides/basic-features/routes#conventional-routing), by default it will do code splitting based on routing components, wrapping `Suspense` components, no need to do code splitting by yourself.
10
+ :::
11
+
12
+ - `import`
13
+ - `React.lazy`
14
+ - `loadable`
15
+
16
+ ## import
17
+
18
+ use dynamic `import()`,`import` The JS modules pass to this API will be packaged into a separate JS file as a new packaging entry, for example:
19
+
20
+ ```ts
21
+ import("./math").then(math => {
22
+ console.log(math.add(16, 26));
23
+ });
24
+ ```
25
+
26
+ The JS modules corresponding to the './math' path will be packaged in a separate JS file.
27
+
28
+
29
+ ## React.lazy
30
+
31
+ The officially way provides by React to split component code.
32
+
33
+ :::caution
34
+ SSR is not supported in React 17 and below, and it is recommended that SSR applications for React 17 use loadable.
35
+ :::
36
+
37
+ ```ts
38
+ import React, { Suspense } from 'react';
39
+
40
+ const OtherComponent = React.lazy(() => import('./OtherComponent'));
41
+ const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
42
+
43
+ function MyComponent() {
44
+ return (
45
+ <div>
46
+ <Suspense fallback={<div>Loading...</div>}>
47
+ <section>
48
+ <OtherComponent />
49
+ <AnotherComponent />
50
+ </section>
51
+ </Suspense>
52
+ </div>
53
+ );
54
+ }
55
+ ```
56
+
57
+ For detail, see [React lazy](https://reactjs.org/docs/code-splitting.html#reactlazy)。
58
+
59
+ ## loadable
60
+
61
+ use `loadable` API,for example:
62
+
63
+ ```ts
64
+ import loadable from '@modern-js/runtime/loadable'
65
+
66
+ const OtherComponent = loadable(() => import('./OtherComponent'));
67
+
68
+ function MyComponent() {
69
+ return <OtherComponent />
70
+ }
71
+ ```
72
+
73
+ For detail, see [loadable API](/docs/apis/app/runtime/utility/loadable)。
74
+
75
+ :::info
76
+ SSR is supported out of the box by `loadable`.
77
+ :::
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Compatibility
3
+ sidebar_position: 5
4
+ ---
5
+
6
+ ## Browserslist
7
+
8
+ Modern.js supports the `browserslist` field in the `package.json` file, or a `.browserslistrc` file to specify the target browser range covered by the project.
9
+
10
+ This value is used by ['@babel/preset-env'] (https://babeljs.io/docs/en/babel-preset-env) and ['autoprefixer'] (https://github.com/postcss/autoprefixer) to determine the JavaScript syntax features to be converted and the CSS browser prefix to be added.
11
+
12
+ The default value in Modern.js as follow:
13
+
14
+ ```js
15
+ ['> 0.01%', 'not dead', 'not op_mini all']
16
+ ```
17
+
18
+ You can learn how to customize the browserlist [here](https://github.com/browserslist/browserslist).
19
+
20
+ See Modern.js Builder docs to learn more [Browserlist](https://modernjs.dev/builder/zh/guide/advanced/browserslist.html) info.
21
+
22
+ :::note
23
+ Modern.js also supports configuring [output.override Browserlist](/docs/configure/app/output/override-browserslist) to override the default browserlist value.
24
+ :::
25
+
26
+
27
+ ## Polyfill
28
+
29
+ ### Polyfill At Compile
30
+
31
+ Modern.js inject the Polyfill code via [core-js] (https://github.com/zloirock/core-js) at compile time by default.
32
+
33
+ By default, the required Polyfill code will be introduced according to the settings of the Browserslist, so there is no need to worry about the Polyfill problem of the project source code and third-party dependencies, but because it contains some Polyfill code that is not used, the final bundle size may be increased.
34
+
35
+ :::info
36
+ For case where Polyfill is not required for third-party dependencies, you can set ['output.polyfill'](/docs/configure/app/output/polyfill) to `usage`, so that Babel compiles only Polyfill code based on the syntax used in the code.
37
+ :::
38
+
39
+ ### Polyfill At Runtime
40
+
41
+ Modern.js also provides a runtime Polyfill solution based on browser [UA](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent) information, which has the following advantages over Babel:
42
+
43
+ * It will not be inserted into the code, reducing the code .
44
+ * The same browser will share a Polyfill code. Therefore, with more and more projects, the UA-based Polyfill code will be delivered faster and faster.
45
+
46
+ exec `pnpm run new` to enable this features:
47
+
48
+ ```bash
49
+ ? 请选择你想要的操作 启用可选功能
50
+ ? 启用可选功能 启用「基于 UA 的 Polyfill」功能
51
+ ```
52
+
53
+ After executing the command, register the Polyfill plugin in `modern.config.ts`:
54
+
55
+ ```ts title="modern.config.ts"
56
+ import PolyfillPlugin from '@modern-js/plugin-polyfill';
57
+ // https://modernjs.dev/docs/apis/app/config
58
+ export default defineConfig({
59
+ ...,
60
+ plugins: [..., PolyfillPlugin()],
61
+ });
62
+ ```
63
+
64
+ After configuring `output.polyfill` as `ua` and executing `pnpm run build & & pnpm run serve` to start the server, visiting the page can see that the HTML product contains the following script:
65
+
66
+ ```js
67
+ <script src="/__polyfill__" crossorigin></script>
68
+ ```
69
+
70
+ Visit the page `http://localhost:8080/__polyfill__` on Chrome 51 to see:
71
+
72
+ ![ua-polyfill](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/docs/ua-polyfill.png)
73
+
74
+ :::caution
75
+ This feature only works when using Modern.js built-in Web Server.
76
+ :::
@@ -0,0 +1,145 @@
1
+ ---
2
+ title: ESLint
3
+ sidebar_position: 8
4
+ ---
5
+
6
+ **Modern.js ESLint Rules** Is the full set of **ESLint** rules,includes `@modern-js` (Lint rules for Node.js projects)and `@modern-js-app`(Lint rules for web projects)。
7
+
8
+ More ESLint usage is described below with specific questions.
9
+
10
+ ## Q: How To Deal With Lint
11
+
12
+ ### Automatic Fix
13
+
14
+ Most problems will be solved by the automatic fix of ESLint rules or the code formatting of [Prettier](https://prettier.io/) (which has been integrated into ESLint), and the developer does not need to care about the details of the problem and how to solve it.
15
+
16
+ :::info
17
+ This kind of automatic fix is mainly performed when the IDE saves the file, and a few will be automatically fix on submit.
18
+ :::
19
+
20
+ ### Batch Automatic Fix
21
+
22
+ 在少数情况下,比如旧项目迁移的时候,可以执行以下命令,批量修复和检查所有文件:
23
+
24
+ ```bash
25
+ pnpm run lint:error
26
+ ```
27
+
28
+ ### Manual Fix
29
+
30
+ 对于无法自动修复的问题,可以在 IDE 里点击问题提示框里的规则链接,打开这条规则的文档,查看问题的解释和解决方案。
31
+
32
+
33
+ ### 声明例外情况
34
+
35
+ 目前阶段,有些规则并不能做到足够智能,多数情况下会有很大收益,在少数情况下也许不适用。但如果为了这些少数情况就把整个规则关掉或改掉,得不偿失。
36
+
37
+ 这种情况下可以用 [eslint-disable](https://eslint.org/docs/user-guide/configuring/rules#disabling-rules) 注释,对符合**少数情况**的代码块做标注,声明这里是一个例外,应该忽略。比如:
38
+
39
+ ```js
40
+ /* eslint-disable filenames/match-exported */
41
+ ...
42
+ /* eslint-enable filenames/match-exported */
43
+ ```
44
+
45
+ :::info 注
46
+ 在 VS Code 编辑器里输入 eslint,会自动出现关于 "eslint-disable" 的提示框,选择提示选项生成对应注释对。
47
+ :::
48
+
49
+ 【Modern.js ESLint 规则集】要求 [eslint-disable](https://eslint.org/docs/user-guide/configuring/rules#disabling-rules) 必须成对使用,必须明确表达要影响的范围,以及在这个范围内明确表达要禁用什么规则,目的是让**例外**有明确的、最小化的范围,避免 [eslint-disable](https://eslint.org/docs/user-guide/configuring/rules#disabling-rules) 被滥用,导致不属于例外的代码也被禁用了规则。
50
+
51
+ ## Q: 如何自定义 ESLint 规则
52
+
53
+ ### 仓库根目录下 `package.json` 里的 "eslintConfig" 字段
54
+
55
+ 这个地方是整个仓库的默认 ESLint 配置,是针对纯 Node.js 代码(只能在 Node.js 里运行)设计的。
56
+
57
+ 如果项目在某些规则上确实有特殊要求或不可避免的兼容问题(不是例外),可以在这里增加规则配置。该配置会优先于默认的【Modern.js ESLint 规则集】,比如:
58
+
59
+ ```json
60
+ "eslintConfig": {
61
+ "extends": [
62
+ "@modern-js"
63
+ ],
64
+ "rules": {
65
+ "filenames/match-exported": "off"
66
+ }
67
+ },
68
+
69
+ ```
70
+
71
+ ### `src/.eslintrc.js` 文件
72
+
73
+ Modern.js 的应用工程、模块工程,源代码目录里都会默认有这个配置文件,是针对 Universal JS 代码设计的。
74
+
75
+ :::info 注
76
+ Universal JS 代码是既能浏览器端也能在服务器端运行的代码。
77
+ :::
78
+
79
+ 如果项目在某些规则上确实有特殊要求或不可避免的兼容问题(不是例外),可以在这里增加规则配置,该配置会优先于默认的【Modern.js ESLint 规则集】,比如:
80
+
81
+ ```js
82
+ // eslint-disable-next-line import/no-commonjs
83
+ module.exports = {
84
+ root: true,
85
+ extends: ['@modern-js-app'],
86
+ parserOptions: {
87
+ tsconfigRootDir: __dirname,
88
+ project: ['../tsconfig.json'],
89
+ },
90
+ rules: {
91
+ 'filenames/match-exported': 'off',
92
+ },
93
+ };
94
+ ```
95
+
96
+ 如果有需要,还可以继续在不同的子目录里增加 `.eslintrc.js` 文件,针对这个子目录里的代码做特殊配置:
97
+
98
+ ```js
99
+ module.exports = {
100
+ rules: {
101
+ 'filenames/match-exported': 'off',
102
+ },
103
+ };
104
+ ```
105
+
106
+ :::tip 提示
107
+ 注意:没有必要使用 `extends` 字段,会自动继承父目录的配置。
108
+ :::
109
+
110
+ ### package.json 里的 `eslintIgnore` 字段
111
+
112
+ 把包含 `.js`、`.jsx`、`.ts`、`.tsx` 文件、但不需要做代码检查和自动修复的目录,添加到 `eslintIgnore` 里,可以优化 ESLint 检查的速度,比如:
113
+
114
+ ```json
115
+ "eslintIgnore": [
116
+ "node_modules",
117
+ "dist",
118
+ "output"
119
+ ],
120
+ ```
121
+
122
+ ## Q: 如何升级 ESLint 插件的版本
123
+
124
+ 只要不是 Major 版本的变化(不符合 [Semver](https://semver.org/) 规则的 `^` 符号),就可以直接在业务项目的 `package.json` 里指定这个依赖,删除 Lock 文件(或尝试手动删除 Lock 文件中这个包名的内容),执行 `pnpm install` 重新安装依赖并且生成新的 Lock 文件。
125
+
126
+ 做完这些操作之后,在业务项目的 `./node_modules` 目录里,这个插件应该只存在一份,并且升级到了你指定的版本。
127
+
128
+ :::tip 提示
129
+ - Major 版本就是主版本号。更多信息,请阅读【[Semantic Versioning](https://semver.org/#summary)】。
130
+ - 所有被 Modern.js 封装的上游项目(比如 ESLint、[ESLint 插件](https://eslint.org/docs/user-guide/configuring/plugins#plugins)、[React Router](https://reactrouter.com/) 等),也都可以这样升级。
131
+ - Modern.js 也会在每次发版中尽量及时的升级这些上游依赖。
132
+ - Major 版本的升级需要由 Modern.js 来发版。
133
+ :::
134
+
135
+ ## Q: WebStorm 有时候会报 ESLint 错误
136
+
137
+ 由于 WebStorm 认为 ESLint 执行目录是根据 `.eslintrc` 文件来决定的。因此 `src/.eslintrc` 文件位置的放置会导致 `tsconfig.json` 文件指定的位置(项目根目录下)在 `src/` 目录下找不到。
138
+
139
+ 此时需要手动配置一下:
140
+
141
+ ```json
142
+ --parser-options=project:../tsconfig.json
143
+ ```
144
+
145
+ ![webstorm-lint-error](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/docs/webstorm-lint-error.png)
@@ -0,0 +1,12 @@
1
+ ---
2
+ type: ref
3
+ ---
4
+
5
+ # Advanced Features
6
+
7
+ This section covers advanced features of Modern.js.
8
+
9
+
10
+
11
+
12
+
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: Low-Level Tools
3
+ sidebar_position: 11
4
+ ---
5
+
6
+ ## Usage
7
+
8
+ Modern.js internally integrates tools such as [Babel](https://babeljs.io/), [TypeScript](https://www.typescriptlang.org/), [Webpack](https://webpack.js.org/), [PostCSS](https://postcss.org/), [Tailwind CSS] (https://tailwindcss.com/) by default.
9
+
10
+ Usually, the default configuration can meet most development needs. When there are special needs, it can be achieved through the underlying configuration.
11
+
12
+ Take configuring Webpack as an example, just add ['tools.webpack'] (/docs/configure/app/tools/webpack) to the modern.config.ts:
13
+
14
+ ```typescript title="modern.config.ts"
15
+ export default defineConfig({
16
+ tools: {
17
+ webpack: config => {
18
+
19
+ }
20
+ }
21
+ })
22
+ ```
23
+
24
+ Configurations in the `tools` can be set to `Object` or `Function`.
25
+
26
+ When the value is `Object`, it will be merged with the default configuration. For the specific merging strategy, refer to the configuration options document (see table below).
27
+
28
+ When the value is `Function`, the first parameter is the default configuration value. You can directly modify this object without returning it, or you can return a new object or a merged object as the final result.
29
+
30
+ ## Low-level Configuration Details
31
+
32
+ Currently provided is as follows:
33
+
34
+ | Tools | Config |
35
+ | -------- | --------- |
36
+ | DevServer | [tools.devServer](/docs/configure/app/tools/dev-server) |
37
+ | Babel | [tools.babel](/docs/configure/app/tools/babel)|
38
+ | styled-components | [tools.styledComponents](/docs/configure/app/tools/styled-components)|
39
+ | PostCSS | [tools.postcss](/docs/configure/app/tools/postcss)|
40
+ | Less | [tools.less](/docs/configure/app/tools/less) |
41
+ | Sass | [tools.sass](/docs/configure/app/tools/sass) |
42
+ | webpack | [tools.webpack](/docs/configure/app/tools/webpack)|
43
+ | Minify CSS | [tools.minifyCss](/docs/configure/app/tools/minify-css)|
44
+ | terser | [tools.terser](/docs/configure/app/tools/terser)|
45
+ | Tailwind CSS | [tools.tailwind](/docs/configure/app/tools/tailwindcss) |
46
+ | Autoprefixer | [tools.autoprefixer](/docs/configure/app/tools/autoprefixer) |