Skip to content

Commit d7102ca

Browse files
committed
feat(rsbuild-plugin): apply the build engine for rslib
`rslib` was left out of the engine entirely, so a library build read none of the Lynx config and had to mirror the parts it needed by hand. Apply the engine there too, and gate the plugins that own the bundle — the template, the dev server, the output layout — on the caller instead. `rslib` assembles the bundle itself, and `rstest` has no bundle at all.
1 parent 558ea30 commit d7102ca

5 files changed

Lines changed: 61 additions & 29 deletions

File tree

.changeset/rslib-engine.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@lynx-js/react-rsbuild-plugin": patch
3+
"@lynx-js/rsbuild-plugin": patch
4+
---
5+
6+
Apply the Lynx build engine for `rslib` as well, so a library build reads the Lynx config. The plugins that own the bundle — the template, the dev server, the output layout — stay off, since `rslib` assembles the bundle itself.

packages/rspeedy/plugin-lynx/src/index.ts

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ export type {
3939
LynxPluginOptions,
4040
} from './config.js'
4141

42+
// `rslib` and `rstest` own the bundle themselves: an external bundle is
43+
// assembled and loaded by its consumer, and a test run has no bundle at all.
44+
// They read the engine config all the same.
45+
function onlyWhenTheEngineOwnsTheBundle(
46+
plugins: RsbuildPlugin[],
47+
): RsbuildPlugin[] {
48+
return plugins.map(plugin => ({
49+
...plugin,
50+
setup(api) {
51+
const { callerName } = api.context
52+
if (callerName === 'rslib' || callerName === 'rstest') {
53+
return
54+
}
55+
return plugin.setup(api)
56+
},
57+
}))
58+
}
59+
4260
/**
4361
* @public
4462
*/
@@ -53,18 +71,20 @@ export function pluginLynx(
5371
},
5472
},
5573
pluginConfig(options),
56-
pluginChunkLoading(),
57-
pluginCssMinimizer(),
58-
pluginDev(),
59-
pluginLynxDebugMetadata(),
60-
pluginMinify(),
61-
pluginOptimization(),
62-
pluginOutput(),
63-
pluginResolve(),
64-
pluginServer(),
65-
pluginSourcemap(),
66-
pluginSwc(),
67-
pluginTarget(),
68-
pluginTemplate(),
74+
...onlyWhenTheEngineOwnsTheBundle([
75+
pluginChunkLoading(),
76+
pluginCssMinimizer(),
77+
pluginDev(),
78+
pluginLynxDebugMetadata(),
79+
pluginMinify(),
80+
pluginOptimization(),
81+
pluginOutput(),
82+
pluginResolve(),
83+
pluginServer(),
84+
pluginSourcemap(),
85+
pluginSwc(),
86+
pluginTarget(),
87+
pluginTemplate(),
88+
]),
6989
]
7090
}

packages/rspeedy/plugin-react/src/autoLynx.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,14 @@ function isEngineRegistered(api: RsbuildPluginAPI): boolean {
2222
)
2323
}
2424

25-
// Rspeedy applies `pluginLynx` itself. With plain Rsbuild nothing does, so the
26-
// build engine is applied here to keep `pluginReactLynx` the only plugin a user
27-
// has to add.
25+
// Rspeedy applies `pluginLynx` itself. Nothing does with plain Rsbuild or
26+
// `rslib`, so the engine is applied here.
2827
export function pluginAutoLynx(): RsbuildPlugin {
2928
return {
3029
name: 'lynx:react:auto-lynx',
3130
async setup(api) {
32-
// The callers that do not emit a Lynx template do not want the engine
33-
// either. See the same condition in `applyEntry`.
34-
const { callerName } = api.context
35-
if (callerName === 'rslib' || callerName === 'rstest') {
31+
// A test run has no bundle for the engine to configure.
32+
if (api.context.callerName === 'rstest') {
3633
return
3734
}
3835

@@ -43,11 +40,8 @@ export function pluginAutoLynx(): RsbuildPlugin {
4340
const original = api.getRsbuildConfig('original')
4441

4542
for (const plugin of pluginLynx()) {
46-
// `setup` is called directly instead of registering the plugins, since
47-
// a plugin cannot add plugins. `apply` is honored here because Rsbuild
48-
// only evaluates it for registered plugins.
49-
// `action` is only set once a build or a server starts, and Rsbuild
50-
// passes it along as-is, so it is passed along the same way here.
43+
// A plugin cannot add plugins, so `setup` is called directly. That
44+
// skips the `apply` Rsbuild would evaluate for a registered plugin.
5145
const { action } = api.context
5246
if (
5347
typeof plugin.apply === 'function'

packages/rspeedy/plugin-react/src/entry.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ export function applyEntry(
8787
const emitTemplate = api.context.callerName !== 'rslib'
8888
&& api.context.callerName !== 'rstest'
8989
if (emitTemplate) {
90-
// `pluginAutoLynx` applies the engine for the same callers, so the config
91-
// is there whenever a template is emitted.
9290
if (!lynxConfig) {
9391
throw new Error(
9492
'No Lynx config exposed. `pluginLynx` has to be applied for the Lynx build engine to be configured.',

packages/rspeedy/plugin-react/test/auto-lynx.test.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ describe('pluginAutoLynx', () => {
9595
expect(include).toStrictEqual([...new Set(include)])
9696
})
9797

98-
test('does not apply the engine for the rslib caller', async () => {
98+
test('applies the engine for the rslib caller, minus the bundle it does not own', async () => {
99+
let lynxConfig: unknown
99100
const rsbuild = await createRsbuild({
100101
callerName: 'rslib',
101102
// eslint-disable-next-line n/no-unsupported-features/node-builtins
@@ -104,12 +105,25 @@ describe('pluginAutoLynx', () => {
104105
mode: 'production',
105106
environments: { lynx: {} },
106107
source: { entry: { main: './fixtures/basic.tsx' } },
107-
plugins: [pluginReactLynx()],
108+
plugins: [
109+
pluginReactLynx(),
110+
{
111+
name: 'test:read-lynx-config',
112+
setup(api) {
113+
api.modifyBundlerChain(() => {
114+
lynxConfig = api.useExposed(
115+
Symbol.for('@lynx-js/rsbuild-plugin:config'),
116+
)
117+
})
118+
},
119+
},
120+
],
108121
},
109122
})
110123

111124
const [config] = await rsbuild.initConfigs()
112125

126+
expect(lynxConfig).toBeDefined()
113127
expect(
114128
config?.plugins?.some(plugin =>
115129
plugin?.constructor.name === 'LynxTemplatePlugin'

0 commit comments

Comments
 (0)