Skip to content

Commit de940e1

Browse files
committed
feat: support "umd" format
1 parent 10941c1 commit de940e1

File tree

53 files changed

+628
-46
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+628
-46
lines changed

biome.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"javascript": {
2828
"formatter": {
2929
"quoteStyle": "single"
30-
}
30+
},
31+
"jsxRuntime": "reactClassic"
3132
},
3233
"json": {
3334
"formatter": {

examples/react-component-bundle-false/rslib.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,12 @@ export default defineConfig({
3535
},
3636
},
3737
],
38-
plugins: [pluginReact(), pluginSass()],
38+
plugins: [
39+
pluginReact({
40+
swcReactOptions: {
41+
runtime: 'classic',
42+
},
43+
}),
44+
pluginSass(),
45+
],
3946
});

examples/react-component-bundle-false/src/components/CounterButton/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import React from 'react';
12
import styles from './index.module.scss';
3+
24
interface CounterButtonProps {
35
onClick: () => void;
46
label: string;

examples/react-component-bundle-false/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from 'react';
12
import { CounterButton } from './components/CounterButton/index';
23
import { useCounter } from './useCounter';
34
import './index.scss';

examples/react-component-bundle-false/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"esModuleInterop": true,
88
"forceConsistentCasingInFileNames": true,
99
"isolatedModules": true,
10-
"jsx": "react-jsx",
10+
"jsx": "react",
1111
"lib": ["DOM", "ESNext"],
1212
"moduleResolution": "node",
1313
"resolveJsonModule": true,

examples/react-component-bundle/rslib.config.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,12 @@ export default defineConfig({
3333
},
3434
},
3535
],
36-
plugins: [pluginReact(), pluginSass()],
36+
plugins: [
37+
pluginReact({
38+
swcReactOptions: {
39+
runtime: 'classic',
40+
},
41+
}),
42+
pluginSass(),
43+
],
3744
});

