diff --git a/examples/react-component-bundle/rslib.config.ts b/examples/react-component-bundle/rslib.config.ts index 59d42518d..c00c22eb5 100644 --- a/examples/react-component-bundle/rslib.config.ts +++ b/examples/react-component-bundle/rslib.config.ts @@ -25,6 +25,7 @@ export default defineConfig({ ], output: { target: 'web', + assetPrefix: 'auto', // TODO: move this line to packages/core/src/asset/assetConfig.ts }, plugins: [pluginReact(), pluginSass()], }); diff --git a/examples/react-component-bundle/src/assets/logo.svg b/examples/react-component-bundle/src/assets/logo.svg new file mode 100644 index 000000000..6b60c1042 --- /dev/null +++ b/examples/react-component-bundle/src/assets/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/examples/react-component-bundle/src/index.scss b/examples/react-component-bundle/src/index.scss index 2e506a0ac..f4c82dce4 100644 --- a/examples/react-component-bundle/src/index.scss +++ b/examples/react-component-bundle/src/index.scss @@ -1,3 +1,10 @@ +.counter-title { + width: 100px; + height: 100px; + background: no-repeat url('./assets/logo.svg'); + background-size: cover; +} + .counter-text { font-size: 50px; } diff --git a/examples/react-component-bundle/src/index.tsx b/examples/react-component-bundle/src/index.tsx index b7e472bb2..b9ceb8718 100644 --- a/examples/react-component-bundle/src/index.tsx +++ b/examples/react-component-bundle/src/index.tsx @@ -8,6 +8,7 @@ export const Counter: React.FC = () => { return (
+

React

Counter: {count}

diff --git a/packages/core/src/asset/assetConfig.ts b/packages/core/src/asset/assetConfig.ts new file mode 100644 index 000000000..908913af9 --- /dev/null +++ b/packages/core/src/asset/assetConfig.ts @@ -0,0 +1,23 @@ +import type { RsbuildConfig } from '@rsbuild/core'; +import type { Format } from '../types'; + +export const composeAssetConfig = ( + bundle: boolean, + format: Format, +): RsbuildConfig => { + if (format === 'esm' || format === 'cjs') { + if (bundle) { + return { + output: { + dataUriLimit: 0, // default: no inline asset + // assetPrefix: 'auto', // TODO: will turn on this with js support together in the future + }, + }; + } + // TODO: bundleless + return {}; + } + + // mf and umd etc + return {}; +}; diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index a7ababfed..2b99c8866 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -11,6 +11,7 @@ import { rspack, } from '@rsbuild/core'; import { glob } from 'tinyglobby'; +import { composeAssetConfig } from './asset/assetConfig'; import { DEFAULT_CONFIG_EXTENSIONS, DEFAULT_CONFIG_NAME, @@ -1221,6 +1222,8 @@ async function composeLibRsbuildConfig( cssModulesAuto, ); const cssConfig = composeCssConfig(lcp, config.bundle); + const assetConfig = composeAssetConfig(bundle, format!); + const entryChunkConfig = composeEntryChunkConfig({ enabledImportMetaUrlShim: enabledShims.cjs['import.meta.url'], }); @@ -1251,6 +1254,7 @@ async function composeLibRsbuildConfig( targetConfig, entryConfig, cssConfig, + assetConfig, entryChunkConfig, minifyConfig, dtsConfig, diff --git a/packages/core/tests/__snapshots__/config.test.ts.snap b/packages/core/tests/__snapshots__/config.test.ts.snap index f99920850..0e4cbf584 100644 --- a/packages/core/tests/__snapshots__/config.test.ts.snap +++ b/packages/core/tests/__snapshots__/config.test.ts.snap @@ -9,6 +9,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 }, "mode": "production", "output": { + "dataUriLimit": 0, "distPath": { "css": "./", "cssAsync": "./", @@ -248,6 +249,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1 }, "mode": "production", "output": { + "dataUriLimit": 0, "distPath": { "css": "./", "cssAsync": "./", diff --git a/tests/e2e/react-component/index.pw.test.ts b/tests/e2e/react-component/index.pw.test.ts index c5ba1b514..54935d837 100644 --- a/tests/e2e/react-component/index.pw.test.ts +++ b/tests/e2e/react-component/index.pw.test.ts @@ -1,3 +1,4 @@ +import assert from 'node:assert'; import fs from 'node:fs'; import path from 'node:path'; import { type Page, expect, test } from '@playwright/test'; @@ -27,9 +28,19 @@ async function styleShouldWork(page: Page) { const buttonEl = page.locator('#root button'); const [subtractEl, addEl] = await buttonEl.all(); - subtractEl && - expect(subtractEl).toHaveCSS('background-color', 'rgb(255, 255, 0)'); - addEl && expect(addEl).toHaveCSS('background-color', 'rgb(255, 255, 0)'); + assert(subtractEl); + assert(addEl); + expect(subtractEl).toHaveCSS('background-color', 'rgb(255, 255, 0)'); + expect(addEl).toHaveCSS('background-color', 'rgb(255, 255, 0)'); +} + +async function assetShouldWork(page: Page) { + // asset in css url('./logo.svg') + const h1El = page.locator('h1'); + assert(h1El); + expect(h1El).toHaveCSS('background', /static\/svg\/logo/); + + // TODO: asset in js } test('should render example "react-component-bundle" successfully', async ({ @@ -43,6 +54,7 @@ test('should render example "react-component-bundle" successfully', async ({ await counterCompShouldWork(page); await styleShouldWork(page); + await assetShouldWork(page); await rsbuild.close(); }); diff --git a/tests/e2e/react-component/rsbuild.config.ts b/tests/e2e/react-component/rsbuild.config.ts index 75d709864..94e159263 100644 --- a/tests/e2e/react-component/rsbuild.config.ts +++ b/tests/e2e/react-component/rsbuild.config.ts @@ -62,6 +62,7 @@ export default defineConfig({ }, output: { target: 'web', + dataUriLimit: 0, // always emit asset for test }, plugins: [ pluginReact({ diff --git a/tests/integration/asset/limit/rslib.config.ts b/tests/integration/asset/limit/rslib.config.ts index b82c816c1..0d0ead07a 100644 --- a/tests/integration/asset/limit/rslib.config.ts +++ b/tests/integration/asset/limit/rslib.config.ts @@ -8,6 +8,9 @@ export default defineConfig({ distPath: { root: './dist/esm/inline', }, + dataUriLimit: { + svg: 4096, + }, }, }), generateBundleEsmConfig({ @@ -15,9 +18,6 @@ export default defineConfig({ distPath: { root: './dist/esm/external', }, - dataUriLimit: { - svg: 0, - }, }, }), generateBundleEsmConfig({ @@ -26,6 +26,9 @@ export default defineConfig({ distPath: { root: './dist/esm/inline-bundleless', }, + dataUriLimit: { + svg: 4096, + }, }, }), generateBundleEsmConfig({ diff --git a/tests/integration/style/sass/__fixtures__/src/foundation/index.scss b/tests/integration/style/sass/__fixtures__/src/foundation/index.scss index 274a0d5b8..6717afb6c 100644 --- a/tests/integration/style/sass/__fixtures__/src/foundation/index.scss +++ b/tests/integration/style/sass/__fixtures__/src/foundation/index.scss @@ -1,3 +1,3 @@ body { - // background: url(./logo.svg); + background: url(./logo.svg); } diff --git a/tests/integration/style/sass/__fixtures__/src/index.scss b/tests/integration/style/sass/__fixtures__/src/index.scss index 7c777ffc6..595e03e02 100644 --- a/tests/integration/style/sass/__fixtures__/src/index.scss +++ b/tests/integration/style/sass/__fixtures__/src/index.scss @@ -3,13 +3,12 @@ // @import '~lib1/index.css'; @import './foundation/index.scss'; -// TODO: asset support -// $url: './foundation/logo.svg'; +$url: './foundation/logo.svg'; $border-dark: rgba($base-color, 0.88); -// .url-variable { -// background: url($url); -// } +.url-variable { + background: url($url); +} .alert { border: 1px solid $border-dark; diff --git a/tests/integration/style/sass/bundle/rslib.config.ts b/tests/integration/style/sass/bundle/rslib.config.ts index dc80e308a..8d05f9f82 100644 --- a/tests/integration/style/sass/bundle/rslib.config.ts +++ b/tests/integration/style/sass/bundle/rslib.config.ts @@ -18,8 +18,6 @@ export default defineConfig({ ], output: { target: 'web', - // dataUriLimit: { - // svg: 0, - // }, + assetPrefix: 'auto', // TODO: move this line to packages/core/src/asset/assetConfig.ts }, }); diff --git a/tests/integration/style/sass/index.test.ts b/tests/integration/style/sass/index.test.ts index 2f4a28920..f85366bda 100644 --- a/tests/integration/style/sass/index.test.ts +++ b/tests/integration/style/sass/index.test.ts @@ -29,6 +29,7 @@ test('should extract css with pluginSass in bundle-false', async () => { [ "/tests/integration/style/sass/bundle-false/dist/esm/foundation/_code.css", "/tests/integration/style/sass/bundle-false/dist/esm/foundation/_lists.css", + "/tests/integration/style/sass/bundle-false/dist/esm/foundation/index.css", "/tests/integration/style/sass/bundle-false/dist/esm/index.css", ] `); @@ -38,6 +39,7 @@ test('should extract css with pluginSass in bundle-false', async () => { [ "/tests/integration/style/sass/bundle-false/dist/cjs/foundation/_code.css", "/tests/integration/style/sass/bundle-false/dist/cjs/foundation/_lists.css", + "/tests/integration/style/sass/bundle-false/dist/cjs/foundation/index.css", "/tests/integration/style/sass/bundle-false/dist/cjs/index.css", ] `);