@modern-js/main-doc 2.42.0 → 2.42.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,161 @@
1
+ ---
2
+ sidebar_position: 13
3
+ ---
4
+
5
+ # Inline Static Assets
6
+
7
+ Inline static assets refer to the practice of including the content of a static asset directly in a HTML or JS file, instead of linking to an external file. This can improve the performance of a website by reducing the number of HTTP requests that the browser has to make to load the page.
8
+
9
+ However, static assets inlining also has some disadvantages, such as increasing the size of a single file, which may lead to slower loading. Therefore, in the actual scenario, it is necessary to decide whether to use static assets inlining according to the specific situation.
10
+
11
+ Modern.js will automatically inline static assets that are less than 10KB, but sometimes you may need to manually control assets to force them to be inlined or not, and this document explains how to precisely control the inlining behavior of static assets.
12
+
13
+ ## Automatic Inlining
14
+
15
+ By default, Modern.js will inline assets when the file size of is less than a threshold (the default is 10KB). When inlined, the asset will be converted to a Base64 encoded string and will no longer send a separate HTTP request. When the file size is greater than this threshold, it is loaded as a separate file with a separate HTTP request.
16
+
17
+ The threshold can be modified with the [output.dataUriLimit](/configure/app/output/data-uri-limit) config. For example, set the threshold of images to 5000 Bytes, and set media assets not to be inlined:
18
+
19
+ ```ts
20
+ export default {
21
+ output: {
22
+ dataUriLimit: {
23
+ image: 5000,
24
+ media: 0,
25
+ },
26
+ },
27
+ };
28
+ ```
29
+
30
+ ## Force Inlining
31
+
32
+ You can force an asset to be inlined by adding the `inline` query when importing the asset, regardless of whether the asset's size is smaller than the size threshold.
33
+
34
+ ```tsx
35
+ import React from 'react';
36
+ import img from '. /foo.png?inline';
37
+
38
+ export default function Foo() {
39
+ return <img src={img} />;
40
+ }
41
+ ```
42
+
43
+ In the above example, the `foo.png` image will always be inlined, regardless of whether the size of the image is larger than the threshold.
44
+
45
+ In addition to the `inline` query, you can also use the `__inline` query to force inlining of the asset:
46
+
47
+ ```tsx
48
+ import img from '. /foo.png?__inline';
49
+ ```
50
+
51
+ ### Referenced from CSS file
52
+
53
+ When you reference a static asset in your CSS file, you can also force inline the asset with the `inline` or `__inline` queries.
54
+
55
+ ```css
56
+ .foo {
57
+ background-image: url('. /icon.png?inline');
58
+ }
59
+ ```
60
+
61
+ :::tip Do you really need to force inlining?
62
+ Inline large assets will significantly increase the first paint time or first contentful paint time of a page, which will hurt user experience. And when you inline a static asset multiple times into a CSS file, the base64 content will be repeatedly injected, causing the bundle size to grow . Please use forced inlining with caution.
63
+ :::
64
+
65
+ ## Force no inlining
66
+
67
+ When you want to always treat some assets as separate files, no matter how small the asset is, you can add the `url` query to force the asset not to be inlined.
68
+
69
+ ```tsx
70
+ import React from 'react';
71
+ import img from '. /foo.png?url';
72
+
73
+ export default function Foo() {
74
+ return <img src={img} />;
75
+ }
76
+ ```
77
+
78
+ In the above example, the `foo.png` image will always be loaded as a separate file, even if the size of the image is smaller than the threshold.
79
+
80
+ In addition to the `url` query, you can also use the `__inline=false` query to force the asset not to be inlined:
81
+
82
+ ```tsx
83
+ import img from '. /foo.png?__inline=false';
84
+ ```
85
+
86
+ ### Referenced from CSS file
87
+
88
+ When you reference a static asset in your CSS file, you can also force the asset not to be inlined with `url` or `__inline=false` queries.
89
+
90
+ ```css
91
+ .foo {
92
+ background-image: url('. /icon.png?url');
93
+ }
94
+ ```
95
+
96
+ :::tip Do you really need to exclude assets from inlining?
97
+ Excluding assets from inlining will increase the number of assets that the Web App needs to load. This will reduce the efficiency of loading assets in a weak network environment or in scenarios where HTTP2 is not enabled. Please use force no Inline with caution.
98
+
99
+ ## Inline JS files
100
+
101
+ In addition to inlining static assets into JS files, Modern.js also supports inlining JS files into HTML files.
102
+
103
+ Just enable the [output.enableInlineScripts](/configure/app/output/enable-inline-scripts) config, and the generated JS files will not be written into the output directory, but will be directly inlined to the corresponding in the HTML file.
104
+
105
+ ```ts
106
+ export default {
107
+ output: {
108
+ enableInlineScripts: true,
109
+ },
110
+ };
111
+ ```
112
+
113
+ :::tip
114
+ Inline JS files may cause the single HTML file to be too large, and it will break the HTTP caching. Please use it with caution.
115
+ :::
116
+
117
+ ## Inline CSS files
118
+
119
+ You can also inline CSS files into HTML files.
120
+
121
+ Just enable the [output.enableInlineStyles](/configure/app/output/enable-inline-styles) config, the generated CSS file will not be written into the output directory, but will be directly inlined to the corresponding in the HTML file.
122
+
123
+ ```ts
124
+ export default {
125
+ output: {
126
+ enableInlineStyles: true,
127
+ },
128
+ };
129
+ ```
130
+
131
+ ## Add Type Declaration
132
+
133
+ When you use URL queries such as `?inline` and `?url` in TypeScript code, TypeScript may prompt that the module is missing a type definition:
134
+
135
+ ```
136
+ TS2307: Cannot find module './logo.png?inline' or its corresponding type declarations.
137
+ ```
138
+
139
+ To fix this, you can add type declarations for these URL queries, please create `src/global.d.ts` file and add the following type declarations:
140
+
141
+ ```ts
142
+ declare module '*?inline' {
143
+ const content: string;
144
+ export default content;
145
+ }
146
+
147
+ declare module '*?inline' {
148
+ const content: string;
149
+ export default content;
150
+ }
151
+
152
+ declare module '*?__inline' {
153
+ const content: string;
154
+ export default content;
155
+ }
156
+
157
+ declare module '*?inline=false' {
158
+ const content: string;
159
+ export default content;
160
+ }
161
+ ```
@@ -44,9 +44,9 @@ See the [performance.bundleAnalyze](/configure/app/performance/bundle-analyze.ht
44
44
 
45
45
  ## Adjust Browserslist
46
46
 
47
- The Builder will compile the code according to the project's Browserslist config, and inject some Polyfills. If the project does not need to be compatible with legacy browsers, you can adjust the Browserslist and drop some legacy browsers, thereby reducing the compilation overhead on syntax and polyfill.
47
+ Modern.js will compile the code according to the project's Browserslist config, and inject some Polyfills. If the project does not need to be compatible with legacy browsers, you can adjust the Browserslist and drop some legacy browsers, thereby reducing the compilation overhead on syntax and polyfill.
48
48
 
49
- Builder's default Browserslist config is:
49
+ Modern.js's default Browserslist config is:
50
50
 
51
51
  ```js
52
52
  ['> 0.01%', 'not dead', 'not op_mini all'];
@@ -66,7 +66,7 @@ Please read the [Browserslist](https://modernjs.dev/builder/en/guide/advanced/br
66
66
 
67
67
  When it is clear that third-party dependencies do not require additional polyfill, you can set [output.polyfill](/configure/app/output/polyfill.html) to `usage`.
68
68
 
69
- In `usage` mode, Builder analyzes the syntax used in the source code and injects the required polyfill code on demand to reduce the size of polyfill.
69
+ In `usage` mode, Modern.js analyzes the syntax used in the source code and injects the required polyfill code on demand to reduce the size of polyfill.
70
70
 
71
71
  ```js
72
72
  export default {
@@ -84,11 +84,12 @@ Please read the [Browser Compatibility](https://modernjs.dev/builder/en/guide/ad
84
84
 
85
85
  In general front-end projects, the size of image often accounts for a large proportion of the total bundle size of the project.So if the image size can be reduced as much as possible, it will have a significant optimization effect on the project bundle size. You can enable image compression by registering a plugin in the Builder:
86
86
 
87
- ```js
87
+ ```ts title="modern.config.ts"
88
88
  import { builderPluginImageCompress } from '@modern-js/builder-plugin-image-compress';
89
89
 
90
- // Add the plugin to the Builder
91
- builder.addPlugins([builderPluginImageCompress()]);
90
+ export default {
91
+ builderPlugins: [builderPluginImageCompress()],
92
+ };
92
93
  ```
93
94
 
94
95
  See details in [plugin-image-compress](https://modernjs.dev/builder/en/plugins/plugin-image-compress.html).
@@ -4,9 +4,87 @@ sidebar_position: 4
4
4
 
5
5
  # Path Alias
6
6
 
7
- import Alias from '@modern-js/builder-doc/docs/en/shared/alias';
7
+ Path aliases allow developers to define aliases for modules, making it easier to reference them in code. This can be useful when you want to use a short, easy-to-remember name for a module instead of a long, complex path.
8
8
 
9
- <Alias />
9
+ For example, if you frequently reference the `src/common/request.ts` module in your project, you can define an alias for it as `@request` and then use `import request from '@request'` in your code instead of writing the full relative path every time. This also allows you to move the module to a different location without needing to update all the import statements in your code.
10
+
11
+ In Modern.js, there are two ways to set up path aliases:
12
+
13
+ - Through the `paths` configuration in `tsconfig.json`.
14
+ - Through the [source.alias](/configure/app/source/alias) configuration.
15
+
16
+ ## Using `tsconfig.json`'s `paths` Configuration
17
+
18
+ You can configure aliases through the `paths` configuration in `tsconfig.json`, which is the recommended approach in TypeScript projects as it also resolves the TS type issues related to path aliases.
19
+
20
+ For example:
21
+
22
+ ```json title="tsconfig.json"
23
+ {
24
+ "compilerOptions": {
25
+ "paths": {
26
+ "@common/*": ["./src/common/*"]
27
+ }
28
+ }
29
+ }
30
+ ```
31
+
32
+ After configuring, if you reference `@common/Foo.tsx` in your code, it will be mapped to the `<project>/src/common/Foo.tsx` path.
33
+
34
+ :::tip
35
+ You can refer to the [TypeScript - paths](https://www.typescriptlang.org/tsconfig#paths) documentation for more details.
36
+ :::
37
+
38
+ ## Use `source.alias` Configuration
39
+
40
+ Modern.js provides the [source.alias](/configure/app/source/alias) configuration option, which corresponds to the webpack/Rspack native [resolve.alias](https://webpack.js.org/configuration/resolve/#resolvealias) configuration. You can configure this option using an object or a function.
41
+
42
+ ### Use Cases
43
+
44
+ Since the `paths` configuration in `tsconfig.json` is written in a static JSON file, it lacks dynamism.
45
+
46
+ The `source.alias` configuration can address this limitation by allowing you to dynamically set the `source.alias` using JavaScript code, such as based on environment variables.
47
+
48
+ ### Object Usage
49
+
50
+ You can configure `source.alias` using an object, where the relative paths will be automatically resolved to absolute paths.
51
+
52
+ For example:
53
+
54
+ ```js
55
+ export default {
56
+ source: {
57
+ alias: {
58
+ '@common': './src/common',
59
+ },
60
+ },
61
+ };
62
+ ```
63
+
64
+ After configuring, if you reference `@common/Foo.tsx` in your code, it will be mapped to the `<project>/src/common/Foo.tsx` path.
65
+
66
+ ### Function Usage
67
+
68
+ You can also configure `source.alias` as a function, which receives the built-in `alias` object and allows you to modify it.
69
+
70
+ For example:
71
+
72
+ ```js
73
+ export default {
74
+ source: {
75
+ alias: alias => {
76
+ alias['@common'] = './src/common';
77
+ return alias;
78
+ },
79
+ },
80
+ };
81
+ ```
82
+
83
+ ### Priority
84
+
85
+ The `paths` configuration in `tsconfig.json` takes precedence over the `source.alias` configuration. When a path matches the rules defined in both `paths` and `source.alias`, the value defined in `paths` will be used.
86
+
87
+ You can adjust the priority of these two options using [source.aliasStrategy](/configure/app/source/alias-strategy).
10
88
 
11
89
  ## Default Aliases
12
90
 
@@ -0,0 +1,228 @@
1
+ ---
2
+ sidebar_position: 14
3
+ ---
4
+
5
+ # Use CSS Modules
6
+
7
+ [CSS Modules](https://github.com/css-modules/css-modules) allows us to write CSS code in a modular way, and these styles can be imported and used in JavaScript files. Using CSS Modules can automatically generate unique class names, isolate styles between different modules, and avoid class name conflicts.
8
+
9
+ Builder supports CSS Modules by default, you don't need to add additional configuration. Our convention is to use the `[name].module.css` filename to enable CSS Modules.
10
+
11
+ The following style files are considered CSS Modules:
12
+
13
+ - `*.module.scss`
14
+ - `*.module.less`
15
+ - `*.module.css`
16
+
17
+ ## Example
18
+
19
+ - Write style:
20
+
21
+ ```css
22
+ /* button.module.css */
23
+ .error {
24
+ background: red;
25
+ }
26
+ ```
27
+
28
+ - Using styles:
29
+
30
+ ```tsx
31
+ // Button.tsx
32
+ import React, { Component } from 'react';
33
+ // import style file
34
+ import styles from './button.module.css';
35
+
36
+ export default () => {
37
+ return <button className={styles.error}>Error Button</button>;
38
+ };
39
+ ```
40
+
41
+ ## Enable CSS Modules for all CSS files
42
+
43
+ By default, only files ending in `*.module.css` are treated CSS Modules.
44
+
45
+ If you want to treat all CSS files in the source directory as CSS Modules, you can enable the [output.disableCssModuleExtension](/configure/app/output/disable-css-module-extension) config, for example:
46
+
47
+ ```ts
48
+ export default {
49
+ output: {
50
+ disableCssModuleExtension: true,
51
+ },
52
+ };
53
+ ```
54
+
55
+ When set, the following two files are treated as CSS Modules:
56
+
57
+ ```ts
58
+ import styles1 from './foo.module.css';
59
+ import styles2 from './bar.css';
60
+ ```
61
+
62
+ :::tip
63
+ We do not recommend enabling this config, because after enabling disableCssModuleExtension, CSS Modules files and ordinary CSS files cannot be clearly distinguished, which is not conducive to long-term maintenance.
64
+ :::
65
+
66
+ ## Enable CSS Modules for the specified style file
67
+
68
+ By default, only files ending in `*.module.css` are treated CSS Modules.
69
+
70
+ If you want to enable CSS Modules only for specified style files, you can configure [output.cssModules](/configure/app/output/css-modules), for example:
71
+
72
+ ```ts
73
+ export default {
74
+ output: {
75
+ cssModules: {
76
+ auto: resource => {
77
+ return resource.includes('.module.') || resource.includes('shared/');
78
+ },
79
+ },
80
+ },
81
+ };
82
+ ```
83
+
84
+ ## Custom Class Names
85
+
86
+ Customizing the class names generated by CSS Modules is also a commonly used function, you can use [output.cssModuleLocalIdentName](/configure/app/output/css-modules.html#cssmodulesexportlocalsconvention) to configure it.
87
+
88
+ ```ts
89
+ export default {
90
+ output: {
91
+ cssModuleLocalIdentName: '[hash:base64:4]',
92
+ },
93
+ };
94
+ ```
95
+
96
+ If you need to customize other configs of CSS Modules, you can set them via [tools.cssLoader](/configure/app/tools/css-loader).
97
+
98
+ ## Add Type Declaration
99
+
100
+ When you import CSS Modules in TypeScript code, TypeScript may prompt that the module is missing a type definition:
101
+
102
+ ```
103
+ TS2307: Cannot find module './index.module.css' or its corresponding type declarations.
104
+ ```
105
+
106
+ To fix this, you need to add a type declaration file for the CSS Modules, please create a `src/global.d.ts` file, and add the corresponding type declaration:
107
+
108
+ ```ts title="src/global.d.ts"
109
+ declare module '*.module.css' {
110
+ const classes: { readonly [key: string]: string };
111
+ export default classes;
112
+ }
113
+
114
+ declare module '*.module.scss' {
115
+ const classes: { readonly [key: string]: string };
116
+ export default classes;
117
+ }
118
+
119
+ declare module '*.module.sass' {
120
+ const classes: { readonly [key: string]: string };
121
+ export default classes;
122
+ }
123
+
124
+ declare module '*.module.less' {
125
+ const classes: { readonly [key: string]: string };
126
+ export default classes;
127
+ }
128
+
129
+ declare module '*.module.styl' {
130
+ const classes: { readonly [key: string]: string };
131
+ export default classes;
132
+ }
133
+ ```
134
+
135
+ If you enabled the `disableCssModuleExtension` config, you also need to add the following types:
136
+
137
+ ```ts title="src/global.d.ts"
138
+ declare module '*.css' {
139
+ const classes: { readonly [key: string]: string };
140
+ export default classes;
141
+ }
142
+
143
+ declare module '*.scss' {
144
+ const classes: { readonly [key: string]: string };
145
+ export default classes;
146
+ }
147
+
148
+ declare module '*.sass' {
149
+ const classes: { readonly [key: string]: string };
150
+ export default classes;
151
+ }
152
+
153
+ declare module '*.less' {
154
+ const classes: { readonly [key: string]: string };
155
+ export default classes;
156
+ }
157
+
158
+ declare module '*.styl' {
159
+ const classes: { readonly [key: string]: string };
160
+ export default classes;
161
+ }
162
+ ```
163
+
164
+ After adding the type declaration, if the type error still exists, you can try to restart the current IDE, or adjust the directory where `global.d.ts` is located, making sure the TypeScript can correctly identify the type definition.
165
+
166
+ ## Generate exact type definitions
167
+
168
+ Although the above method can provide the type of CSS Modules, it cannot accurately prompt which classNames are exported by a certain CSS file.
169
+
170
+ Builder supports generating accurate type declarations for CSS Modules, you only need to enable the [output.enableCssModuleTSDeclaration](/configure/app/output/enable-css-module-tsdeclaration) config, and then execute the build, Modern.js will generate type declaration files for all CSS Modules.
171
+
172
+ ```ts
173
+ export default {
174
+ output: {
175
+ enableCssModuleTSDeclaration: true,
176
+ },
177
+ };
178
+ ```
179
+
180
+ ### Example
181
+
182
+ For example, there are two files `src/index.ts` and `src/index.module.scss` under a certain folder:
183
+
184
+ ```tsx title="src/index.ts"
185
+ import styles from './index.module.scss';
186
+
187
+ export default () => {
188
+ <div>
189
+ <div className={styles.pageHeader}>Page Header</div>
190
+ </div>;
191
+ };
192
+ ```
193
+
194
+ ```scss title="src/index.module.scss"
195
+ .page-header {
196
+ color: black;
197
+ }
198
+ ```
199
+
200
+ After executing the build, the `src/index.module.scss.d.ts` type declaration file will be automatically generated:
201
+
202
+ ```ts title="src/index.module.scss.d.ts"
203
+ // This file is automatically generated.
204
+ // Please do not change this file!
205
+ interface CssExports {
206
+ 'page-header': string;
207
+ pageHeader: string;
208
+ }
209
+ export const cssExports: CssExports;
210
+ export default cssExports;
211
+ ```
212
+
213
+ Then open the `src/index.ts` file again, you will see that the `styles` object already has a exact type.
214
+
215
+ ### Related configuration
216
+
217
+ In the above example, `src/index.module.scss.d.ts` is generated by compilation, you can choose to commit them to the Git repository, or you can choose to ignore them in the `.gitignore` file:
218
+
219
+ ```bash
220
+ # Ignore auto generated CSS declarations
221
+ *.module.css.d.ts
222
+ *.module.sass.d.ts
223
+ *.module.scss.d.ts
224
+ *.module.less.d.ts
225
+ *.module.styl.d.ts
226
+ ```
227
+
228
+ In addition, if the generated code causes ESLint to report errors, you can also add the above configuration to the `.eslintignore` file.
@@ -0,0 +1,106 @@
1
+ ---
2
+ sidebar_position: 12
3
+ ---
4
+
5
+ # Import JSON Files
6
+
7
+ Modern.js supports import JSON files in code, and also supports import [YAML](https://yaml.org/) and [Toml](https://toml.io/en/) files and converting them to JSON format.
8
+
9
+ ## JSON file
10
+
11
+ You can import JSON files directly in JavaScript files.
12
+
13
+ ### Example
14
+
15
+ ```json title="example.json"
16
+ {
17
+ "name": "foo",
18
+ "items": [1, 2]
19
+ }
20
+ ```
21
+
22
+ ```js title="index.js"
23
+ import example from './example.json';
24
+
25
+ console.log(example.name); // 'foo';
26
+ console.log(example.items); // [1, 2];
27
+ ```
28
+
29
+ ### Named Import
30
+
31
+ Modern.js does not support importing JSON files via named import yet:
32
+
33
+ ```js
34
+ import { name } from './example.json';
35
+ ```
36
+
37
+ ## YAML file
38
+
39
+ YAML is a data serialization language commonly used for writing configuration files.
40
+
41
+ You can directly import `.yaml` or `.yml` files in JavaScript and they will be automatically converted to JSON format.
42
+
43
+ ### Example
44
+
45
+ ```yaml title="example.yaml"
46
+ ---
47
+ hello: world
48
+ foo:
49
+ bar: baz
50
+ ```
51
+
52
+ ```js
53
+ import example from './example.yaml';
54
+
55
+ console.log(example.hello); // 'world';
56
+ console.log(example.foo); // { bar: 'baz' };
57
+ ```
58
+
59
+ ### Add type declaration
60
+
61
+ When you import a YAML file in your TypeScript code, please create a `src/global.d.ts` file in your project and add the corresponding type declaration:
62
+
63
+ ```ts title="src/global.d.ts"
64
+ declare module '*.yaml' {
65
+ const content: Record<string, any>;
66
+ export default content;
67
+ }
68
+
69
+ declare module '*.yml' {
70
+ const content: Record<string, any>;
71
+ export default content;
72
+ }
73
+ ```
74
+
75
+ ## Toml file
76
+
77
+ Toml is a semantically explicit, easy-to-read configuration file format.
78
+
79
+ You can directly import `.toml` files in JavaScript and it will be automatically converted to JSON format.
80
+
81
+ ### Example
82
+
83
+ ```toml title="example.toml"
84
+ hello = "world"
85
+
86
+ [foo]
87
+ bar = "baz"
88
+ ```
89
+
90
+ ```js
91
+ import example from './example.toml';
92
+
93
+ console.log(example.hello); // 'world';
94
+ console.log(example.foo); // { bar: 'baz' };
95
+ ```
96
+
97
+ ### Add type declaration
98
+
99
+ When you import Toml files in TypeScript code, please create a `src/global.d.ts` file in your project and add the corresponding type declarations:
100
+
101
+ ```ts title="src/global.d.ts"
102
+ declare module '*.toml' {
103
+ const content: Record<string, any>;
104
+ export default content;
105
+ }
106
+ ```