Skip to content

Commit db3dce7

Browse files
committed
feat(react-rsbuild-plugin): apply the build engine for the rslib caller
`pluginAutoLynx` skipped `rslib` because an external bundle assembles its own `.lynx.bundle`. It reads the engine config all the same, and now drives the template hooks too, so skipping it left `pluginLynx` to be added by hand for either to reach an external bundle — and left `@lynx-js/lynx-bundle-rslib-config` carrying a second set of defaults for when it was not. Apply the engine for it, the way plain Rsbuild already gets it. `pluginLynx` leaves out the plugins that would rewrite what an external bundle assembles, so what it gains is the config and the plugins that tap the template hooks.
1 parent 63762e4 commit db3dce7

5 files changed

Lines changed: 52 additions & 16 deletions

File tree

.changeset/rslib-auto-lynx.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@lynx-js/react-rsbuild-plugin": minor
3+
---
4+
5+
Apply the Lynx build engine for the `rslib` caller too, so an external bundle no longer needs `pluginLynx` added by hand.

packages/rspeedy/lynx-bundle-rslib-config/test/external-bundle.test.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,14 @@ describe('with the engine config', () => {
178178
})
179179
}
180180

181-
it('emits the same bytes as a build without it', async () => {
182-
// A local production build ships no debug metadata, so the engine adds
183-
// nothing to the bundle here. The rstest harness sets `DEBUG=rspeedy` and
184-
// CI sets `CI`, either of which would opt the build back into it.
181+
it('emits the same bytes whether the engine is applied by hand or not', async () => {
182+
// `pluginReactLynx` applies the engine, so adding `pluginLynx` on top of it
183+
// has to be a no-op rather than a second copy.
184+
//
185+
// A local production build ships no debug metadata, which keeps the bytes
186+
// free of the build paths that differ between the two. The rstest harness
187+
// sets `DEBUG=rspeedy` and CI sets `CI`, either of which would opt the
188+
// build back into it.
185189
const restore = new Map(
186190
['DEBUG', 'CI', 'CI_REPO_NAME', 'BUILD_VERSION'].map(key => {
187191
const value = process.env[key]
@@ -191,7 +195,7 @@ describe('with the engine config', () => {
191195
)
192196
rstest.stubEnv('NODE_ENV', 'production')
193197
try {
194-
await build(configFor('engine-off', []))
198+
await build(configFor('engine-auto', []))
195199
await build(configFor('engine-on', pluginLynx()))
196200

197201
expect(
@@ -200,7 +204,7 @@ describe('with the engine config', () => {
200204
),
201205
).toBe(
202206
sha256(
203-
path.join(fixtureDir, 'dist/engine-off/engine-off.lynx.bundle'),
207+
path.join(fixtureDir, 'dist/engine-auto/engine-auto.lynx.bundle'),
204208
),
205209
)
206210
} finally {
@@ -211,8 +215,8 @@ describe('with the engine config', () => {
211215
}
212216
})
213217

214-
it('runs the plugins that tap the template hooks', async () => {
215-
await build(configFor('engine-debug', pluginLynx()))
218+
it('runs the plugins that tap the template hooks without being applied by hand', async () => {
219+
await build(configFor('engine-debug', []))
216220

217221
const decoded = await decodeTemplate(
218222
path.join(fixtureDir, 'dist/engine-debug/engine-debug.lynx.bundle'),

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ export function pluginAutoLynx(): RsbuildPlugin {
3636
return {
3737
name: 'lynx:react:auto-lynx',
3838
async setup(api) {
39-
// `rslib` and `rstest` drive the build themselves — an external bundle
40-
// assembles its own `.lynx.bundle`, and a test run emits nothing — so
41-
// the engine has nothing to add. See the same condition in `applyEntry`.
42-
const { callerName } = api.context
43-
if (callerName === 'rslib' || callerName === 'rstest') {
39+
// A test run emits nothing, so the engine has nothing to add. `rslib`
40+
// does emit a bundle and reads the engine config, so the engine is
41+
// applied for it; `pluginLynx` leaves out the plugins that would rewrite
42+
// what an external bundle assembles itself.
43+
if (api.context.callerName === 'rstest') {
4444
return
4545
}
4646

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ 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.
90+
// `pluginAutoLynx` applies the engine for every caller that assembles a
91+
// template here, so the config is there whenever one is emitted.
9292
if (!lynxConfig) {
9393
throw new Error(
9494
'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: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,31 @@ describe('pluginAutoLynx', () => {
7777
expect(include).toStrictEqual([...new Set(include)])
7878
})
7979

80-
test('does not apply the engine for the rslib caller', async () => {
80+
test('applies the engine for the rslib caller', async () => {
81+
const rsbuild = await createRsbuild({
82+
callerName: 'rslib',
83+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
84+
cwd: import.meta.dirname,
85+
rsbuildConfig: {
86+
mode: 'development',
87+
environments: { lynx: {} },
88+
source: { entry: { main: './fixtures/basic.tsx' } },
89+
plugins: [pluginReactLynx()],
90+
},
91+
})
92+
93+
const [config] = await rsbuild.initConfigs()
94+
95+
// `pluginLynxDebugMetadata` taps the template hooks, which an external
96+
// bundle drives itself, so the engine reaches it without assembling one.
97+
expect(
98+
config?.plugins?.some(plugin =>
99+
plugin?.constructor.name === 'LynxDebugMetadataPlugin'
100+
),
101+
).toBe(true)
102+
})
103+
104+
test('leaves out the plugins that assemble a bundle for the rslib caller', async () => {
81105
const rsbuild = await createRsbuild({
82106
callerName: 'rslib',
83107
// eslint-disable-next-line n/no-unsupported-features/node-builtins
@@ -97,6 +121,9 @@ describe('pluginAutoLynx', () => {
97121
plugin?.constructor.name === 'LynxTemplatePlugin'
98122
),
99123
).toBe(false)
124+
// `pluginChunkLoading` loads a chunk the way a template does, which is not
125+
// how an external bundle is consumed.
126+
expect(config?.output?.chunkLoading).toBeUndefined()
100127
})
101128

102129
test('honors the apply condition of the engine plugins', async () => {

0 commit comments

Comments
 (0)