examples/react-component-bundle/src/components/CounterButton/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import React from 'react';
12
import styles from './index.module.scss';
3+
24
interface CounterButtonProps {
35
onClick: () => void;
46
label: string;

examples/react-component-bundle/src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from 'react';
12
import { CounterButton } from './components/CounterButton/index';
23
import { useCounter } from './useCounter';
34
import './index.scss';

examples/react-component-bundle/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"esModuleInterop": true,
88
"forceConsistentCasingInFileNames": true,
99
"isolatedModules": true,
10-
"jsx": "react-jsx",
10+
"jsx": "react",
1111
"lib": ["DOM", "ESNext"],
1212
"moduleResolution": "node",
1313
"resolveJsonModule": true,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# @examples/react-component
2+
3+
This example demonstrates how to use Rslib to build a simple React component.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@examples/react-component-umd",
3+
"private": true,
4+
"main": "./dist/umd/index.js",
5+
"unpkg": "./dist/umd/index.js",
6+
"scripts": {
7+
"build": "rslib build"
8+
},
9+
"devDependencies": {
10+
"@rsbuild/plugin-react": "^1.0.4",
11+
"@rsbuild/plugin-sass": "^1.0.3",
12+
"@rslib/core": "workspace:*",
13+
"@types/react": "^18.3.11",
14+
"react": "^18.3.1"
15+
},
16+
"peerDependencies": {
17+
"react": "*"
18+
}
19+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { pluginReact } from '@rsbuild/plugin-react';
2+
import { pluginSass } from '@rsbuild/plugin-sass';
3+
import { defineConfig } from '@rslib/core';
4+
5+
export default defineConfig({
6+
lib: [
7+
{
8+
format: 'umd',
9+
umdName: 'RslibUmdExample',
10+
output: {
11+
externals: {
12+
react: 'React',
13+
},
14+
distPath: {
15+
root: './dist/umd',
16+
css: '.',
17+
cssAsync: '.',
18+
},
19+
},
20+
},
21+
],
22+
plugins: [
23+
pluginReact({
24+
swcReactOptions: {
25+
runtime: 'classic',
26+
},
27+
}),
28+
pluginSass(),
29+
],
30+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.button {
2+
background: yellow;
3+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import styles from './index.module.scss';
3+
4+
interface CounterButtonProps {
5+
onClick: () => void;
6+
label: string;
7+
}
8+
9+
export const CounterButton: React.FC<CounterButtonProps> = ({
10+
onClick,
11+
label,
12+
}) => (
13+
<button type="button" className={styles.button} onClick={onClick}>
14+
{label}
15+
</button>
16+
);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '*.module.scss' {
2+
const classes: { [key: string]: string };
3+
export default classes;
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.counter-text {
2+
font-size: 50px;
3+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { CounterButton } from './components/CounterButton/index';
3+
import { useCounter } from './useCounter';
4+
import './index.scss';
5+
6+
export const Counter: React.FC = () => {
7+
const { count, increment, decrement } = useCounter();
8+
9+
return (
10+
<div>
11+
<h2 className="counter-text">Counter: {count}</h2>
12+
<CounterButton onClick={decrement} label="-" />
13+
<CounterButton onClick={increment} label="+" />
14+
</div>
15+
);
16+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { useState } from 'react';
2+
3+
export const useCounter = (initialValue = 0) => {
4+
const [count, setCount] = useState(initialValue);
5+
6+
const increment = () => setCount((prev) => prev + 1);
7+
const decrement = () => setCount((prev) => prev - 1);
8+
9+
return { count, increment, decrement };
10+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"allowJs": true,
4+
"baseUrl": ".",
5+
"declaration": true,
6+
"emitDeclarationOnly": true,
7+
"esModuleInterop": true,
8+
"forceConsistentCasingInFileNames": true,
9+
"isolatedModules": true,
10+
"jsx": "react",
11+
"lib": ["DOM", "ESNext"],
12+
"moduleResolution": "node",
13+
"resolveJsonModule": true,
14+
"rootDir": "src",
15+
"skipLibCheck": true,
16+
"strict": true
17+
},
18+
"exclude": ["**/node_modules"],
19+
"include": ["src"]
20+
}

packages/core/src/config.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,11 @@ export async function createConstantRsbuildConfig(): Promise<RsbuildConfig> {
449449
});
450450
}
451451

452-
const composeFormatConfig = (format: Format): RsbuildConfig => {
452+
const composeFormatConfig = ({
453+
format,
454+
bundle = true,
455+
umdName,
456+
}: { format: Format; bundle?: boolean; umdName?: string }): RsbuildConfig => {
453457
const jsParserOptions = {
454458
cjs: {
455459
requireResolve: false,
@@ -517,8 +521,14 @@ const composeFormatConfig = (format: Format): RsbuildConfig => {
517521
},
518522
},
519523
};
520-
case 'umd':
521-
return {
524+
case 'umd': {
525+
if (bundle === false) {
526+
throw new Error(
527+
'When "format" is set to "umd", "bundle" must not be set to "false", consider setting "bundle" to "true" or remove the field, it\'s default value is "true".',
528+
);
529+
}
530+
531+
const config: RsbuildConfig = {
522532
tools: {
523533
rspack: {
524534
module: {
@@ -529,13 +539,23 @@ const composeFormatConfig = (format: Format): RsbuildConfig => {
529539
},
530540
},
531541
output: {
532-
library: {
533-
type: 'umd',
534-
},
542+
asyncChunks: false,
543+
544+
library: umdName
545+
? {
546+
type: 'umd',
547+
name: umdName,
548+
}
549+
: {
550+
type: 'umd',
551+
},
535552
},
536553
},
537554
},
538555
};
556+
557+
return config;
558+
}
539559
default:
540560
throw new Error(`Unsupported format: ${format}`);
541561
}
@@ -785,7 +805,7 @@ const composeBundleConfig = (
785805
jsExtension: string,
786806
redirect: Redirect,
787807
cssModulesAuto: CssLoaderOptionsAuto,
788-
bundle = true,
808+
bundle: boolean,
789809
): RsbuildConfig => {
790810
if (bundle) return {};
791811

@@ -957,15 +977,21 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
957977
const {
958978
format,
959979
shims,
980+
bundle = true,
960981
banner = {},
961982
footer = {},
962983
autoExtension = true,
963984
autoExternal = true,
964985
externalHelpers = false,
965986
redirect = {},
987+
umdName,
966988
} = config;
967989
const shimsConfig = composeShimsConfig(format!, shims);
968-
const formatConfig = composeFormatConfig(format!);
990+
const formatConfig = composeFormatConfig({
991+
format: format!,
992+
bundle,
993+
umdName,
994+
});
969995
const externalHelpersConfig = composeExternalHelpersConfig(
970996
externalHelpers,
971997
pkgJson,
@@ -983,7 +1009,7 @@ async function composeLibRsbuildConfig(config: LibConfig, configPath: string) {
9831009
jsExtension,
9841010
redirect,
9851011
cssModulesAuto,
986-
config.bundle,
1012+
bundle,
9871013
);
9881014
const targetConfig = composeTargetConfig(config.output?.target);
9891015
const syntaxConfig = composeSyntaxConfig(

packages/core/src/types/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export interface LibConfig extends RsbuildConfig {
8080
footer?: BannerAndFooter;
8181
shims?: Shims;
8282
dts?: Dts;
83+
umdName?: string;
8384
}
8485

8586
export interface RslibConfig extends RsbuildConfig {

packages/core/tests/__snapshots__/config.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ exports[`Should compose create Rsbuild config correctly > Merge Rsbuild config 1
404404
},
405405
},
406406
"output": {
407+
"asyncChunks": false,
407408
"library": {
408409
"type": "umd",
409410
},

0 commit comments

Comments
 (0)