github lynx-family/lynx-stack @lynx-js/react-rsbuild-plugin@0.18.0

Minor Changes

  • Stop injecting webpackChunkName into dynamic imports so lazy bundle intermediate files stay inside the output directory. (#2961)

    The ReactLynx transform injected webpackChunkName: "<request>-react__<layer>", so a dynamic import resolving above the compiler context (e.g. import('../../Foo.js')) leaked ../ into [name]/[id] and the intermediate js/css/hmr files escaped the output directory. Async chunks now keep rspack's own ids, __webpack_require__.lynx_aci maps them by chunk id, and each lazy bundle's intermediate JS and CSS are emitted under .rspeedy/async/<bundle-name>/<layer>.js and <layer>.css next to its other intermediate outputs (tasm.json, debug-metadata.json, CSS hot-update files). Explicit webpackChunkName comments written by users are still honored and keep the user-controlled [name] placement. Main-thread chunks no longer emit CSS hot-update files — CSS only exists on the background thread, and the main-thread HMR runtime receives updates from it.

    These packages release together and must be upgraded together: @lynx-js/react-webpack-plugin and @lynx-js/css-extract-webpack-plugin require @lynx-js/template-webpack-plugin ^0.13.0, and @lynx-js/react-rsbuild-plugin requires @lynx-js/react ^0.123.0.

  • Choose the lazy bundle loader from engineVersion: use the new fetchBundle (#2584)
    loader when engineVersion >= 3.9, otherwise keep the legacy QueryComponent
    loader.

    import('./Foo.jsx', { with: { mode: 'sync' | 'async' } })

    Force a loader regardless of engineVersion with the REACT_LAZY_BUNDLE_FETCHER
    env var (FetchBundle / QueryComponent).

  • Add firstScreenSyncTiming: 'manual' and a new markFirstScreenSyncReady() API exported by @lynx-js/react. (#2826)

    In 'manual' mode, the main thread holds the UI control after the first screen until the business calls markFirstScreenSyncReady(), so the handover timing to the background thread (for hydration) is fully controlled by the user. The API can be called from both threads (a background-thread call is forwarded to the main thread) and takes effect once the first-screen tree has finished rendering.

    pluginReactLynx({
      firstScreenSyncTiming: 'manual',
    })
    import { markFirstScreenSyncReady } from '@lynx-js/react'
    
    markFirstScreenSyncReady()

Patch Changes

  • Add compat.legacySlot to pluginReactLynx. When enabled, dynamic children are compiled to the pre-SlotV2 form (JSX children + wrapper elements + __DynamicPartChildren/__DynamicPartSlot symbols instead of $0/$1 slot props + SlotV2), so the compiled output stays compatible with legacy runtimes without SlotV2 support (< 0.120.0, which shipped the SlotV2 refactor in #1764) — e.g. a standalone lazy bundle consumed by a host App that ships an older runtime. (#2947)

    import { defineConfig } from '@lynx-js/rspeedy'
    import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin'
    
    export default defineConfig({
      plugins: [
        pluginReactLynx({
          compat: {
            legacySlot: true,
          },
        }),
      ],
    })

    The default (SlotV2) codegen is unchanged, and the runtime keeps supporting both forms.

  • Updated dependencies [0a5f3f2, 983e33d, 1064984, a10dbd8, 34318ea, fec4237, 2b5d83a, 2b5d83a, fec4237, fec4237, fec4237, 983e33d]:

    • @lynx-js/react-webpack-plugin@0.10.0
    • @lynx-js/react-refresh-webpack-plugin@0.4.1
    • @lynx-js/react-alias-rsbuild-plugin@0.18.0
    • @lynx-js/css-extract-webpack-plugin@0.9.0
    • @lynx-js/template-webpack-plugin@0.13.0
    • @lynx-js/use-sync-external-store@1.5.0
    • @lynx-js/runtime-wrapper-webpack-plugin@0.2.2

Don't miss a new lynx-stack release

NewReleases is sending notifications on new releases.