diff --git a/tests/integration/asset/__snapshots__/index.test.ts.snap b/tests/integration/asset/__snapshots__/index.test.ts.snap index 800bcb601..0e589033d 100644 --- a/tests/integration/asset/__snapshots__/index.test.ts.snap +++ b/tests/integration/asset/__snapshots__/index.test.ts.snap @@ -13,7 +13,14 @@ export { draft_rslib_entry_namespaceObject as default }; `; exports[`use json 1`] = ` -"JSON.parse('{"foo":1,"bar":["2"]}'); +"var data_namespaceObject = { + R: 1, + K: [ + "2" + ] +}; +console.log(data_namespaceObject.R); +console.log(data_namespaceObject.K); " `; diff --git a/tests/integration/asset/json/src/index.js b/tests/integration/asset/json/src/index.js index c14c58d2a..fff715a3c 100644 --- a/tests/integration/asset/json/src/index.js +++ b/tests/integration/asset/json/src/index.js @@ -1,3 +1,4 @@ -import a from './assets/data.json'; +import { bar, foo } from './assets/data.json'; -a; +console.log(foo); +console.log(bar); diff --git a/website/docs/en/config/rsbuild/output.mdx b/website/docs/en/config/rsbuild/output.mdx index d0b0123c8..6f140e0a2 100644 --- a/website/docs/en/config/rsbuild/output.mdx +++ b/website/docs/en/config/rsbuild/output.mdx @@ -4,9 +4,11 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge'; Options for build outputs. -{/* ## output.assetPrefix */} +## output.assetPrefix -{/* In [production mode](https://rsbuild.dev/config/mode), use this option to set the URL prefix for static assets, such as setting it to a CDN URL. */} +Use this option to set the URL prefix for static assets, such as setting it to a CDN URL. + +When [format](/config/lib/format) is set to `cjs` or `esm`, Rslib defaults to setting `output.assetPrefix` to `"auto"`. ## output.charset @@ -28,6 +30,8 @@ For custom CSS Modules configuration. Set the size threshold to inline static assets such as images and fonts. +When [format](/config/lib/format) is set to `cjs` or `esm`, Rslib defaults to setting `output.dataUriLimit` to `0`, without inlining any static assets, so that build tools on the application side can handle and optimize them. + ## output.distPath Set the directory of the dist files. Rsbuild will output files to the corresponding subdirectory according to the file type. diff --git a/website/docs/en/guide/advanced/_meta.json b/website/docs/en/guide/advanced/_meta.json index c9bbf4c49..58d2ca213 100644 --- a/website/docs/en/guide/advanced/_meta.json +++ b/website/docs/en/guide/advanced/_meta.json @@ -2,6 +2,9 @@ "third-party-deps", "output-compatibility", "dts", + "static-assets", + "svgr-files", + "json-files", "module-federation", "storybook" ] diff --git a/website/docs/en/guide/advanced/json-files.mdx b/website/docs/en/guide/advanced/json-files.mdx new file mode 100644 index 000000000..5b89694c7 --- /dev/null +++ b/website/docs/en/guide/advanced/json-files.mdx @@ -0,0 +1,106 @@ +# Import JSON files + +Rslib supports import JSON files in code. + +## JSON file + +You can directly import JSON files in JavaScript files. + +:::warning + +In bundle mode, JSON files support both default and named import. + +In bundleless mode, JSON files only support named import. + +::: + +### Default import + +```json title="example.json" +{ + "name": "foo", + "items": [1, 2] +} +``` + +```js title="index.js" +import example from './example.json'; + +console.log(example.name); // 'foo'; +console.log(example.items); // [1, 2]; +``` + +### Named import + +Rslib also supports importing JSON files through named import. + +Here is an example, assuming the source code is as follows: + +import { Tabs, Tab } from '@theme'; + + + + +```js +import { name } from './example.json'; + +console.log(name); // 'foo'; +``` + + + + +```json +{ + "name": "foo", + "items": [1, 2] +} +``` + + + + +Based on the configuration in the [output structure](/guide/basic/output-structure) specified in the configuration file, the following outputs will be emitted: + + + + + + +```tsx +var example_namespaceObject = { + u: 'foo', +}; +console.log(example_namespaceObject.u); +``` + + + + + + + + + + +```tsx +import * as example from './example.js'; + +console.log(example.name); +``` + + + + +```tsx +var example_namespaceObject = JSON.parse('{"name":"foo","items":[1,2]}'); +var __webpack_exports__items = example_namespaceObject.items; +var __webpack_exports__name = example_namespaceObject.name; +export { __webpack_exports__items as items, __webpack_exports__name as name }; +``` + + + + + + diff --git a/website/docs/en/guide/advanced/static-assets.mdx b/website/docs/en/guide/advanced/static-assets.mdx new file mode 100644 index 000000000..69df68e2a --- /dev/null +++ b/website/docs/en/guide/advanced/static-assets.mdx @@ -0,0 +1,295 @@ +# Import static assets + +Rslib supports import static assets, including images, fonts, audio and video. + +## Assets format + +The following are the formats supported by Rslib by default: + +- **images**: png, jpg, jpeg, gif, svg, bmp, webp, ico, apng, avif, tif, tiff, jfif, pjpeg, pjp, cur. +- **fonts**: woff, woff2, eot, ttf, otf, ttc. +- **audio**: mp3, wav, flac, aac, m4a, opus. +- **video**: mp4, webm, ogg, mov. + +To import assets in other formats, refer to [Extend Asset Types](#extend-asset-types). + +## Import assets in JS file + +In JS files, you can directly import static assets with relative paths through `import`: + +```tsx +// Import the logo.png image in the 'src/assets' directory +import logo from './assets/logo.png'; + +console.log(logo); // "/static/logo.[hash].png" + +export default = () => ; +``` + +Import with **alias** is also available: + +```tsx +import logo from '@/assets/logo.png'; + +console.log(logo); // "/static/logo.[hash].png" + +export default = () => ; +``` + +When the [format](/config/lib/format) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and transforms the source file into a JS file and a static asset file that is emitted according to [output.distPath](/config/rsbuild/output#outputdistpath) by default, which is used to preserve the `import` statements for static assets. + +The following is an example of usage, assuming the source code is as follows: + +import { Tabs, Tab } from '@theme'; + + + + +```tsx +import logo from './assets/logo.svg'; + +console.log(logo); +``` + + + + + + + +Based on the configuration in the [output structure](/guide/basic/output-structure) in the configuration file, the following outputs will be emitted: + + + + + + +```tsx +import logo_rslib_entry_namespaceObject from './static/svg/logo.svg'; + +console.log(logo_rslib_entry_namespaceObject); +``` + + + + + + + + + + + + + +```tsx +import logo from './assets/logo.mjs'; + +console.log(logo); +``` + + + + +```tsx +import logo_rslib_entry_namespaceObject from '../static/svg/logo.svg'; +export { logo_rslib_entry_namespaceObject as default }; +``` + + + + + + + + + + +## Import assets in CSS file + +In CSS files, you can import static assets with relative paths: + +```css title="src/index.css" +.logo { + background-image: url('./assets/logo.png'); +} +``` + +Import with **alias** are also supported: + +```css title="src/index.css" +.logo { + background-image: url('@/assets/logo.png'); +} +``` + +When the [format](/config/lib/format) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and preserves relative reference paths in CSS outputs by default via setting [output.assetPrefix](/config/rsbuild/output#outputassetprefix) to `"auto"`. + +The following is an example of usage, assuming the source code is as follows: + + + + +```css +.logo { + background-image: url('./assets/logo.png'); +} +``` + + + + + + + +The following output will be emitted: + + + + + +```css +.logo { + background-image: url('./static/image/logo.png'); +} +``` + + + + + + + + + +--- + +### Ignore some assets imported in CSS + +If you need to import a static asset with an absolute path in a CSS file: + +```css +@font-face { + font-family: DingTalk; + src: url('/image/font/foo.ttf'); +} +``` + +By default, the built-in `css-loader` in Rslib will resolve absolute paths in `url()` and look for the specified modules. If you want to skip resolving absolute paths, you can configure [`tools.cssLoader`](/config/rsbuild/tools#toolscssloader) to filter out the specified paths. The filtered paths are preserved as they are in the code. + +```ts +export default { + tools: { + cssLoader: { + url: { + filter: (url) => { + if (/\/image\/font/.test(url)) { + return false; + } + return true; + }, + }, + }, + }, +}; +``` + +## Inline static assets + +When the [format](/config/lib/format) is set to `cjs` or `esm`, Rslib treats the output as an mid-level artifact that will be consumed by other build tools again and sets [output.dataUriLimit](/config/rsbuild/output#outputdataurilimit) to `0` by default to not inline any static assets. + +## Build output directory + +Once static assets are imported, they will automatically be output to the build output directory. You can: + +- Modify the filename of the outputs through [output.filename](/config/rsbuild/output#outputfilename). +- Change the output path of the outputs through [output.distPath](/config/rsbuild/output#outputdistpath). + +## Type declaration + +When you import static assets in TypeScript code, TypeScript may prompt that the module is missing a type definition: + +``` +TS2307: Cannot find module './logo.png' or its corresponding type declarations. +``` + +To fix this, you need to add a type declaration file for the static assets, please create a `src/env.d.ts` file, and add the corresponding type declaration. + +- Method 1: If the `@rslib/core` package is installed, you can reference the **preset types** provided by `@rslib/core`: + +```ts +/// +``` + +- Method 2: Manually add the required type declarations: + +```ts title="src/env.d.ts" +// Taking png images as an example +declare module '*.png' { + const content: string; + export default content; +} +``` + +After adding the type declaration, if the type error still exists, you can try to restart the current IDE, or adjust the directory where `env.d.ts` is located, making sure the TypeScript can correctly identify the type definition. + +## Extend asset types + +If the built-in static assets type of Rslib does not meet your needs, you can extend the additional static assets type in the following ways. + +### Use `source.assetsInclude` + +By using the [source.assetsInclude](/config/rsbuild/source#sourceassetsinclude) config, you can specify additional file types to be treated as static assets. + +```ts title="rslib.config.ts" +export default { + source: { + assetsInclude: /\.pdf$/, + }, +}; +``` + +After adding the above configuration, you can import `*.pdf` files in your code, for example: + +```js +import myFile from './static/myFile.pdf'; + +console.log(myFile); +``` + +### Use `tools.rspack` + +You can modify the built-in Rspack configuration and add custom static assets handling rules via [tools.rspack](/config/rsbuild/tools#toolsrspack). + +For example, to treat `*.pdf` files as assets and output them to the dist directory, you can add the following configuration: + +```ts title="rslib.config.ts" +export default { + tools: { + rspack(config, { addRules }) { + addRules([ + { + test: /\.pdf$/, + // Convert assets to separate files and keep import statements + type: 'asset/resource', + generator: { + importMode: 'preserve', + }, + }, + ]); + }, + }, +}; +``` + +For more information about asset modules, please refer to [Rspack - Asset modules](https://rspack.dev/guide/features/asset-module). diff --git a/website/docs/en/guide/advanced/svgr-files.mdx b/website/docs/en/guide/advanced/svgr-files.mdx new file mode 100644 index 000000000..b52cc365d --- /dev/null +++ b/website/docs/en/guide/advanced/svgr-files.mdx @@ -0,0 +1,107 @@ +# Import SVGR + +By default, Rslib treats SVG images as static assets. + +By adding the [@rsbuild/plugin-svgr](https://rsbuild.dev/plugins/list/plugin-svgr) plugin, Rslib supports transforming SVG to React components via [SVGR](https://react-svgr.com/). + +## Quick start + +### Install the plugin + +You can install the plugin using the following command: + +import { PackageManagerTabs } from '@theme'; + + + +### Register the plugin + +You can register the plugin in the `rslib.config.ts` file: + +```ts title="rslib.config.ts" +import { pluginSvgr } from '@rsbuild/plugin-svgr'; + +export default { + plugins: [pluginSvgr()], +}; +``` + +## Examples + +### Bundle mode + +In bundle mode, all usages supported by [@rsbuild/plugin-svgr](https://rsbuild.dev/plugins/list/plugin-svgr) are available in Rslib. The only difference is that when using an SVG file in URL form, Rslib will retain the `import` statement for the static asset in the output according to [Import static assets](/guide/advanced/static-assets). + +Here is an example of usage: + +```jsx title="App.jsx" +import Logo from './logo.svg?react'; + +export const App = () => ; +``` + +If the import path does not include the `?react` suffix, the SVG will be treated as a normal static asset, and the `import` statement for the static asset will be retained. + +`@rsbuild/plugin-svgr` also supports default imports and mixed imports: + +```js +import logoURL from './static/logo.svg'; + +console.log(logoURL); +``` + +`@rsbuild/plugin-svgr` also supports default import and mixed import: + +- Enable default import by setting [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'default'`. +- Enable mixed import through the [mixedImport](https://rsbuild.dev/plugins/list/plugin-svgr#mixedimport) option to use both default and named import. + +### Bundleless mode + +In bundleless mode, since each file undergoes code transformation independently, the import ways of `?react` and `?url` are not supported. However, the following two usage forms are supported: + +#### Named import + +`@rsbuild/plugin-svgr` supports named import of `ReactComponent` to use SVGR. You need to set [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'named'`. + +```js +pluginSvgr({ + svgrOptions: { + exportType: 'named', + }, +}); +``` + +```jsx title="App.jsx" +import { ReactComponent as Logo } from './logo.svg'; + +export const App = () => ; +``` + +All `.svg` files will be transformed into React components. At this time, you can: + +- Exclude files that do not need to be transformed by setting [exclude](https://rsbuild.dev/plugins/list/plugin-svgr#exclude). +- Change to default export by setting [svgrOptions.exportType](https://rsbuild.dev/plugins/list/plugin-svgr#svgroptionsexporttype) to `'default'`. + +#### Mixed import + +If your library has both URL and React component import forms for SVG files, you can also use mixed import. + +```ts +pluginSvgr({ + mixedImport: true, + svgrOptions: { + exportType: 'named', + }, +}); +``` + +At this time, the imported SVG file will export both the URL and the React component. + +```js +import logoUrl, { ReactComponent as Logo } from './logo.svg'; + +console.log(logoUrl); // -> string +console.log(Logo); // -> React component +``` + +For more information, refer to the [mixedImport](https://rsbuild.dev/plugins/list/plugin-svgr#mixedimport) option. diff --git a/website/docs/zh/config/rsbuild/output.mdx b/website/docs/zh/config/rsbuild/output.mdx index 75e76d398..f9c216aff 100644 --- a/website/docs/zh/config/rsbuild/output.mdx +++ b/website/docs/zh/config/rsbuild/output.mdx @@ -4,6 +4,12 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge'; 与构建产物相关的选项。 +## output.assetPrefix + +使用该选项设置静态资源的 URL 前缀,比如设置为 CDN 地址。 + +在 [format](/config/lib/format) 为 `cjs` 或 `esm` 时,Rslib 默认会将 `output.assetPrefix` 设置为 `"auto"`。 + ## output.charset 指定输出文件的 [字符编码](https://developer.mozilla.org/en-US/docs/Glossary/Character_encoding),以确保它们在不同的环境中能够正确显示。 @@ -24,6 +30,8 @@ import { RsbuildDocBadge } from '@components/RsbuildDocBadge'; 设置图片、字体、媒体等静态资源被自动内联为 base64 的体积阈值。 +在 [format](/config/lib/format) 为 `cjs` 或 `esm` 时,Rslib 默认会将 `output.dataUriLimit` 设置为 `0`,不内联任何静态资源,以便于应用侧的构建工具处理和优化。 + ## output.distPath 设置构建产物的输出目录,Rsbuild 会根据产物的类型输出到对应的子目录下。 diff --git a/website/docs/zh/guide/advanced/_meta.json b/website/docs/zh/guide/advanced/_meta.json index c9bbf4c49..58d2ca213 100644 --- a/website/docs/zh/guide/advanced/_meta.json +++ b/website/docs/zh/guide/advanced/_meta.json @@ -2,6 +2,9 @@ "third-party-deps", "output-compatibility", "dts", + "static-assets", + "svgr-files", + "json-files", "module-federation", "storybook" ] diff --git a/website/docs/zh/guide/advanced/json-files.mdx b/website/docs/zh/guide/advanced/json-files.mdx new file mode 100644 index 000000000..478a93295 --- /dev/null +++ b/website/docs/zh/guide/advanced/json-files.mdx @@ -0,0 +1,103 @@ +# 引用 JSON 文件 + +Rslib 支持在代码中引用 JSON 文件。 + +## JSON 文件 + +你可以直接在 JavaScript 文件中引用 JSON 文件。 + +:::warning + +在 bundle 模式下,JSON 文件支持默认引用和具名引用。 + +在 bundleless 模式下,JSON 文件仅支持具名引用。 + +::: + +### 默认引用 + +```json title="example.json" +{ + "name": "foo", + "items": [1, 2] +} +``` + +```js title="index.js" +import example from './example.json'; + +console.log(example.name); // 'foo'; +console.log(example.items); // [1, 2]; +``` + +### 具名引用 + +Rslib 同样支持通过 named import 来引用 JSON 文件。 + +下面是一个使用示例,假设源码如下: + +import { Tabs, Tab } from '@theme'; + + + + +```js +import { name } from './example.json'; + +console.log(name); // 'foo'; +``` + + + + +```json +{ + "name": "foo", + "items": [1, 2] +} +``` + + + + +会根据配置文件中的 [产物结构](/guide/basic/output-structure) 配置,输出如下产物: + + + + + +```tsx +var example_namespaceObject = { + u: 'foo', +}; +console.log(example_namespaceObject.u); +``` + + + + + + + + + + +```tsx +import * as example from './example.js'; + +console.log(example.name); +``` + + + +```tsx +var example_namespaceObject = JSON.parse('{"name":"foo","items":[1,2]}'); +var __webpack_exports__items = example_namespaceObject.items; +var __webpack_exports__name = example_namespaceObject.name; +export { __webpack_exports__items as items, __webpack_exports__name as name }; +``` + + + + + diff --git a/website/docs/zh/guide/advanced/static-assets.mdx b/website/docs/zh/guide/advanced/static-assets.mdx new file mode 100644 index 000000000..9b5483938 --- /dev/null +++ b/website/docs/zh/guide/advanced/static-assets.mdx @@ -0,0 +1,295 @@ +# 引用静态资源 + +Rslib 支持在代码中引用图片、字体、音频、视频等类型的静态资源。 + +## 静态资源格式 + +以下是 Rslib 默认支持的静态资源格式: + +- **图片**:png、jpg、jpeg、gif、svg、bmp、webp、ico、apng、avif、tif、tiff、jfif、pjpeg、pjp、cur。 +- **字体**:woff、woff2、eot、ttf、otf、ttc。 +- **音频**:mp3、wav、flac、aac、m4a、opus。 +- **视频**:mp4、webm、ogg、mov。 + +如果你需要引用其他格式的静态资源,请参考 [扩展静态资源类型](#扩展静态资源类型)。 + +## 在 JS 文件中引用 + +在 JS 文件中,可以直接通过 `import` 的方式引用相对路径下的静态资源: + +```tsx +// 引用 src/assets 目录下的 logo.png 图片 +import logo from './assets/logo.png'; + +console.log(logo); // "/static/logo.[hash].png" + +export default = () => ; +``` + +也可以使用**路径别名**来引用: + +```tsx +import logo from '@/assets/logo.png'; + +console.log(logo); // "/static/logo.[hash].png" + +export default = () => ; +``` + +在 [format](/config/lib/format) 为 `cjs` 或 `esm` 时,Rslib 将产物视为会被其他打包工具再次消费的中间产物,默认会在代码转换时将源文件转化为一个 JS 文件和一个根据 [output.distPath](/config/rsbuild/output#outputdistpath) 输出的静态资源文件,从而保留引用静态资源的 `import` 语句。 + +下面是一个使用示例,假设源码如下: + +import { Tabs, Tab } from '@theme'; + + + + +```tsx +import logo from './assets/logo.svg'; + +console.log(logo); +``` + + + + + + + +会根据配置文件中的 [产物结构](/guide/basic/output-structure) 配置,输出如下产物: + + + + + + +```tsx +import logo_rslib_entry_namespaceObject from './static/svg/logo.svg'; + +console.log(logo_rslib_entry_namespaceObject); +``` + + + + + + + + + + + + + +```tsx +import logo from './assets/logo.mjs'; + +console.log(logo); +``` + + + + +```tsx +import logo_rslib_entry_namespaceObject from '../static/svg/logo.svg'; +export { logo_rslib_entry_namespaceObject as default }; +``` + + + + + + + + + + +## 在 CSS 文件中引用 + +在 CSS 文件中,可以引用相对路径下的静态资源: + +```css title="src/index.css" +.logo { + background-image: url('./assets/logo.png'); +} +``` + +也支持使用**路径别名**来引用: + +```css title="src/index.css" +.logo { + background-image: url('@/assets/logo.png'); +} +``` + +在 [format](/config/lib/format) 为 `cjs` 或 `esm` 时,Rslib 将产物视为会被其他打包工具再次消费的中间产物,默认会将 [output.assetPrefix](/config/rsbuild/output#outputassetprefix) 设置为 `"auto"` 来使 CSS 产物中保留相对引用路径。 + +下面是一个使用示例,假设源码如下: + + + + +```css +.logo { + background-image: url('./assets/logo.png'); +} +``` + + + + + + + +会输出如下产物: + + + + + +```css +.logo { + background-image: url('./static/image/logo.png'); +} +``` + + + + + + + + + +--- + +### 在 CSS 中忽略某些文件引用 + +如果需要在 CSS 文件中引用绝对路径下的静态资源: + +```css +@font-face { + font-family: DingTalk; + src: url('/image/font/foo.ttf'); +} +``` + +默认情况下,Rslib 内置的 `css-loader` 会解析 `url()` 中的绝对路径并寻找指定的模块。如果你希望跳过绝对路径的解析,可以配置 [`tools.cssLoader`](/config/rsbuild/tools#toolscssloader) 来过滤指定的路径,被过滤的路径将被原样保留在代码中。 + +```ts +export default { + tools: { + cssLoader: { + url: { + filter: (url) => { + if (/\/image\/font/.test(url)) { + return false; + } + return true; + }, + }, + }, + }, +}; +``` + +## 静态资源内联 + +在 [format](/config/lib/format) 为 `cjs` 或 `esm` 时,Rslib 将产物视为会被其他打包工具再次消费的中间产物,默认会将 [output.dataUriLimit](/config/rsbuild/output#outputdataurilimit) 设置为 `0` 以不内联任何静态资源。 + +## 构建产物目录 + +当静态资源被引用后,会自动被输出到构建产物的目录下,你可以: + +- 通过 [output.filename](/config/rsbuild/output#outputfilename) 来修改产物的文件名。 +- 通过 [output.distPath](/config/rsbuild/output#outputdistpath) 来修改产物的输出路径。 + +## 类型声明 + +当你在 TypeScript 代码中引用静态资源时,TypeScript 可能会提示该模块缺少类型定义: + +``` +TS2307: Cannot find module './logo.png' or its corresponding type declarations. +``` + +此时你需要为静态资源添加类型声明文件,请在项目中创建 `src/env.d.ts` 文件,并添加相应的类型声明。 + +- 方法一:如果项目里安装了 `@rslib/core` 包,你可以直接引用 `@rslib/core` 提供的**预设类型**: + +```ts +/// +``` + +- 方法二:手动添加需要的类型声明: + +```ts title="src/env.d.ts" +// 以 png 图片为例 +declare module '*.png' { + const url: string; + export default url; +} +``` + +添加类型声明后,如果依然存在上述错误提示,请尝试重启当前 IDE,或者调整 `env.d.ts` 所在的目录,使 TypeScript 能够正确识别类型定义。 + +## 扩展静态资源类型 + +如果 Rslib 内置的静态资源类型不能满足你的需求,可以通过以下方式扩展额外的静态资源类型。 + +### 使用 `source.assetsInclude` + +通过 [source.assetsInclude](/config/rsbuild/source#sourceassetsinclude) 配置项,你可以指定需要被视为静态资源的额外文件类型。 + +```ts title="rslib.config.ts" +export default { + source: { + assetsInclude: /\.pdf$/, + }, +}; +``` + +添加以上配置后,你就可以在代码里引用 `*.pdf` 文件了,比如: + +```js +import myFile from './static/myFile.pdf'; + +console.log(myFile); // "/static/assets/myFile.[hash].pdf" +``` + +### 使用 `tools.rspack` + +可以通过 [tools.rspack](/config/rsbuild/tools#toolsrspack) 来修改内置的 Rspack 配置,并添加自定义的静态资源处理规则。 + +比如,把 `*.pdf` 文件当做静态资源输出到产物目录,可以添加以下配置: + +```ts title="rslib.config.ts" +export default { + tools: { + rspack(config, { addRules }) { + addRules([ + { + test: /\.pdf$/, + // 将资源转换为单独的文件,并且保留 import 语句 + type: 'asset/resource', + generator: { + importMode: 'preserve', + }, + }, + ]); + }, + }, +}; +``` + +关于资源模块的更多介绍,请参考 [Rspack - 资源模块](https://rspack.dev/zh/guide/features/asset-module)。 diff --git a/website/docs/zh/guide/advanced/svgr-files.mdx b/website/docs/zh/guide/advanced/svgr-files.mdx new file mode 100644 index 000000000..50dac8591 --- /dev/null +++ b/website/docs/zh/guide/advanced/svgr-files.mdx @@ -0,0 +1,105 @@ +# 引用 SVGR + +默认情况下,Rslib 会将 SVG 图片当作静态资源处理。 + +通过添加 [@rsbuild/plugin-svgr](https://rsbuild.dev/zh/plugins/list/plugin-svgr) 插件,Rslib 支持调用 [SVGR](https://react-svgr.com/),将 SVG 图片转换为一个 React 组件使用。 + +## 快速开始 + +### 安装插件 + +你可以通过如下的命令安装插件: + +import { PackageManagerTabs } from '@theme'; + + + +### 注册插件 + +你可以在 `rslib.config.ts` 文件中注册插件: + +```ts title="rslib.config.ts" +import { pluginSvgr } from '@rsbuild/plugin-svgr'; + +export default { + plugins: [pluginSvgr()], +}; +``` + +## 示例 + +### Bundle 模式 + +在 bundle 模式下,Rslib 支持 [@rsbuild/plugin-svgr](https://rsbuild.dev/zh/plugins/list/plugin-svgr) 下的所有用法,唯一的区别是当以 URL 形式使用 SVG 文件时,Rslib 会按照 [引用静态资源](/guide/advanced/static-assets) 在产物中对应保留静态资源的 `import` 语句。 + +下面是一个使用示例: + +```jsx title="App.jsx" +import Logo from './logo.svg?react'; + +export const App = () => ; +``` + +如果导入的路径不包含 `?react` 后缀,那么 SVG 会被当做普通的静态资源来处理,即保留对静态资源的 `import` 语句。 + +```js +import logoURL from './static/logo.svg'; + +console.log(logoURL); +``` + +`@rsbuild/plugin-svgr` 也支持默认导入和混合导入等用法: + +- 通过 [svgrOptions.exportType](https://rsbuild.dev/zh/plugins/list/plugin-svgr#svgroptionsexporttype) 设置为 `'default'` 来启用默认导入。 +- 通过 [mixedImport](https://rsbuild.dev/zh/plugins/list/plugin-svgr#mixedimport) 选项来启用混合导入,从而同时使用默认导入和具名导入。 + +### Bundleless 模式 + +在 bundleless 模式下,由于每个文件都是独立经过代码转换,因此不支持 `?react` 和 `?url` 的引用形式,但支持下面两种使用形式: + +#### 具名导入 + +`@rsbuild/plugin-svgr` 支持具名导入 `ReactComponent` 来使用 SVGR,你需要设置 [svgrOptions.exportType](https://rsbuild.dev/zh/plugins/list/plugin-svgr#svgroptionsexporttype) 为 `'named'`: + +```js +pluginSvgr({ + svgrOptions: { + exportType: 'named', + }, +}); +``` + +```jsx title="App.jsx" +import { ReactComponent as Logo } from './logo.svg'; + +export const App = () => ; +``` + +所有的 `.svg` 文件都会被转换成 React 组件,此时你可以: + +- 通过设置 [exclude](https://rsbuild.dev/zh/plugins/list/plugin-svgr#exclude) 来排除不需要转换的文件。 +- 通过 [svgrOptions.exportType](https://rsbuild.dev/zh/plugins/list/plugin-svgr#svgroptionsexporttype) 设置为 `'default'` 来修改为默认导出。 + +#### 混合导入 + +如果你的库中同时存在 url 和 React 组件两种引入形式,你也可以通过混合导入的方式来使用: + +```ts +pluginSvgr({ + mixedImport: true, + svgrOptions: { + exportType: 'named', + }, +}); +``` + +此时引用的 SVG 文件会同时导出 URL 和 React 组件: + +```js +import logoUrl, { ReactComponent as Logo } from './logo.svg'; + +console.log(logoUrl); // -> string +console.log(Logo); // -> React component +``` + +更多信息可以参考 [mixedImport](https://rsbuild.dev/zh/plugins/list/plugin-svgr#mixedimport) 选项。 diff --git a/website/docs/zh/guide/solution/index.mdx b/website/docs/zh/guide/solution/index.mdx index 23d3c33d4..a3e0e7a9b 100644 --- a/website/docs/zh/guide/solution/index.mdx +++ b/website/docs/zh/guide/solution/index.mdx @@ -4,7 +4,7 @@ ## Browser target -开发在浏览器中运行的库时,可以将其打包为 [ESM](/guide/basic/output-format#esm--cjs) 和 [CJS](/guide/basic/output-format#esm--cjs) 格式,用于与 app 的 bundler 集成。将包 [conditional-exports](https://nodejs.org/api/packages.html#conditional-exports) 配置为 ESM 输出可以更好地进行 treeshaking。此外,你可以创建 [UMD](/guide/basic/output-format#umd) 格式输出以供浏览器直接使用,甚至可以生成 [模块联邦](/guide/advanced/module-federation) 格式以供其他应用程序动态加载。根据目标浏览器支持配置 [Browserslist](https://rsbuild.dev/zh/guide/advanced/browserslist)以确定输出的降级语法,或添加 [polyfill](/guide/advanced/output-compatibility) 用于兼容 API。 +开发在浏览器中运行的库时,可以将其打包为 [ESM](/guide/basic/output-format#esm--cjs) 和 [CJS](/guide/basic/output-format#esm--cjs) 格式,用于与 app 的打包工具集成。将包 [conditional-exports](https://nodejs.org/api/packages.html#conditional-exports) 配置为 ESM 输出可以更好地进行 treeshaking。此外,你可以创建 [UMD](/guide/basic/output-format#umd) 格式输出以供浏览器直接使用,甚至可以生成 [模块联邦](/guide/advanced/module-federation) 格式以供其他应用程序动态加载。根据目标浏览器支持配置 [Browserslist](https://rsbuild.dev/zh/guide/advanced/browserslist)以确定输出的降级语法,或添加 [polyfill](/guide/advanced/output-compatibility) 用于兼容 API。 发布到 npm 时,你可以选择不压缩代码或[压缩代码](/config/rsbuild/output#outputminify),同时提供[sourcemap](/config/rsbuild/output#outputsourcema) 以增强库使用者的调试体验。样式上,可以使用 CSS 或 CSS 预处理器,如 Sass、Less 或 Stylus 等,或使用 PostCSS 用于 CSS 后处理。 Tailwind CSS 等工具也可以帮助你构建样式,也可以使用 CSS Modules。