@lynx-js/react-rsbuild-plugin 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/index.js +131 -111
  3. package/package.json +22 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @lynx-js/react-rsbuild-plugin
2
2
 
3
+ ## 0.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - **BREAKING CHANGE**: Require `@lynx-js/rspeedy` `^0.17.0` in the plugins that read the build engine config through `Symbol.for('@lynx-js/rsbuild-plugin:config')`, since the engine that ships with `0.16` does not expose it. The plugins that do not touch the engine keep their existing range and add `^0.17.0` to it. ([#3682](https://github.com/lynx-family/lynx-stack/pull/3682))
8
+
9
+ ### Patch Changes
10
+
11
+ - Do not apply the Lynx build engine again when `pluginLynx` is registered on an environment rather than globally, which silently replaced the options it was given. ([#3695](https://github.com/lynx-family/lynx-stack/pull/3695))
12
+
13
+ - Move runtime attribute-name configuration to the page-scoped `lynx` object and ([#3718](https://github.com/lynx-family/lynx-stack/pull/3718))
14
+ inject it from the host compilation through a standalone webpack plugin. Lazy
15
+ and external bundles reuse the host-injected configuration without applying
16
+ the plugin themselves. The runtime-config webpack plugin is published through
17
+ its own DSL-neutral package entry and accepts arbitrary runtime configuration
18
+ keys without depending on ReactLynx. The merged top-level configuration is
19
+ shallow-frozen to prevent accidental mutation after host initialization.
20
+ - Accept `DEBUG=lynx` (and `lynx:*`, `lynx:template`) for the Lynx debug output and intermediates. It is the recommended form now that the plugins also run under Rslib and Rsbuild; `DEBUG=rspeedy` keeps working. ([#3735](https://github.com/lynx-family/lynx-stack/pull/3735))
21
+
22
+ - Honor `splitChunks`, `performance.chunkSplit` and `output.sourceMap` when they are set on an environment. `pluginReactLynx` used to read them from the root of the config only when deciding whether to split chunks and whether to inline sources into source maps. ([#3768](https://github.com/lynx-family/lynx-stack/pull/3768))
23
+
24
+ - Skip the background runtime wrapper on any asset marked `lynx:main-thread` instead of matching filenames, and mark the main-thread assets of an external bundle by the layer of their modules, so a main-thread entry an external bundle names itself is no longer wrapped. ([#3751](https://github.com/lynx-family/lynx-stack/pull/3751))
25
+
26
+ - Declare the build host as an optional peer dependency. `@rsbuild/core` covers a plain Rsbuild build, and `@lynx-js/rspeedy` covers an Rspeedy one, so whichever host is installed is version-checked. ([#3678](https://github.com/lynx-family/lynx-stack/pull/3678))
27
+
28
+ - Add `performance` to the `pluginLynx` options, alongside `output`, and expose it on the config `pluginLynx` provides. Rspeedy maps its `performance.profile` onto it, so a plugin can read the option from the build engine instead of requiring Rspeedy to be the caller. `pluginReactLynx` reads it from there instead of requiring Rspeedy. ([#3691](https://github.com/lynx-family/lynx-stack/pull/3691))
29
+
30
+ - Honor `output.distPath.intermediate`. The Lynx build engine now resolves the intermediate directory, so the option is no longer ignored by the plugins that emit a Lynx bundle. ([#3676](https://github.com/lynx-family/lynx-stack/pull/3676))
31
+
32
+ - Accept `@lynx-js/react` 0.126, which ships Preact 11. ([#3450](https://github.com/lynx-family/lynx-stack/pull/3450))
33
+
34
+ - Apply the Lynx build engine to `rslib` builds: module resolution, SWC transforms, bundler target, output, minification (JS and CSS), source maps and debug metadata now match an application build. The plugins that load or serve a bundle stay off, since `rslib` assembles its own. ([#3696](https://github.com/lynx-family/lynx-stack/pull/3696))
35
+
36
+ - `pluginReactLynx` registers the encoders and the background runtime wrapper for every caller, and `WebEncodePlugin` routes the custom sections of a bundle without a root into the slots the web runtime reads. `@lynx-js/lynx-bundle-rslib-config` only sets the template plugin and the main-thread wrapper up now. ([#3744](https://github.com/lynx-family/lynx-stack/pull/3744))
37
+
38
+ - Expose `Symbol.for('LynxTemplatePlugin')` from `pluginLynx` instead of from each DSL plugin, so the plugins that tap the template hooks work with the build engine alone. ([#3675](https://github.com/lynx-family/lynx-stack/pull/3675))
39
+
40
+ - Skip the built-in `pluginLynx` when one is already applied, so a user who needs to configure the Lynx build engine can apply `pluginLynx` themselves and have their options win. `@lynx-js/rspeedy` becomes an optional peer dependency of `pluginReactLynx` and `pluginQRCode`. ([#3661](https://github.com/lynx-family/lynx-stack/pull/3661))
41
+ - Updated dependencies [[`643a52d`](https://github.com/lynx-family/lynx-stack/commit/643a52d9aefb327ca5a090cb052fd9b08cefbba6), [`76126fc`](https://github.com/lynx-family/lynx-stack/commit/76126fcad0f16e649c372d22c013e90ad88640df), [`b854dec`](https://github.com/lynx-family/lynx-stack/commit/b854dec62d48a09f60abc0632ba541bbdffda31f), [`c21cddd`](https://github.com/lynx-family/lynx-stack/commit/c21cddd0b75290330b6891f041db63ee5b28f492), [`f743e12`](https://github.com/lynx-family/lynx-stack/commit/f743e123e058d8f97720b1ce8c4a3d6601c8f7be), [`9bbfe5d`](https://github.com/lynx-family/lynx-stack/commit/9bbfe5d6e5367fbbaacc0129559e7b1d823038ad), [`5637926`](https://github.com/lynx-family/lynx-stack/commit/5637926c579bac5e9b78a02b982b1110cf4421d4), [`cdceffc`](https://github.com/lynx-family/lynx-stack/commit/cdceffc6f3fb9ac7b5ce1f48b7edb53c7788c057), [`6da3e18`](https://github.com/lynx-family/lynx-stack/commit/6da3e189f58637e14318782c176ed5970b59f75d), [`754ed35`](https://github.com/lynx-family/lynx-stack/commit/754ed35f8063c9333b75a7a7bbb264cb19c5cc51), [`5637926`](https://github.com/lynx-family/lynx-stack/commit/5637926c579bac5e9b78a02b982b1110cf4421d4), [`ab041b7`](https://github.com/lynx-family/lynx-stack/commit/ab041b72bc0d93e22f542b5963e221b6bd3f39e8), [`0a52438`](https://github.com/lynx-family/lynx-stack/commit/0a524389500421bb07e6a69366879e453d5d1d09), [`c6f971a`](https://github.com/lynx-family/lynx-stack/commit/c6f971a31fc0c54b98458c01f8c39a0828fe198c), [`0c47383`](https://github.com/lynx-family/lynx-stack/commit/0c4738342365ed4670ec659df5ede683e5aa2529), [`b3c6045`](https://github.com/lynx-family/lynx-stack/commit/b3c604544f84f1c600fb42468b05f7d73c120ad3), [`08a36e3`](https://github.com/lynx-family/lynx-stack/commit/08a36e39a5ba336946335d55a29efba1750e65ad), [`abab087`](https://github.com/lynx-family/lynx-stack/commit/abab087d0a4ce2e993c2417ce7bbf17e585ac972), [`32ba734`](https://github.com/lynx-family/lynx-stack/commit/32ba7347d1733eb4b2e19e95d7b7415ae78e23d2), [`7850e1e`](https://github.com/lynx-family/lynx-stack/commit/7850e1edb6f02ef2d332b756cd6e1a6ae6584368), [`3ab5ba3`](https://github.com/lynx-family/lynx-stack/commit/3ab5ba3fb738c368cfca6b6a5fc8c4ea323de124), [`eaefef6`](https://github.com/lynx-family/lynx-stack/commit/eaefef64d9874a8236d99b8abe17978d803a02da), [`e2ac811`](https://github.com/lynx-family/lynx-stack/commit/e2ac811c48535672bb14e4662f38dbebf0276167), [`0be26e9`](https://github.com/lynx-family/lynx-stack/commit/0be26e91d362041d1b0f568d15828d92f0ed2a6d), [`3d63331`](https://github.com/lynx-family/lynx-stack/commit/3d63331dc861bf3180f975ca54d4e7d9afd5eb70), [`32ba734`](https://github.com/lynx-family/lynx-stack/commit/32ba7347d1733eb4b2e19e95d7b7415ae78e23d2)]:
42
+ - @lynx-js/rsbuild-plugin@0.1.0
43
+ - @lynx-js/react-webpack-plugin@0.11.2
44
+ - @lynx-js/runtime-config-webpack-plugin@0.0.1
45
+ - @lynx-js/template-webpack-plugin@0.16.0
46
+ - @lynx-js/runtime-wrapper-webpack-plugin@0.2.4
47
+ - @lynx-js/react-alias-rsbuild-plugin@0.20.0
48
+ - @lynx-js/css-extract-webpack-plugin@0.11.0
49
+ - @lynx-js/use-sync-external-store@1.5.0
50
+ - @lynx-js/react-refresh-webpack-plugin@0.4.2
51
+
52
+ ## 0.19.1
53
+
54
+ ### Patch Changes
55
+
56
+ - Apply the Lynx build engine automatically when it is not already applied, so `pluginReactLynx` works with plain Rsbuild. ([#3578](https://github.com/lynx-family/lynx-stack/pull/3578))
57
+
58
+ - Read the bundle filename from the Rsbuild config instead of the Rspeedy API. ([#3570](https://github.com/lynx-family/lynx-stack/pull/3570))
59
+
60
+ - Emit the Lynx template for callers other than `rslib` and `rstest`. ([#3572](https://github.com/lynx-family/lynx-stack/pull/3572))
61
+
62
+ - Widen the `@lynx-js/react` peer dependency range to include 0.125. ([#3551](https://github.com/lynx-family/lynx-stack/pull/3551))
63
+ - Updated dependencies [[`1d08862`](https://github.com/lynx-family/lynx-stack/commit/1d08862ef9a1883fe98f2b9f7dce59d092d14d68), [`99ed745`](https://github.com/lynx-family/lynx-stack/commit/99ed7451d190cd18a45f78f731141994104a054b), [`0d10b79`](https://github.com/lynx-family/lynx-stack/commit/0d10b796d219e6f661709885d9ff2a4e61f4e65b), [`0d10b79`](https://github.com/lynx-family/lynx-stack/commit/0d10b796d219e6f661709885d9ff2a4e61f4e65b), [`0d10b79`](https://github.com/lynx-family/lynx-stack/commit/0d10b796d219e6f661709885d9ff2a4e61f4e65b), [`0d10b79`](https://github.com/lynx-family/lynx-stack/commit/0d10b796d219e6f661709885d9ff2a4e61f4e65b), [`92b54ed`](https://github.com/lynx-family/lynx-stack/commit/92b54edba5adea2a4ddd355c821ff25205273479), [`37497d5`](https://github.com/lynx-family/lynx-stack/commit/37497d58fe4e0762d687001d61181ec5e0e650b9)]:
64
+ - @lynx-js/react-webpack-plugin@0.11.1
65
+ - @lynx-js/rsbuild-plugin@0.0.3
66
+ - @lynx-js/react-alias-rsbuild-plugin@0.19.1
67
+ - @lynx-js/use-sync-external-store@1.5.0
68
+ - @lynx-js/react-refresh-webpack-plugin@0.4.2
69
+ - @lynx-js/css-extract-webpack-plugin@0.10.1
70
+ - @lynx-js/template-webpack-plugin@0.15.2
71
+
3
72
  ## 0.19.0
4
73
 
5
74
  ### Minor Changes
package/dist/index.js CHANGED
@@ -1,11 +1,30 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { pluginReactAlias } from "@lynx-js/react-alias-rsbuild-plugin";
3
3
  import { LAYERS, ReactWebpackPlugin } from "@lynx-js/react-webpack-plugin";
4
- import { LynxEncodePlugin, LynxTemplatePlugin, WebEncodePlugin } from "@lynx-js/template-webpack-plugin";
4
+ import { isPluginLynxRegistered, pluginLynx } from "@lynx-js/rsbuild-plugin";
5
5
  import node_path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
+ import { RuntimeConfigWebpackPlugin } from "@lynx-js/runtime-config-webpack-plugin";
7
8
  import { RuntimeWrapperWebpackPlugin } from "@lynx-js/runtime-wrapper-webpack-plugin";
9
+ import { LynxEncodePlugin, LynxTemplatePlugin, WebEncodePlugin } from "@lynx-js/template-webpack-plugin";
8
10
  import { ReactRefreshRspackPlugin } from "@lynx-js/react-refresh-webpack-plugin";
11
+ function pluginAutoLynx() {
12
+ return {
13
+ name: 'lynx:react:auto-lynx',
14
+ async setup (api) {
15
+ if ('rstest' === api.context.callerName) return;
16
+ const { environments } = api.getRsbuildConfig('original');
17
+ if (isPluginLynxRegistered(api, Object.keys(environments ?? {}))) return;
18
+ const original = api.getRsbuildConfig('original');
19
+ for (const plugin of pluginLynx()){
20
+ const { action } = api.context;
21
+ if ('function' != typeof plugin.apply || plugin.apply(original, {
22
+ action
23
+ })) await plugin.setup(api);
24
+ }
25
+ }
26
+ };
27
+ }
9
28
  const DETECT_IMPORT_ERROR = 'react:detect-import-error';
10
29
  const ALIAS_BACKGROUND_ONLY_MAIN = 'react:alias-background-only-main';
11
30
  const ALIAS_BACKGROUND_ONLY_BACKGROUND = 'react:alias-background-only-background';
@@ -126,53 +145,94 @@ function meetsMinEngineVersion(actual, min) {
126
145
  }
127
146
  return true;
128
147
  }
148
+ const isPlainObject = (obj)=>null !== obj && 'object' == typeof obj && '[object Object]' === Object.prototype.toString.call(obj);
149
+ function getUserSplitChunks(config, environment) {
150
+ const scoped = config.environments?.[environment];
151
+ return {
152
+ splitChunks: scoped?.splitChunks ?? config.splitChunks,
153
+ chunkSplitStrategy: scoped?.performance?.chunkSplit?.strategy ?? config.performance?.chunkSplit?.strategy
154
+ };
155
+ }
156
+ const applySplitChunksRule = (api)=>{
157
+ api.modifyEnvironmentConfig((config, { name, mergeEnvironmentConfig })=>{
158
+ const { splitChunks, chunkSplitStrategy } = getUserSplitChunks(api.getRsbuildConfig('original'), name);
159
+ if (void 0 === splitChunks && ('all-in-one' === chunkSplitStrategy || !chunkSplitStrategy)) return mergeEnvironmentConfig(config, {
160
+ splitChunks: false
161
+ });
162
+ return config;
163
+ });
164
+ api.modifyBundlerChain((chain, { environment })=>{
165
+ const { config } = environment;
166
+ const { splitChunks, chunkSplitStrategy } = getUserSplitChunks(api.getRsbuildConfig('original'), environment.name);
167
+ const isSplitByExperience = void 0 === splitChunks ? 'split-by-experience' === chunkSplitStrategy : isPlainObject(config.splitChunks) && 'default' === config.splitChunks.preset;
168
+ if (!isSplitByExperience) return;
169
+ const currentConfig = chain.optimization.splitChunks.values();
170
+ if (!isPlainObject(currentConfig)) return;
171
+ const extraGroups = {};
172
+ extraGroups['preact'] = {
173
+ name: 'lib-preact',
174
+ test: /node_modules[\\/](.*?[\\/])?(?:(?:internal-)?preact|(?:internal-)?preact[\\/]compat|(?:internal-)?preact[\\/]hooks|(?:internal-)?preact[\\/]jsx-runtime)[\\/]/,
175
+ priority: 0
176
+ };
177
+ chain.optimization.splitChunks({
178
+ ...currentConfig,
179
+ cacheGroups: {
180
+ ...currentConfig.cacheGroups,
181
+ ...extraGroups
182
+ }
183
+ });
184
+ });
185
+ api.modifyRspackConfig((rspackConfig)=>{
186
+ if (!rspackConfig.optimization) return rspackConfig;
187
+ if (!rspackConfig.optimization.splitChunks) return rspackConfig;
188
+ rspackConfig.optimization.splitChunks.chunks = function(chunk) {
189
+ return !chunk.name?.includes('__main-thread');
190
+ };
191
+ return rspackConfig;
192
+ });
193
+ };
194
+ const S_LYNX_CONFIG = Symbol.for('@lynx-js/rsbuild-plugin:config');
129
195
  const PLUGIN_NAME_REACT = 'lynx:react';
196
+ const PLUGIN_NAME_RUNTIME_CONFIG = 'lynx:runtime-config';
130
197
  const PLUGIN_NAME_TEMPLATE = 'lynx:template';
131
198
  const PLUGIN_NAME_RUNTIME_WRAPPER = 'lynx:runtime-wrapper';
132
199
  const PLUGIN_NAME_WEB = 'lynx:web';
133
- const DEFAULT_DIST_PATH_INTERMEDIATE = '.rspeedy';
134
200
  const DEFAULT_FILENAME_HASH = '.[contenthash:8]';
135
201
  const EMPTY_HASH = '';
136
202
  function applyEntry(api, options) {
137
203
  const { compat, customCSSInheritanceList, debugInfoOutside, defaultDisplayLinear, enableAccessibilityElement, enableCSSInheritance, enableCSSInvalidation, enableCSSSelector, enableNewGesture, enableRemoveCSSScope, firstScreenSyncTiming, globalPropsMode, enableSSR, removeDescendantSelectorScope, targetSdkVersion, extractStr: originalExtractStr, experimental_isLazyBundle, experimental_transformBuiltinAttributeNames } = options;
138
204
  const lazyBundleFetcher = resolveLazyBundleFetcher(targetSdkVersion);
205
+ const runtimeConfig = {};
206
+ if (experimental_transformBuiltinAttributeNames) runtimeConfig['transformBuiltinAttributeNames'] = experimental_transformBuiltinAttributeNames;
139
207
  api.modifyBundlerChain(async (chain, { environment, isDev, isProd })=>{
140
208
  const mainThreadChunks = [];
141
209
  const entryPairs = [];
142
- const rsbuildConfig = api.getRsbuildConfig();
143
- const userConfig = api.getRsbuildConfig('original');
144
- const chunkSplitStrategy = userConfig.performance?.chunkSplit?.strategy;
145
- const enableChunkSplitting = void 0 === userConfig.splitChunks ? chunkSplitStrategy ? 'all-in-one' !== chunkSplitStrategy : false !== rsbuildConfig.splitChunks : false !== rsbuildConfig.splitChunks;
210
+ const { splitChunks, chunkSplitStrategy } = getUserSplitChunks(api.getRsbuildConfig('original'), environment.name);
211
+ const enableChunkSplitting = void 0 === splitChunks ? chunkSplitStrategy ? 'all-in-one' !== chunkSplitStrategy : false !== environment.config.splitChunks : false !== environment.config.splitChunks;
146
212
  const rspeedyConfig = 'rspeedy' === api.context.callerName ? api.useExposed(Symbol.for('rspeedy.api'))?.config : void 0;
147
- const isRspeedy = 'rspeedy' === api.context.callerName;
148
- if (isRspeedy) {
213
+ const lynxConfig = api.useExposed(S_LYNX_CONFIG);
214
+ const isLynx = 'lynx' === environment.name || environment.name.startsWith('lynx-');
215
+ const isWeb = 'web' === environment.name || environment.name.startsWith('web-');
216
+ const isApplication = 'rslib' !== api.context.callerName && 'rstest' !== api.context.callerName;
217
+ if (isApplication) {
218
+ if (!lynxConfig) throw new Error('No Lynx config exposed. `pluginLynx` has to be applied for the Lynx build engine to be configured.');
149
219
  const entries = chain.entryPoints.entries() ?? {};
150
- const isLynx = 'lynx' === environment.name || environment.name.startsWith('lynx-');
151
- const isWeb = 'web' === environment.name || environment.name.startsWith('web-');
152
220
  const { hmr, liveReload } = environment.config.dev ?? {};
153
221
  const enabledHMR = isDev && false !== hmr;
154
222
  const enabledLiveReload = isDev && false !== liveReload;
155
223
  chain.entryPoints.clear();
156
224
  Object.entries(entries).forEach(([entryName, entryPoint])=>{
157
225
  const { imports } = getChunks(entryName, entryPoint.values());
158
- const bundleFilename = 'object' == typeof rspeedyConfig?.output?.filename ? rspeedyConfig.output.filename.bundle ?? rspeedyConfig.output.filename.template : rspeedyConfig?.output?.filename;
159
- let templateFilename;
160
- let lazyBundleFilename;
161
- if ('function' == typeof bundleFilename) {
162
- templateFilename = bundleFilename({
163
- lazyBundle: false,
164
- entryName,
165
- platform: environment.name
166
- });
167
- lazyBundleFilename = bundleFilename({
168
- lazyBundle: true,
169
- entryName: void 0,
170
- platform: environment.name
171
- }).replaceAll('[platform]', environment.name);
172
- } else templateFilename = bundleFilename ?? '[name].[platform].bundle';
226
+ const templateFilename = lynxConfig.resolveBundleFilename({
227
+ entryName,
228
+ platform: environment.name
229
+ });
230
+ const lazyBundleFilename = lynxConfig.resolveLazyBundleFilename({
231
+ platform: environment.name
232
+ });
173
233
  const mainThreadEntry = `${entryName}__main-thread`;
174
- const mainThreadName = node_path.posix.join(isLynx ? DEFAULT_DIST_PATH_INTERMEDIATE : '', `${entryName}/main-thread.js`);
175
- const backgroundName = node_path.posix.join(isLynx ? DEFAULT_DIST_PATH_INTERMEDIATE : '', getBackgroundFilename(entryName, environment.config, isProd, experimental_isLazyBundle));
234
+ const mainThreadName = node_path.posix.join(isLynx ? lynxConfig.resolveIntermediateDir() : '', `${entryName}/main-thread.js`);
235
+ const backgroundName = node_path.posix.join(isLynx ? lynxConfig.resolveIntermediateDir() : '', getBackgroundFilename(entryName, environment.config, isProd, experimental_isLazyBundle));
176
236
  const backgroundEntry = entryName;
177
237
  mainThreadChunks.push(mainThreadName);
178
238
  entryPairs.push({
@@ -213,11 +273,13 @@ function applyEntry(api, options) {
213
273
  mainThreadEntry,
214
274
  backgroundEntry
215
275
  ],
216
- filename: templateFilename.replaceAll('[name]', entryName).replaceAll('[platform]', environment.name),
276
+ filename: templateFilename,
217
277
  ...lazyBundleFilename ? {
218
278
  lazyBundleFilename
219
279
  } : {},
220
- intermediate: node_path.posix.join(DEFAULT_DIST_PATH_INTERMEDIATE, entryName),
280
+ intermediate: lynxConfig.resolveIntermediateDir({
281
+ entryName
282
+ }),
221
283
  customCSSInheritanceList,
222
284
  debugInfoOutside,
223
285
  defaultDisplayLinear,
@@ -236,35 +298,34 @@ function applyEntry(api, options) {
236
298
  }
237
299
  ]).end();
238
300
  });
239
- if (isLynx) {
240
- let inlineScripts;
241
- inlineScripts = experimental_isLazyBundle ? true : environment.config.output?.inlineScripts ?? !enableChunkSplitting;
242
- chain.plugin(PLUGIN_NAME_RUNTIME_WRAPPER).use(RuntimeWrapperWebpackPlugin, [
243
- {
244
- injectVars (vars) {
245
- const UNUSED_VARS = new Set([
246
- 'Card',
247
- 'Component',
248
- 'ReactLynx',
249
- 'Behavior'
250
- ]);
251
- return vars.map((name)=>{
252
- if (UNUSED_VARS.has(name)) return `__${name}`;
253
- return name;
254
- });
255
- },
256
- targetSdkVersion,
257
- test: /^(?!.*main-thread(?:\.[A-Fa-f0-9]*)?\.js$).*\.js$/,
258
- experimental_isLazyBundle
259
- }
260
- ]).end().plugin(`${LynxEncodePlugin.name}`).use(LynxEncodePlugin, [
261
- {
262
- inlineScripts
263
- }
264
- ]).end();
265
- }
266
- if (isWeb) chain.plugin(PLUGIN_NAME_WEB).use(WebEncodePlugin, []).end();
267
301
  }
302
+ if (isLynx) {
303
+ let inlineScripts;
304
+ inlineScripts = experimental_isLazyBundle ? true : environment.config.output?.inlineScripts ?? !enableChunkSplitting;
305
+ chain.plugin(PLUGIN_NAME_RUNTIME_WRAPPER).use(RuntimeWrapperWebpackPlugin, [
306
+ {
307
+ injectVars (vars) {
308
+ const UNUSED_VARS = new Set([
309
+ 'Card',
310
+ 'Component',
311
+ 'ReactLynx',
312
+ 'Behavior'
313
+ ]);
314
+ return vars.map((name)=>{
315
+ if (UNUSED_VARS.has(name)) return `__${name}`;
316
+ return name;
317
+ });
318
+ },
319
+ targetSdkVersion,
320
+ experimental_isLazyBundle
321
+ }
322
+ ]).end().plugin(`${LynxEncodePlugin.name}`).use(LynxEncodePlugin, [
323
+ {
324
+ inlineScripts
325
+ }
326
+ ]).end();
327
+ }
328
+ if (isWeb) chain.plugin(PLUGIN_NAME_WEB).use(WebEncodePlugin, []).end();
268
329
  let extractStr = originalExtractStr;
269
330
  if (enableChunkSplitting && originalExtractStr) {
270
331
  (api.logger ?? console).warn('`extractStr` is changed to `false` because it is only supported when chunk splitting is disabled, please set `splitChunks` to `false` to use `extractStr.`');
@@ -282,16 +343,19 @@ function applyEntry(api, options) {
282
343
  extractStr,
283
344
  experimental_isLazyBundle,
284
345
  experimental_useElementTemplate: options.experimental_useElementTemplate,
285
- experimental_transformBuiltinAttributeNames,
286
346
  profile: getDefaultProfile(),
287
347
  workletRuntimePath: await resolve(`@lynx-js/react/${isDev ? 'worklet-dev-runtime' : 'worklet-runtime'}`),
288
348
  lazyBundleFetcher
289
349
  }
290
350
  ]);
351
+ const isHostEnvironment = isApplication && !experimental_isLazyBundle;
352
+ if (isHostEnvironment && Object.keys(runtimeConfig).length > 0) chain.plugin(PLUGIN_NAME_RUNTIME_CONFIG).after(PLUGIN_NAME_REACT).use(RuntimeConfigWebpackPlugin, [
353
+ runtimeConfig
354
+ ]);
291
355
  function getDefaultProfile() {
292
356
  const environmentProfile = rspeedyConfig?.environments?.[environment.name]?.performance?.profile;
293
357
  if (void 0 !== environmentProfile) return environmentProfile;
294
- const userProfile = rspeedyConfig?.performance?.profile;
358
+ const userProfile = lynxConfig?.performance.profile;
295
359
  if (void 0 !== userProfile) return userProfile;
296
360
  if (isDebug()) return true;
297
361
  }
@@ -301,6 +365,7 @@ const isDebug = ()=>{
301
365
  if (!process.env['DEBUG']) return false;
302
366
  const values = process.env['DEBUG'].toLocaleLowerCase().split(',');
303
367
  return [
368
+ 'lynx',
304
369
  'rspeedy',
305
370
  '*'
306
371
  ].some((key)=>values.includes(key));
@@ -373,8 +438,7 @@ const MAIN_THREAD_ENV_INCLUDE = [
373
438
  const MAIN_THREAD_ENV_TARGETS = {
374
439
  chrome: '120'
375
440
  };
376
- function getLoaderOptions(api, options, isMainThread = false) {
377
- const { output } = api.getRsbuildConfig();
441
+ function getLoaderOptions(output, options, isMainThread = false) {
378
442
  const inlineSourcesContent = output?.sourceMap === true || !(output?.sourceMap === false || output?.sourceMap?.js === false || output?.sourceMap?.js?.includes('nosources'));
379
443
  const { compat, enableRemoveCSSScope, shake, defineDCE, engineVersion, enableUiSourceMap, experimental_transformBuiltinAttributeNames, experimental_isLazyBundle, experimental_useElementTemplate } = options;
380
444
  return {
@@ -394,13 +458,13 @@ function getLoaderOptions(api, options, isMainThread = false) {
394
458
  }
395
459
  const TESTING_RULE_NAME = 'react:testing';
396
460
  function applyTestingLoaders(api, options) {
397
- api.modifyBundlerChain((chain, { CHAIN_ID })=>{
461
+ api.modifyBundlerChain((chain, { CHAIN_ID, environment })=>{
398
462
  const rule = chain.module.rule(CHAIN_ID.RULE.JS).oneOf(CHAIN_ID.ONE_OF.JS_MAIN);
399
- rule.use(TESTING_RULE_NAME).loader(ReactWebpackPlugin.loaders.TESTING).options(getLoaderOptions(api, options)).end();
463
+ rule.use(TESTING_RULE_NAME).loader(ReactWebpackPlugin.loaders.TESTING).options(getLoaderOptions(environment.config.output, options)).end();
400
464
  });
401
465
  }
402
466
  function applyLoaders(api, options) {
403
- api.modifyBundlerChain((chain, { CHAIN_ID })=>{
467
+ api.modifyBundlerChain((chain, { CHAIN_ID, environment })=>{
404
468
  const rule = chain.module.rule(CHAIN_ID.RULE.JS);
405
469
  const jsMainRule = rule.oneOf(CHAIN_ID.ONE_OF.JS_MAIN);
406
470
  const type = jsMainRule.get('type');
@@ -409,7 +473,7 @@ function applyLoaders(api, options) {
409
473
  const backgroundRule = jsMainRule.oneOf(LAYERS.BACKGROUND);
410
474
  backgroundRule.issuerLayer(LAYERS.BACKGROUND).when(void 0 !== type, (rule)=>{
411
475
  rule.type(type);
412
- }).uses.merge(uses).end().use(LAYERS.BACKGROUND).loader(ReactWebpackPlugin.loaders.BACKGROUND).options(getLoaderOptions(api, options)).end();
476
+ }).uses.merge(uses).end().use(LAYERS.BACKGROUND).loader(ReactWebpackPlugin.loaders.BACKGROUND).options(getLoaderOptions(environment.config.output, options)).end();
413
477
  const mainThreadRule = jsMainRule.oneOf(LAYERS.MAIN_THREAD);
414
478
  mainThreadRule.issuerLayer(LAYERS.MAIN_THREAD).when(void 0 !== type, (rule)=>{
415
479
  rule.type(type);
@@ -433,7 +497,7 @@ function applyLoaders(api, options) {
433
497
  ]
434
498
  }
435
499
  });
436
- }).use(LAYERS.MAIN_THREAD).loader(ReactWebpackPlugin.loaders.MAIN_THREAD).options(getLoaderOptions(api, options, true)).end();
500
+ }).use(LAYERS.MAIN_THREAD).loader(ReactWebpackPlugin.loaders.MAIN_THREAD).options(getLoaderOptions(environment.config.output, options, true)).end();
437
501
  });
438
502
  }
439
503
  function applyNodeEnv(api) {
@@ -500,46 +564,6 @@ async function applyRefreshRules(api, chain, CHAIN_ID, ReactRefreshPlugin) {
500
564
  chain.resolve.alias.set('@lynx-js/react/refresh$', refresh);
501
565
  chain.plugin(PLUGIN_NAME_REACT_REFRESH).before(CHAIN_ID.PLUGIN.HMR).use(ReactRefreshPlugin).end().module.rule('react:refresh').issuerLayer(LAYERS.BACKGROUND).before(CHAIN_ID.RULE.JS).test(/\.[jt]sx$/).exclude.add(/node_modules/).add(node_path.dirname(reactRuntime)).add(node_path.dirname(refresh)).add(node_path.dirname(workletRuntime)).add(ReactRefreshPlugin.loader).end().use('ReactRefresh').loader(ReactRefreshPlugin.loader).options({}).end().end().end().end();
502
566
  }
503
- const isPlainObject = (obj)=>null !== obj && 'object' == typeof obj && '[object Object]' === Object.prototype.toString.call(obj);
504
- const applySplitChunksRule = (api)=>{
505
- api.modifyRsbuildConfig((config, { mergeRsbuildConfig })=>{
506
- const userConfig = api.getRsbuildConfig('original');
507
- const chunkSplitStrategy = userConfig.performance?.chunkSplit?.strategy;
508
- if (void 0 === userConfig.splitChunks && ('all-in-one' === chunkSplitStrategy || !chunkSplitStrategy)) return mergeRsbuildConfig(config, {
509
- splitChunks: false
510
- });
511
- return config;
512
- });
513
- api.modifyBundlerChain((chain, { environment })=>{
514
- const { config } = environment;
515
- const userConfig = api.getRsbuildConfig('original');
516
- const isSplitByExperience = void 0 === userConfig.splitChunks ? userConfig.performance?.chunkSplit?.strategy === 'split-by-experience' : isPlainObject(config.splitChunks) && 'default' === config.splitChunks.preset;
517
- if (!isSplitByExperience) return;
518
- const currentConfig = chain.optimization.splitChunks.values();
519
- if (!isPlainObject(currentConfig)) return;
520
- const extraGroups = {};
521
- extraGroups['preact'] = {
522
- name: 'lib-preact',
523
- test: /node_modules[\\/](.*?[\\/])?(?:(?:internal-)?preact|(?:internal-)?preact[\\/]compat|(?:internal-)?preact[\\/]hooks|(?:internal-)?preact[\\/]jsx-runtime)[\\/]/,
524
- priority: 0
525
- };
526
- chain.optimization.splitChunks({
527
- ...currentConfig,
528
- cacheGroups: {
529
- ...currentConfig.cacheGroups,
530
- ...extraGroups
531
- }
532
- });
533
- });
534
- api.modifyRspackConfig((rspackConfig)=>{
535
- if (!rspackConfig.optimization) return rspackConfig;
536
- if (!rspackConfig.optimization.splitChunks) return rspackConfig;
537
- rspackConfig.optimization.splitChunks.chunks = function(chunk) {
538
- return !chunk.name?.includes('__main-thread');
539
- };
540
- return rspackConfig;
541
- });
542
- };
543
567
  function applySWC(api) {
544
568
  api.modifyRsbuildConfig((config, { mergeRsbuildConfig })=>mergeRsbuildConfig({
545
569
  tools: {
@@ -1428,6 +1452,7 @@ function pluginReactLynx(userOptions) {
1428
1452
  engineVersion
1429
1453
  });
1430
1454
  return [
1455
+ pluginAutoLynx(),
1431
1456
  pluginReactAlias({
1432
1457
  lazy: resolvedOptions.experimental_isLazyBundle,
1433
1458
  elementTemplate: resolvedOptions.experimental_useElementTemplate,
@@ -1489,11 +1514,6 @@ function pluginReactLynx(userOptions) {
1489
1514
  if (resolvedOptions.optimizeBundleSize) applyOptimizeBundleSize(api, resolvedOptions);
1490
1515
  if (resolvedOptions.experimental_isLazyBundle) applyLazy(api);
1491
1516
  api.expose(Symbol.for('LAYERS'), LAYERS);
1492
- api.expose(Symbol.for('LynxTemplatePlugin'), {
1493
- LynxTemplatePlugin: {
1494
- getLynxTemplatePluginHooks: LynxTemplatePlugin.getLynxTemplatePluginHooks.bind(LynxTemplatePlugin)
1495
- }
1496
- });
1497
1517
  const require = createRequire(import.meta.url);
1498
1518
  const { version } = require('../package.json');
1499
1519
  const webpackPluginPath = require.resolve('@lynx-js/react-webpack-plugin');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/react-rsbuild-plugin",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "A rsbuild plugin for ReactLynx",
5
5
  "keywords": [
6
6
  "rsbuild",
@@ -33,21 +33,23 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "tiny-invariant": "^1.3.3",
36
- "@lynx-js/css-extract-webpack-plugin": "0.10.1",
37
- "@lynx-js/react-alias-rsbuild-plugin": "0.19.0",
36
+ "@lynx-js/css-extract-webpack-plugin": "0.11.0",
37
+ "@lynx-js/react-webpack-plugin": "0.11.2",
38
38
  "@lynx-js/react-refresh-webpack-plugin": "0.4.2",
39
- "@lynx-js/react-webpack-plugin": "0.11.0",
40
- "@lynx-js/runtime-wrapper-webpack-plugin": "0.2.3",
41
- "@lynx-js/template-webpack-plugin": "0.15.1",
39
+ "@lynx-js/rsbuild-plugin": "0.1.0",
40
+ "@lynx-js/runtime-config-webpack-plugin": "0.0.1",
41
+ "@lynx-js/react-alias-rsbuild-plugin": "0.20.0",
42
+ "@lynx-js/runtime-wrapper-webpack-plugin": "0.2.4",
43
+ "@lynx-js/template-webpack-plugin": "0.16.0",
42
44
  "@lynx-js/use-sync-external-store": "1.5.0",
43
45
  "background-only": "^0.0.1"
44
46
  },
45
47
  "devDependencies": {
46
48
  "@microsoft/api-extractor": "7.58.12",
47
- "@rsbuild/core": "2.1.10",
49
+ "@rsbuild/core": "2.2.3",
48
50
  "@rsbuild/plugin-sass": "2.0.1",
49
51
  "@rsbuild/plugin-typed-css-modules": "1.2.4",
50
- "@rstest/core": "0.11.6",
52
+ "@rstest/core": "0.11.12",
51
53
  "rsbuild-plugin-arethetypeswrong": "0.3.1",
52
54
  "rsbuild-plugin-publint": "1.0.0",
53
55
  "source-map": "^0.8.0",
@@ -55,19 +57,27 @@
55
57
  "type-fest": "^5.8.0",
56
58
  "typia": "12.1.1",
57
59
  "typia-rspack-plugin": "3.0.1",
58
- "@lynx-js/config-rsbuild-plugin": "0.2.2",
60
+ "@lynx-js/config-rsbuild-plugin": "0.2.3",
59
61
  "@lynx-js/debug-metadata": "0.1.0",
60
- "@lynx-js/react": "0.124.0",
62
+ "@lynx-js/react": "0.126.0",
61
63
  "@lynx-js/react-transform": "0.2.0",
62
- "@lynx-js/rspeedy": "0.16.4",
64
+ "@lynx-js/rspeedy": "0.17.0",
63
65
  "@lynx-js/test-tools": "0.0.0"
64
66
  },
65
67
  "peerDependencies": {
66
- "@lynx-js/react": "^0.124.0"
68
+ "@lynx-js/react": "^0.124.0 || ^0.125.0 || ^0.126.0",
69
+ "@lynx-js/rspeedy": "^0.17.0",
70
+ "@rsbuild/core": "^2.0.0"
67
71
  },
68
72
  "peerDependenciesMeta": {
69
73
  "@lynx-js/react": {
70
74
  "optional": true
75
+ },
76
+ "@lynx-js/rspeedy": {
77
+ "optional": true
78
+ },
79
+ "@rsbuild/core": {
80
+ "optional": true
71
81
  }
72
82
  },
73
83
  "engines": {