From 538e38b5be876a32682e0a6272ee6516f97fa243 Mon Sep 17 00:00:00 2001 From: "dm.choi" Date: Mon, 6 Jul 2026 12:44:46 +0900 Subject: [PATCH 01/37] fix(devtools): guard invalid module info payloads (#4787) Co-authored-by: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Co-authored-by: ScriptedAlchemy Co-authored-by: Hanric --- .changeset/quiet-devtools-module-info.md | 5 + .../__tests__/module-info-payload.spec.ts | 193 ++++++++++++++++++ packages/chrome-devtools/src/App.tsx | 5 +- .../chrome-devtools/src/utils/chrome/index.ts | 87 ++++++-- .../src/utils/chrome/post-message-listener.ts | 13 +- 5 files changed, 279 insertions(+), 24 deletions(-) create mode 100644 .changeset/quiet-devtools-module-info.md create mode 100644 packages/chrome-devtools/__tests__/module-info-payload.spec.ts diff --git a/.changeset/quiet-devtools-module-info.md b/.changeset/quiet-devtools-module-info.md new file mode 100644 index 00000000000..5e59a64195a --- /dev/null +++ b/.changeset/quiet-devtools-module-info.md @@ -0,0 +1,5 @@ +--- +'@module-federation/devtools': patch +--- + +Guard Chrome DevTools module info sync against invalid undefined placeholder payloads. diff --git a/packages/chrome-devtools/__tests__/module-info-payload.spec.ts b/packages/chrome-devtools/__tests__/module-info-payload.spec.ts new file mode 100644 index 00000000000..00bf9f8c387 --- /dev/null +++ b/packages/chrome-devtools/__tests__/module-info-payload.spec.ts @@ -0,0 +1,193 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; + +import { + getGlobalModuleInfo, + normalizeModuleInfoPayload, +} from '../src/utils/chrome'; +import { + MESSAGE_ACTIVE_TAB_CHANGED, + MESSAGE_OBSERVABILITY_DEVTOOLS_EVENT, +} from '../src/utils/chrome/messages'; + +const dispatchModuleInfoMessage = (moduleInfo: unknown) => { + window.dispatchEvent( + new MessageEvent('message', { + data: { + moduleInfo, + }, + origin: 'https://example.com', + }), + ); +}; + +const dispatchRawMessageData = (data: unknown) => { + window.dispatchEvent( + new MessageEvent('message', { + data, + origin: 'https://example.com', + }), + ); +}; + +describe('normalizeModuleInfoPayload', () => { + afterEach(() => { + vi.useRealTimers(); + vi.resetModules(); + vi.restoreAllMocks(); + Reflect.deleteProperty(globalThis, 'chrome'); + Reflect.deleteProperty(window, 'moduleHandler'); + Reflect.deleteProperty(window, '__FEDERATION__'); + Reflect.deleteProperty(window, '__VMOK__'); + }); + + it('drops undefined placeholders produced by safe post message serialization', () => { + expect(normalizeModuleInfoPayload('[undefined]')).toEqual({}); + }); + + it('drops non-object module info payloads', () => { + expect(normalizeModuleInfoPayload(undefined)).toEqual({}); + expect(normalizeModuleInfoPayload(null)).toEqual({}); + expect(normalizeModuleInfoPayload([])).toEqual({}); + }); + + it('keeps valid module info snapshots', () => { + expect( + normalizeModuleInfoPayload({ + 'host:http://localhost:3000/mf-manifest.json': { + remotesInfo: {}, + }, + broken: '[undefined]', + }), + ).toEqual({ + 'host:http://localhost:3000/mf-manifest.json': { + remotesInfo: {}, + }, + }); + }); + + it('does not relay undefined placeholders from the page message listener', async () => { + const sendMessage = vi.fn(() => Promise.resolve()); + vi.stubGlobal('chrome', { + runtime: { + sendMessage, + }, + }); + + await import('../src/utils/chrome/post-message-listener'); + + dispatchModuleInfoMessage('[undefined]'); + expect(sendMessage).not.toHaveBeenCalled(); + + dispatchRawMessageData(null); + dispatchRawMessageData('[undefined]'); + expect(sendMessage).not.toHaveBeenCalled(); + + dispatchModuleInfoMessage({ + 'host:http://localhost:3000/mf-manifest.json': { + remotesInfo: {}, + }, + }); + expect(sendMessage).toHaveBeenCalledTimes(1); + }); + + it('ignores unrelated runtime messages without clearing cached module info', async () => { + vi.useFakeTimers(); + + const moduleInfo = { + 'host:http://localhost:3000/mf-manifest.json': { + remotesInfo: {}, + }, + }; + window.__FEDERATION__ = { + moduleInfo, + } as any; + window.__VMOK__ = window.__FEDERATION__; + + let runtimeListener: + | ((message: { data?: unknown; type?: string; tabId?: number }) => void) + | undefined; + const addListener = vi.fn((listener) => { + runtimeListener = listener; + }); + const removeListener = vi.fn(); + + vi.stubGlobal('chrome', { + runtime: { + getURL: (file: string) => `chrome-extension://id/${file}`, + onMessage: { + addListener, + removeListener, + }, + }, + devtools: { + inspectedWindow: { + tabId: 1, + eval: vi.fn((_code: string, callback) => { + callback(true, undefined); + }), + }, + }, + tabs: { + query: vi.fn().mockResolvedValue([{ id: 1 }]), + }, + scripting: { + executeScript: vi.fn().mockResolvedValue([]), + }, + }); + + const callback = vi.fn(); + const cleanupPromise = getGlobalModuleInfo(callback); + + expect(callback).toHaveBeenCalledWith(moduleInfo); + await vi.advanceTimersByTimeAsync(300); + expect(addListener).toHaveBeenCalledTimes(1); + + runtimeListener?.({ + type: MESSAGE_ACTIVE_TAB_CHANGED, + tabId: 1, + }); + runtimeListener?.({ + type: MESSAGE_OBSERVABILITY_DEVTOOLS_EVENT, + data: { + kind: 'installed', + }, + }); + + expect(window.__FEDERATION__?.moduleInfo).toEqual(moduleInfo); + expect(callback).toHaveBeenCalledTimes(1); + + runtimeListener?.({ + data: { + share: { + default: {}, + }, + }, + }); + + expect(window.__FEDERATION__?.moduleInfo).toEqual(moduleInfo); + expect(window.__FEDERATION__?.__SHARE__).toEqual({ + default: {}, + }); + expect(callback).toHaveBeenCalledTimes(2); + + const nextModuleInfo = { + 'remote:http://localhost:3001/mf-manifest.json': { + remoteEntry: 'http://localhost:3001/remoteEntry.js', + version: 'http://localhost:3001/remoteEntry.js', + }, + }; + runtimeListener?.({ + data: { + moduleInfo: nextModuleInfo, + }, + }); + + expect(window.__FEDERATION__?.moduleInfo).toEqual(nextModuleInfo); + expect(callback).toHaveBeenCalledWith(nextModuleInfo); + + await vi.advanceTimersByTimeAsync(50); + const cleanup = await cleanupPromise; + cleanup(); + expect(removeListener).toHaveBeenCalledWith(runtimeListener); + }); +}); diff --git a/packages/chrome-devtools/src/App.tsx b/packages/chrome-devtools/src/App.tsx index b01045e0e6d..767bccc85f9 100644 --- a/packages/chrome-devtools/src/App.tsx +++ b/packages/chrome-devtools/src/App.tsx @@ -16,6 +16,7 @@ import LanguageSwitch from './component/LanguageSwitch'; import ThemeToggle from './component/ThemeToggle'; import { getGlobalModuleInfo, + normalizeModuleInfoPayload, refreshModuleInfo, RootComponentProps, separateType, @@ -31,10 +32,10 @@ import btnStyles from './component/ThemeToggle.module.scss'; const cloneModuleInfo = (info?: GlobalModuleInfo | null): GlobalModuleInfo => { try { - return JSON.parse(JSON.stringify(info || {})); + return normalizeModuleInfoPayload(info); } catch (error) { console.warn('[MF Devtools] cloneModuleInfo failed', error); - return info || {}; + return {}; } }; diff --git a/packages/chrome-devtools/src/utils/chrome/index.ts b/packages/chrome-devtools/src/utils/chrome/index.ts index 25c2d315b84..d756d9edb2d 100644 --- a/packages/chrome-devtools/src/utils/chrome/index.ts +++ b/packages/chrome-devtools/src/utils/chrome/index.ts @@ -5,6 +5,40 @@ import { sanitizePostMessagePayload } from './safe-post-message'; export * from './storage'; +const isModuleInfoRecord = (value: unknown): value is Record => + Boolean(value) && typeof value === 'object' && !Array.isArray(value); + +type ModuleInfoSyncMessage = { + moduleInfo?: unknown; + updateModule?: unknown; + share?: unknown; + appInfos?: unknown; +}; + +const isModuleInfoSyncMessage = ( + value: unknown, +): value is ModuleInfoSyncMessage => + isModuleInfoRecord(value) && + ('moduleInfo' in value || 'updateModule' in value || 'share' in value); + +export const normalizeModuleInfoPayload = ( + moduleInfo: unknown, +): GlobalModuleInfo => { + const sanitized = sanitizePostMessagePayload(moduleInfo); + if (!isModuleInfoRecord(sanitized)) { + return {} as GlobalModuleInfo; + } + return Object.entries(sanitized).reduce( + (moduleMap, [moduleId, snapshot]) => { + if (moduleId === 'extendInfos' || isModuleInfoRecord(snapshot)) { + moduleMap[moduleId] = snapshot as GlobalModuleInfo[string]; + } + return moduleMap; + }, + {}, + ); +}; + const sleep = (num: number) => { return new Promise((resolve) => { setTimeout(() => { @@ -109,47 +143,60 @@ export const getGlobalModuleInfo = async ( callback: (moduleInfo: GlobalModuleInfo) => void, ) => { if (typeof window !== 'undefined' && window.__FEDERATION__?.moduleInfo) { - callback( - sanitizePostMessagePayload( - window.__FEDERATION__?.moduleInfo, - ) as GlobalModuleInfo, - ); + callback(normalizeModuleInfoPayload(window.__FEDERATION__?.moduleInfo)); } await sleep(300); const listener = (message: { origin: string; data: any }) => { const { data } = message; - if (!data || data?.appInfos) { + if (!isModuleInfoSyncMessage(data) || data?.appInfos) { return; } if (!window?.__FEDERATION__) { definePropertyGlobalVal(window, '__FEDERATION__', {}); definePropertyGlobalVal(window, '__VMOK__', window.__FEDERATION__); } - window.__FEDERATION__.originModuleInfo = sanitizePostMessagePayload( - data?.moduleInfo, - ); - if (data?.updateModule) { + window.__FEDERATION__.originModuleInfo = + 'moduleInfo' in data + ? normalizeModuleInfoPayload(data.moduleInfo) + : normalizeModuleInfoPayload( + window.__FEDERATION__.originModuleInfo || + window.__FEDERATION__.moduleInfo, + ); + const updateModule = data.updateModule; + if ( + isModuleInfoRecord(updateModule) && + typeof updateModule.name === 'string' + ) { + const updateModuleName = updateModule.name; const moduleIds = Object.keys(window.__FEDERATION__.originModuleInfo); const shouldUpdate = !moduleIds.some((id) => - id.includes(data.updateModule.name), + id.includes(updateModuleName), ); if (shouldUpdate) { const destination = - data.updateModule.entry || data.updateModule.version; - window.__FEDERATION__.originModuleInfo[ - `${data.updateModule.name}:${destination}` - ] = { - remoteEntry: destination, - version: destination, - }; + typeof updateModule.entry === 'string' + ? updateModule.entry + : typeof updateModule.version === 'string' + ? updateModule.version + : undefined; + if (destination) { + window.__FEDERATION__.originModuleInfo[ + `${updateModuleName}:${destination}` + ] = { + remoteEntry: destination, + version: destination, + }; + } } } if (data?.share) { - window.__FEDERATION__.__SHARE__ = sanitizePostMessagePayload(data.share); + window.__FEDERATION__.__SHARE__ = sanitizePostMessagePayload( + data.share, + ) as typeof window.__FEDERATION__.__SHARE__; } - window.__FEDERATION__.moduleInfo = sanitizePostMessagePayload( + window.__FEDERATION__.moduleInfo = normalizeModuleInfoPayload( window.__FEDERATION__.originModuleInfo, ); console.log('getGlobalModuleInfo window', window.__FEDERATION__); diff --git a/packages/chrome-devtools/src/utils/chrome/post-message-listener.ts b/packages/chrome-devtools/src/utils/chrome/post-message-listener.ts index 7f5c06a4329..9980071f303 100644 --- a/packages/chrome-devtools/src/utils/chrome/post-message-listener.ts +++ b/packages/chrome-devtools/src/utils/chrome/post-message-listener.ts @@ -4,11 +4,20 @@ import { OBSERVABILITY_DEVTOOLS_SOURCE, } from './messages'; +const isModuleInfoPayload = (value: unknown) => + Boolean(value) && typeof value === 'object' && !Array.isArray(value); + +const getMessageData = (data: unknown) => + Boolean(data) && typeof data === 'object' + ? (data as Record) + : {}; + if (window.moduleHandler) { window.removeEventListener('message', window.moduleHandler); } else { window.moduleHandler = (event) => { - const { origin, data } = event; + const { origin } = event; + const data = getMessageData(event.data); if (data?.source === OBSERVABILITY_DEVTOOLS_SOURCE) { chrome.runtime .sendMessage({ @@ -22,7 +31,7 @@ if (window.moduleHandler) { return; } - if (!data.moduleInfo) { + if (!isModuleInfoPayload(data.moduleInfo)) { return; } From f0ad9b51763d1ecf9d8fe105da0698411b7f5010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor=20Lopes?= Date: Mon, 6 Jul 2026 04:32:29 -0300 Subject: [PATCH 02/37] feat(i18n): add Brazilian Portuguese localization and documentation (#4850) Co-authored-by: Hanric --- .../pt-BR/_components/EnableAsyncEntry.mdx | 24 + .../pt-BR/_components/cli/view-all-cmds.mdx | 21 + .../configure/mf-manifest-stats-common.mdx | 68 ++ ...eate-shared-tree-shaking-deploy-server.mdx | 44 + .../pt-BR/_components/data-fetch/consumer.mdx | 34 + .../_components/data-fetch/prefetch-demo.mdx | 34 + .../_components/data-fetch/prefetch-tip.mdx | 5 + .../_components/data-fetch/provider-tip.mdx | 3 + .../docs/pt-BR/_components/runtime/index.mdx | 31 + .../pt-BR/_components/secondary-build.mdx | 70 ++ apps/website-new/docs/pt-BR/_nav.json | 113 ++ apps/website-new/docs/pt-BR/ai/index.mdx | 116 ++ apps/website-new/docs/pt-BR/ai/skill.mdx | 135 +++ apps/website-new/docs/pt-BR/blog/_meta.json | 16 + .../docs/pt-BR/blog/announcement.mdx | 116 ++ .../docs/pt-BR/blog/error-load-remote.mdx | 597 +++++++++ .../docs/pt-BR/blog/hoisted-runtime.mdx | 77 ++ apps/website-new/docs/pt-BR/blog/index.mdx | 31 + apps/website-new/docs/pt-BR/blog/node.mdx | 76 ++ .../docs/pt-BR/blog/v2-stable-version.mdx | 149 +++ .../docs/pt-BR/configure/_meta.json | 107 ++ apps/website-new/docs/pt-BR/configure/dev.mdx | 40 + apps/website-new/docs/pt-BR/configure/dts.mdx | 394 ++++++ .../docs/pt-BR/configure/experiments.mdx | 103 ++ .../docs/pt-BR/configure/exposes.mdx | 44 + .../docs/pt-BR/configure/filename.mdx | 6 + .../docs/pt-BR/configure/getpublicpath.mdx | 37 + .../docs/pt-BR/configure/implementation.mdx | 25 + .../docs/pt-BR/configure/index.mdx | 38 + .../injectTreeShakingUsedExports.mdx | 11 + .../docs/pt-BR/configure/library.mdx | 101 ++ .../docs/pt-BR/configure/manifest.mdx | 52 + .../website-new/docs/pt-BR/configure/name.mdx | 8 + .../docs/pt-BR/configure/remotes.mdx | 77 ++ .../docs/pt-BR/configure/remotetype.mdx | 59 + .../docs/pt-BR/configure/runtimeplugins.mdx | 101 ++ .../docs/pt-BR/configure/shareScope.mdx | 51 + .../docs/pt-BR/configure/shareStrategy.mdx | 49 + .../docs/pt-BR/configure/shared.mdx | 260 ++++ .../docs/pt-BR/configure/treeShakingDir.mdx | 8 + .../treeShakingSharedExcludePlugins.mdx | 8 + .../configure/treeShakingSharedPlugins.mdx | 34 + apps/website-new/docs/pt-BR/guide/_meta.json | 47 + .../docs/pt-BR/guide/advanced/_meta.json | 14 + .../pt-BR/guide/advanced/manifest-fields.mdx | 71 ++ .../guide/advanced/multiple-shared-scope.mdx | 266 ++++ .../guide/advanced/shared-tree-shaking.mdx | 130 ++ .../pt-BR/guide/advanced/stats-fields.mdx | 73 ++ .../docs/pt-BR/guide/basic/_meta.json | 6 + .../docs/pt-BR/guide/basic/cli.mdx | 42 + .../docs/pt-BR/guide/basic/css-isolate.mdx | 170 +++ .../pt-BR/guide/basic/manifest-snapshot.mdx | 116 ++ .../docs/pt-BR/guide/basic/type-prompt.mdx | 100 ++ .../docs/pt-BR/guide/bridge/_meta.json | 14 + .../docs/pt-BR/guide/bridge/overview.mdx | 298 +++++ .../docs/pt-BR/guide/bridge/react/_meta.json | 22 + .../pt-BR/guide/bridge/react/export-app.mdx | 265 ++++ .../guide/bridge/react/getting-started.mdx | 64 + .../pt-BR/guide/bridge/react/load-app.mdx | 307 +++++ .../guide/bridge/react/load-component.mdx | 295 +++++ .../docs/pt-BR/guide/data/_meta.json | 17 + .../pt-BR/guide/data/data-fetch-cache.mdx | 322 +++++ .../docs/pt-BR/guide/data/data-fetch.mdx | 210 ++++ .../docs/pt-BR/guide/data/data-prefetch.mdx | 49 + .../docs/pt-BR/guide/debug/_meta.json | 5 + .../docs/pt-BR/guide/debug/chrome-devtool.mdx | 151 +++ .../docs/pt-BR/guide/debug/mode.mdx | 25 + .../docs/pt-BR/guide/debug/variables.mdx | 909 ++++++++++++++ .../docs/pt-BR/guide/deployment/_meta.json | 3 + .../docs/pt-BR/guide/deployment/zephyr.mdx | 41 + .../docs/pt-BR/guide/runtime/_meta.json | 22 + .../docs/pt-BR/guide/runtime/index.mdx | 342 ++++++ .../docs/pt-BR/guide/runtime/runtime-api.mdx | 983 +++++++++++++++ .../pt-BR/guide/runtime/runtime-hooks.mdx | 1066 +++++++++++++++++ .../pt-BR/guide/runtime/runtime-plugins.mdx | 308 +++++ .../docs/pt-BR/guide/start/_meta.json | 5 + .../docs/pt-BR/guide/start/glossary.mdx | 46 + .../docs/pt-BR/guide/start/index.mdx | 73 ++ .../docs/pt-BR/guide/start/npm-packages.mdx | 65 + .../docs/pt-BR/guide/start/quick-start.mdx | 212 ++++ .../pt-BR/guide/troubleshooting/_meta.json | 5 + .../pt-BR/guide/troubleshooting/build.mdx | 88 ++ .../pt-BR/guide/troubleshooting/runtime.mdx | 526 ++++++++ .../docs/pt-BR/guide/troubleshooting/type.mdx | 89 ++ apps/website-new/docs/pt-BR/index.md | 34 + .../docs/pt-BR/integrations/_meta.json | 36 + .../pt-BR/integrations/build-tool/_meta.json | 17 + .../pt-BR/integrations/build-tool/rsbuild.mdx | 140 +++ .../pt-BR/integrations/build-tool/rslib.mdx | 75 ++ .../pt-BR/integrations/build-tool/vite.mdx | 63 + .../pt-BR/integrations/bundler/_meta.json | 5 + .../docs/pt-BR/integrations/bundler/metro.mdx | 282 +++++ .../pt-BR/integrations/bundler/rspack.mdx | 46 + .../pt-BR/integrations/bundler/webpack.mdx | 43 + .../integrations/documentation/_meta.json | 7 + .../integrations/documentation/rspress.mdx | 162 +++ .../pt-BR/integrations/framework/_meta.json | 30 + .../integrations/framework/angular/_meta.json | 12 + .../framework/angular/angular-cli.mdx | 231 ++++ .../framework/angular/angular-mfe.mdx | 334 ++++++ .../integrations/framework/angular/auth0.mdx | 146 +++ .../integrations/framework/angular/index.mdx | 16 + .../framework/angular/mf-ssr-angular.mdx | 115 ++ .../framework/angular/okta-auth.mdx | 253 ++++ .../framework/angular/service-workers-mf.mdx | 276 +++++ .../angular/splitting-to-mf-part1.mdx | 299 +++++ .../angular/splitting-to-mf-part2.mdx | 155 +++ .../angular/using-nx-for-angular.mdx | 172 +++ .../framework/modernjs/_meta.json | 5 + .../framework/modernjs/dynamic-remote.mdx | 202 ++++ .../integrations/framework/modernjs/index.mdx | 202 ++++ .../framework/modernjs/quick-start.mdx | 279 +++++ .../framework/monorepos/_meta.json | 4 + .../framework/monorepos/index.mdx | 99 ++ .../monorepos/nx-for-module-federation.mdx | 102 ++ .../integrations/framework/nextjs/_meta.json | 9 + .../framework/nextjs/basic-example.mdx | 490 ++++++++ .../framework/nextjs/dynamic-remotes.mdx | 19 + .../integrations/framework/nextjs/express.mdx | 77 ++ .../framework/nextjs/importing-components.mdx | 89 ++ .../framework/nextjs/importing-pages.mdx | 134 +++ .../integrations/framework/nextjs/index.mdx | 314 +++++ .../integrations/framework/nextjs/presets.mdx | 138 +++ .../docs/pt-BR/integrations/index.mdx | 27 + .../pt-BR/integrations/practice/_meta.json | 19 + .../pt-BR/integrations/practice/index.mdx | 14 + .../integrations/practice/react/_meta.json | 10 + .../practice/react/i18n-react.mdx | 210 ++++ .../integrations/practice/react/index.mdx | 20 + .../practice/react/rsbuild-cra.mdx | 313 +++++ .../practice/react/using-nx-for-react.mdx | 172 +++ .../docs/pt-BR/integrations/practice/vue.mdx | 253 ++++ apps/website-new/docs/pt-BR/plugin/_meta.json | 12 + .../docs/pt-BR/plugin/dev/_meta.json | 3 + .../docs/pt-BR/plugin/dev/index.mdx | 107 ++ .../docs/pt-BR/plugin/plugins/_meta.json | 6 + .../plugins/building-custom-retry-plugin.mdx | 450 +++++++ .../docs/pt-BR/plugin/plugins/index.mdx | 67 ++ .../plugin/plugins/observability-plugin.mdx | 490 ++++++++ .../pt-BR/plugin/plugins/retry-plugin.mdx | 292 +++++ .../docs/pt-BR/showcase/_meta.json | 3 + .../website-new/docs/pt-BR/showcase/index.mdx | 15 + apps/website-new/i18n.json | 89 ++ apps/website-new/rspress.config.ts | 34 +- apps/website-new/theme/i18n/index.ts | 2 + apps/website-new/theme/i18n/ptBR.ts | 26 + 146 files changed, 18967 insertions(+), 14 deletions(-) create mode 100644 apps/website-new/docs/pt-BR/_components/EnableAsyncEntry.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/cli/view-all-cmds.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/configure/mf-manifest-stats-common.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/create-shared-tree-shaking-deploy-server.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/data-fetch/consumer.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-demo.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-tip.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/data-fetch/provider-tip.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/runtime/index.mdx create mode 100644 apps/website-new/docs/pt-BR/_components/secondary-build.mdx create mode 100644 apps/website-new/docs/pt-BR/_nav.json create mode 100644 apps/website-new/docs/pt-BR/ai/index.mdx create mode 100644 apps/website-new/docs/pt-BR/ai/skill.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/_meta.json create mode 100644 apps/website-new/docs/pt-BR/blog/announcement.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/error-load-remote.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/hoisted-runtime.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/index.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/node.mdx create mode 100644 apps/website-new/docs/pt-BR/blog/v2-stable-version.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/_meta.json create mode 100644 apps/website-new/docs/pt-BR/configure/dev.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/dts.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/experiments.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/exposes.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/filename.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/getpublicpath.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/implementation.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/index.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/injectTreeShakingUsedExports.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/library.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/manifest.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/name.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/remotes.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/remotetype.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/runtimeplugins.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/shareScope.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/shareStrategy.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/shared.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/treeShakingDir.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/treeShakingSharedExcludePlugins.mdx create mode 100644 apps/website-new/docs/pt-BR/configure/treeShakingSharedPlugins.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/manifest-fields.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/multiple-shared-scope.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/shared-tree-shaking.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/stats-fields.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/basic/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/basic/cli.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/basic/css-isolate.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/basic/manifest-snapshot.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/basic/type-prompt.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/overview.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/react/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/react/export-app.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/react/getting-started.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/react/load-app.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/bridge/react/load-component.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/data/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/data/data-fetch-cache.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/data/data-fetch.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/data/data-prefetch.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/debug/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/debug/chrome-devtool.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/debug/mode.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/debug/variables.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/deployment/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/deployment/zephyr.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/runtime/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/runtime/index.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/runtime/runtime-api.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/runtime/runtime-hooks.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/runtime/runtime-plugins.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/start/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/start/glossary.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/start/index.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/start/npm-packages.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/start/quick-start.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/troubleshooting/_meta.json create mode 100644 apps/website-new/docs/pt-BR/guide/troubleshooting/build.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/troubleshooting/runtime.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/troubleshooting/type.mdx create mode 100644 apps/website-new/docs/pt-BR/index.md create mode 100644 apps/website-new/docs/pt-BR/integrations/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/build-tool/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/build-tool/rsbuild.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/build-tool/rslib.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/build-tool/vite.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/bundler/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/bundler/metro.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/bundler/rspack.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/bundler/webpack.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/documentation/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/documentation/rspress.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/angular-cli.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/angular-mfe.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/auth0.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/mf-ssr-angular.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/okta-auth.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/service-workers-mf.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/splitting-to-mf-part1.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/splitting-to-mf-part2.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/angular/using-nx-for-angular.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/modernjs/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/modernjs/dynamic-remote.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/modernjs/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/modernjs/quick-start.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/monorepos/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/monorepos/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/monorepos/nx-for-module-federation.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/basic-example.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/dynamic-remotes.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/express.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/importing-components.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/importing-pages.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/framework/nextjs/presets.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/react/_meta.json create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/react/i18n-react.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/react/index.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/react/rsbuild-cra.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/react/using-nx-for-react.mdx create mode 100644 apps/website-new/docs/pt-BR/integrations/practice/vue.mdx create mode 100644 apps/website-new/docs/pt-BR/plugin/_meta.json create mode 100644 apps/website-new/docs/pt-BR/plugin/dev/_meta.json create mode 100644 apps/website-new/docs/pt-BR/plugin/dev/index.mdx create mode 100644 apps/website-new/docs/pt-BR/plugin/plugins/_meta.json create mode 100644 apps/website-new/docs/pt-BR/plugin/plugins/building-custom-retry-plugin.mdx create mode 100644 apps/website-new/docs/pt-BR/plugin/plugins/index.mdx create mode 100644 apps/website-new/docs/pt-BR/plugin/plugins/observability-plugin.mdx create mode 100644 apps/website-new/docs/pt-BR/plugin/plugins/retry-plugin.mdx create mode 100644 apps/website-new/docs/pt-BR/showcase/_meta.json create mode 100644 apps/website-new/docs/pt-BR/showcase/index.mdx create mode 100644 apps/website-new/i18n.json create mode 100644 apps/website-new/theme/i18n/ptBR.ts diff --git a/apps/website-new/docs/pt-BR/_components/EnableAsyncEntry.mdx b/apps/website-new/docs/pt-BR/_components/EnableAsyncEntry.mdx new file mode 100644 index 00000000000..d0f0f8970c7 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/EnableAsyncEntry.mdx @@ -0,0 +1,24 @@ +Se o `@module-federation/modern-js-v3` plugin é usado, o corresponding asynchronous entry vai ser habilitado based no builder tipo por padrão. + +But se it é [build mode](https://modernjs.dev/en/guides/concept/entries.html#build-mode-entry), then você still precisa definir o asynchronous entry manually. + +Next, nós vai demonstrate como para habilite asynchronous entry. + +Crie o bootstrap.js arquivo e copy o contents do original arquivo de entrada here: + +```diff title="bootstrap.js" ++ import React from 'react'; ++ import ReactDOM from 'react-dom'; ++ import App from './App'; ++ ReactDOM.render(, document.getElementById('root')); +``` + +Modify o content do original arquivo de entrada e reference bootstrap.js instead: + +```diff title="index.js" ++ import('./bootstrap'); +- import React from 'react'; +- import ReactDOM from 'react-dom'; +- import App from './App'; +- ReactDOM.render(, document.getElementById('root')); +``` diff --git a/apps/website-new/docs/pt-BR/_components/cli/view-all-cmds.mdx b/apps/website-new/docs/pt-BR/_components/cli/view-all-cmds.mdx new file mode 100644 index 00000000000..e50262d724a --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/cli/view-all-cmds.mdx @@ -0,0 +1,21 @@ +Se você precisa view all disponível CLI comandos, please run o seguintes comando no projeto diretório: + +```bash +npx mf -h +``` + +Output: + +```bash + +Usage: mf [options] + +Options: + -V, --version output the version number + -h, --help display help for command + +Commands: + dts [options] generate or fetch the mf types + help [command] display help for command + +``` diff --git a/apps/website-new/docs/pt-BR/_components/configure/mf-manifest-stats-common.mdx b/apps/website-new/docs/pt-BR/_components/configure/mf-manifest-stats-common.mdx new file mode 100644 index 00000000000..f37ef0ccc51 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/configure/mf-manifest-stats-common.mdx @@ -0,0 +1,68 @@ +## metaData (Both Arquivos) + +`metaData` describes como este build é consumido em runtime e o build context. Both `mf-stats.json` e `mf-manifest.json` include it. + +### StatsMetaData + +`StatsMetaData` has two mutually exclusive shapes: + +- **Função form**: `getPublicPath: string` +- **String form**: `publicPath: string` (opcional `ssrPublicPath: string`) + +Shared fields: + +| Field | Tipo | Obrigatório | Description | +| ---------------- | ---------------- | -------- | ------------------------------- | +| `name` | `string` | Yes | Current remote/host name | +| `globalName` | `string` | Yes | Global name for o remoteEntry | +| `buildInfo` | `StatsBuildInfo` | Yes | Build information | +| `remoteEntry` | `ResourceInfo` | Yes | Remote entry resource | +| `ssrRemoteEntry` | `ResourceInfo` | No | SSR remote entry (se any) | +| `types` | `MetaDataTypes` | No | Tipos bundle info (se any) | +| `type` | `string` | Yes | APP, NPM | +| `pluginVersion` | `string` | No | MF Plugin versão | + +### ResourceInfo + +| Field | Tipo | Obrigatório | Description | +| ------ | ----------------- | -------- | ------------------------------------------ | +| `path` | `string` | Yes | Relative caminho em build output | +| `name` | `string` | Yes | Arquivo name | +| `type` | `RemoteEntryType` | Yes | Remote entry format (`var/umd/system/...`) | + +### StatsBuildInfo + +| Field | Tipo | Obrigatório | Description | +| ---------------- | ---------- | -------- | ---------------------------- | +| `buildVersion` | `string` | Yes | Build versão | +| `buildName` | `string` | Yes | Build name | +| `target` | `string[]` | No | Build targets | +| `plugins` | `string[]` | No | Tree-shaking plugins | +| `excludePlugins` | `string[]` | No | Tree-shaking exclude plugins | + +### MetaDataTypes + +| Field | Tipo | Obrigatório | Description | +| ------ | -------- | -------- | --------------------------------------------------------- | +| `path` | `string` | Yes | Output caminho | +| `name` | `string` | Yes | Arquivo name (obrigatório for legacy tipos, vai ser deprecated) | +| `api` | `string` | Yes | API entry | +| `zip` | `string` | Yes | Zip caminho | + +## assets (Both Arquivos) + +`StatsAssets` describes sync/async assets para uma shared ou módulo exposto. Both arquivos use it. + +### StatsAssets + +| Field | Tipo | Obrigatório | Description | +| ----- | ----------------- | -------- | ----------------- | +| `js` | `StatsAssetsInfo` | Yes | JavaScript assets | +| `css` | `StatsAssetsInfo` | Yes | CSS assets | + +### StatsAssetsInfo + +| Field | Tipo | Obrigatório | Description | +| ------- | ---------- | -------- | -------------- | +| `sync` | `string[]` | Yes | Initial assets | +| `async` | `string[]` | Yes | Async assets | diff --git a/apps/website-new/docs/pt-BR/_components/create-shared-tree-shaking-deploy-server.mdx b/apps/website-new/docs/pt-BR/_components/create-shared-tree-shaking-deploy-server.mdx new file mode 100644 index 00000000000..54b158e6914 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/create-shared-tree-shaking-deploy-server.mdx @@ -0,0 +1,44 @@ +## Deploy Servidor (reference implementation) + +Se você plan para build your own Deploy Servidor, o seguintes high-level flow pode ser usado para implement `server-calc`. + +### 1. Aggregate `usedExports` during implantação + +In your CI/CD implantação pipeline, your service deve: + +- collect build metadata for all aplicações about para ser released (typically `mf-stats.json` ou similar arquivos); +- para o mesmo dependência compartilhada (e.g. `antd@6.1.0`), aggregate o `usedExports` declared by each aplicação. + +### 2. Compute o global minimum union + +Merge e deduplicate all collected `usedExports` lists para get o minimal global definir (o union) obrigatório pelo system. + +### 3. Run uma secondary build para produce o optimized shared bundle + +Invoke your ferramenta de build (e.g. Rspack CLI) as um isolated build e pass: + +- o target dependência compartilhada name e versão (e.g. `antd@6.1.0`); +- o global `usedExports` union do previous step. + O output é uma standalone shared bundle containing apenas o obrigatório módulos. + +### 4. Update e publish o Snapshot + +Upload o optimized bundle para your static asset host (CDN). Then update o Module Federation Snapshot arquivo (typically o remote versão de `mf-manifest.json`) com fields such as: + +- `secondarySharedTreeShakingEntry`: URL do optimized bundle, +- `secondarySharedTreeShakingName`: unique bundle name, +- `treeShakingStatus`: mark as disponível. + +Finally, distribute o updated Snapshot para all consumers. + +### 5. Runtime on-demand carregamento + +Quando uma user visits a aplicação, o MF Runtime reads o Snapshot. Se `treeShakingStatus` é disponível e o environment meets o carregamento conditions, it carrega o optimized bundle via `secondarySharedTreeShakingEntry` instead do full bundle. + +:::tip Versioning, caching, and compatibility + +- **Strict versioning** é o foundation. Ensure secondary builds e carregamento em runtime são based no exact mesmo versão (e.g. `antd@6.1.0`) para avoid mismatches. +- Use uma **reasonable caching estratégia** for secondary build artifacts. Since content changes com o global `usedExports`, prefer content-hash-based filenames for long-term caching. +- Este flow é **forward compatible**: quando não habilitado ou conditions aren't met, consumers fall back para o full bundle sem impacting existente functionality. + +::: diff --git a/apps/website-new/docs/pt-BR/_components/data-fetch/consumer.mdx b/apps/website-new/docs/pt-BR/_components/data-fetch/consumer.mdx new file mode 100644 index 00000000000..22438aa4b40 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/data-fetch/consumer.mdx @@ -0,0 +1,34 @@ +::: info Note +Atualmente, apenas [Modern.js](/integrations/framework/modernjs/index.html) suporta dados fetching em SSR environments. +::: + +No consumer, precisamos use o [createLazyComponent](/guide/bridge/react/load-component.html#what-is-createlazycomponent) API para carregar o remote componente e buscar its dados. + +```tsx +import { getInstance } from '@module-federation/enhanced/runtime'; +import { ERROR_TYPE } from '@module-federation/bridge-react/data-fetch'; +import { lazyLoadComponentPlugin } from '@module-federation/bridge-react/data-fetch'; + +const instance = getInstance(); +instance.registerPlugins([lazyLoadComponentPlugin()]); + +const List = instance.createLazyComponent({ + loader: () => import('remote/List'), + loading: 'loading...', + export: 'default', + fallback: ({ error, errorType, dataFetchMapKey }) => { + console.error(error); + if (errorType === ERROR_TYPE.LOAD_REMOTE) { + return
load remote failed
; + } + if (errorType === ERROR_TYPE.DATA_FETCH) { + return
data fetch failed: {dataFetchMapKey}
; + } + return
error type is unknown
; + }, +}); + +export default function Index() { + return ; +} +``` diff --git a/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-demo.mdx b/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-demo.mdx new file mode 100644 index 00000000000..592c88ab6e0 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-demo.mdx @@ -0,0 +1,34 @@ +### Scenario 1: Prefetching Dados Only + +Quando uma user hovers over uma link esse vai navigate para o shop page, nós pode pré-busca o dados needed for esse page. + +```ts +import { getInstance } from '@module-federation/enhanced/runtime'; + +const instance = getInstance(); + +const handleMouseEnter = () => { + instance.prefetch({ + id: 'shop/Button', + dataFetchParams: { productId: '12345' }, + }); +}; +``` + +### Scenario 2: Prefetching Dados e Preloading Componente Resources + +For further optimization, nós pode download o componente's JS e CSS arquivos at o mesmo time as prefetching o dados. + +```ts +import { getInstance } from '@module-federation/enhanced/runtime'; + +const instance = getInstance(); + +const handleMouseEnter = () => { + instance.prefetch({ + id: 'shop/Button', + dataFetchParams: { productId: '12345' }, + preloadComponentResource: true, + }); +}; +``` diff --git a/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-tip.mdx b/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-tip.mdx new file mode 100644 index 00000000000..38fa7ca4652 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/data-fetch/prefetch-tip.mdx @@ -0,0 +1,5 @@ +:::note + +Esta API requires registering o [lazyLoadComponentPlugin plugin](/guide/bridge/react/load-component.html#step-1-register-lazyloadcomponentplugin) antes ele pode ser usado. + +::: diff --git a/apps/website-new/docs/pt-BR/_components/data-fetch/provider-tip.mdx b/apps/website-new/docs/pt-BR/_components/data-fetch/provider-tip.mdx new file mode 100644 index 00000000000..38d15f34458 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/data-fetch/provider-tip.mdx @@ -0,0 +1,3 @@ +::: tip +Producers pode use [Rslib](/integrations/build-tool/rslib.html#ssr) e [Modern.js](/integrations/framework/modernjs/index.html). +::: diff --git a/apps/website-new/docs/pt-BR/_components/runtime/index.mdx b/apps/website-new/docs/pt-BR/_components/runtime/index.mdx new file mode 100644 index 00000000000..c1d99c36e78 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/runtime/index.mdx @@ -0,0 +1,31 @@ +Se o plugin de build é usado, um MF instance vai ser automatically criado e stored em memory quando o projeto começa. Você pode diretamente call métodos do MF instance via o. + +```ts +import { loadRemote } from '@module-federation/enhanced/runtime'; + +loadRemote('remote1'); +``` + +Se o plugin de build é não usado, você precisa manually crie um MF instance antes chamar o corresponding API. + +```ts +import { createInstance } from '@module-federation/enhanced/runtime'; + +const mf = createInstance({ + name: 'host', + remotes: [ + { + name: 'remote1', + entry: 'http://localhost:2001/vmok-manifest.json', + }, + ], +}); + +mf.loadRemote('remote1'); +``` + +:::tip ModuleFederation instance + +Um objeto criado pelo `ModuleFederation` class esse contains all runtime functionality. Você pode enter `__FEDERATION__.__INSTANCES__` no console para view o full instance information. + +::: diff --git a/apps/website-new/docs/pt-BR/_components/secondary-build.mdx b/apps/website-new/docs/pt-BR/_components/secondary-build.mdx new file mode 100644 index 00000000000..7eccd0420cf --- /dev/null +++ b/apps/website-new/docs/pt-BR/_components/secondary-build.mdx @@ -0,0 +1,70 @@ +## Producing uma secondary tree-shaken shared artifact + +:::warning Note +Se your goal é “tree-shake uma dependência compartilhada para uma single aplicação”, [usedExports](/configure/shared.html#usedexports) é geralmente enough. + +Este section é about generating uma standalone secondary artifact esse pode ser carregado em runtime on demand, e pode ser distributed ou reused do implantação side. +::: + +Este process builds apenas dependências compartilhadas; remotes vai não take effect. O original projeto entry é automatically ignored during o build, e apenas módulos shared são bundled. + +### Non-Modern.js projetos + +Use `TreeShakingSharedPlugin` em your build configuração, definir `secondary: true`, e reuse your existente `mfConfig`. + +import { Tab, Tabs } from '@theme'; + + + + ```ts + import { TreeShakingSharedPlugin } from '@module-federation/enhanced'; + // import { TreeShakingSharedPlugin } from '@module-federation/enhanced/rspack'; + // ... + plugins: [ + new TreeShakingSharedPlugin({ + secondary: true, + mfConfig, + }), + ]; + ``` + + + ```ts + import { TreeShakingSharedPlugin } from '@module-federation/rsbuild-plugin'; + // ... + plugins: [ + new TreeShakingSharedPlugin({ + secondary: true, + mfConfig, + }), + ]; + ``` + + + ```ts + import { sharing } from '@rspack/core'; + const { TreeShakingSharedPlugin } = sharing; + // ... + plugins: [ + new TreeShakingSharedPlugin({ + secondary: true, + mfConfig, + }), + ]; + ``` + + + +### Modern.js projetos + +Ao usar `@module-federation/modern-js-v3`, habilite `secondarySharedTreeShaking: true` no plugin opções para gerar o secondary artifact. + +```ts title="modern.config.ts" +import mfPlugin from '@module-federation/modern-js-v3'; +// ... +plugins: [ + mfPlugin({ + secondarySharedTreeShaking: true, + }), +]; +``` diff --git a/apps/website-new/docs/pt-BR/_nav.json b/apps/website-new/docs/pt-BR/_nav.json new file mode 100644 index 00000000000..0053c44e388 --- /dev/null +++ b/apps/website-new/docs/pt-BR/_nav.json @@ -0,0 +1,113 @@ +[ + { + "text": "IA", + "link": "/ai/", + "activeMatch": "/ai/" + }, + { + "text": "Guia", + "link": "/guide/start/", + "activeMatch": "/guide/" + }, + { + "text": "Integrações", + "link": "/integrations/", + "activeMatch": "/integrations/", + "items": [ + { + "text": "Visão geral", + "link": "/integrations/" + }, + { + "text": "Rsbuild", + "link": "/integrations/build-tool/rsbuild" + }, + { + "text": "Rslib", + "link": "/integrations/build-tool/rslib" + }, + { + "text": "Vite", + "link": "/integrations/build-tool/vite" + }, + { + "text": "Rspack", + "link": "/integrations/bundler/rspack" + }, + { + "text": "Webpack", + "link": "/integrations/bundler/webpack" + }, + { + "text": "Metro", + "link": "/integrations/bundler/metro" + }, + { + "text": "Rspress", + "link": "/integrations/documentation/rspress" + }, + { + "text": "Modern.js", + "link": "/integrations/framework/modernjs" + }, + { + "text": "Next.js", + "link": "/integrations/framework/nextjs" + }, + { + "text": "Angular", + "link": "/integrations/framework/angular" + }, + { + "text": "Monorepos", + "link": "/integrations/framework/monorepos" + }, + { + "text": "Prática", + "link": "/integrations/practice" + } + ] + }, + { + "text": "Configuração", + "link": "/configure/", + "activeMatch": "/configure/" + }, + { + "text": "Plugins", + "link": "/plugin/dev/index", + "activeMatch": "/plugin/" + }, + { + "text": "Showcase", + "link": "/showcase/index", + "activeMatch": "/showcase/" + }, + { + "text": "Blog", + "link": "/blog/index", + "activeMatch": "/blog/" + }, + { + "text": "Ecossistema", + "activeMatch": "/ecosystem/", + "items": [ + { + "text": "Module Federation Examples", + "link": "https://github.com/module-federation/module-federation-examples" + }, + { + "text": "Practical Module Federation", + "link": "https://module-federation.myshopify.com/products/practical-module-federation" + }, + { + "text": "Zephyr Cloud", + "link": "https://zephyr-cloud.io/" + }, + { + "text": "Nx", + "link": "https://nx.dev/" + } + ] + } +] diff --git a/apps/website-new/docs/pt-BR/ai/index.mdx b/apps/website-new/docs/pt-BR/ai/index.mdx new file mode 100644 index 00000000000..dd5e8a40433 --- /dev/null +++ b/apps/website-new/docs/pt-BR/ai/index.mdx @@ -0,0 +1,116 @@ +--- +pageType: doc-wide +sidebar: false +--- + +# Início rápido com AI + +:::tip Prefere ler a documentação por conta própria? +Se quiser percorrer os conceitos, a configuração e as integrações do Module Federation em ordem, acesse o [guia de introdução](/guide/start/index.html). +::: + +## Uma maneira melhor de começar + +Se você já usa uma ferramenta de codificação com AI, o melhor ponto de partida não é ler toda a documentação manualmente. + +A abordagem mais rápida é: **entregue primeiro a documentação mais recente do Module Federation ao seu agente; depois, deixe-o responder perguntas, depurar problemas, atualizar configurações e escrever código.** + +Muitos modelos ainda têm conhecimento incompleto ou desatualizado sobre o Module Federation 2.0. O objetivo desta página não é fazer você estudar primeiro, mas ajudar seu agente a consultar o material correto antes de agir. + +## Configuração recomendada + +Se você usa Claude Code, Cursor, Windsurf ou outro editor com suporte a Skills, instale: + +```bash +npx skills add module-federation/agent-skills --skill mf -y +``` + +Depois peça ao agente para ler a documentação antes de responder: + +```text +/mf docs What's the difference between singleton and requiredVersion in shared? +``` + +A ideia é simples: + +- você não precisa procurar pela documentação primeiro +- seu agente lê a documentação mais recente antes de responder +- o resultado tem muito mais chance de ser correto + +## Se quiser que o agente faça mais + +A skill `mf` faz mais do que responder perguntas. Ela também pode ajudar seu agente a: + +- adicionar Module Federation a um projeto existente +- inspecionar problemas de configuração +- analisar problemas de tipos +- verificar conflitos de dependências compartilhadas +- inspecionar informações de módulos remotos +- ler relatórios de observabilidade e depurar falhas de carregamento do MF + +[Ver documentação das Agent Skills](/ai/skill.html) + +## Observar e depurar carregamento do MF + +Se você quiser que um agente de codificação com AI depure carregamento do Module Federation com dados concretos de runtime, habilite o [Observability Plugin](/plugin/plugins/observability-plugin.html) +primeiro. + +Depois de uma falha de carregamento, o console do navegador imprime uma `traceId` e, +em desenvolvimento, um comando `read:`. Passe essa dica do console para seu agente: + +```text +/mf observability +I saw this Module Federation console error: + +[Module Federation] Observability report generated +traceId: mf-... +read: window.__FEDERATION__.__OBSERVABILITY__["runtime_host"].getReport("mf-...") + +Please read the report and fix the issue. +``` + +Para Node ou SSR, peça ao agente para ler `.mf/observability/latest.json`. Em +produção, envie relatórios com o callback `onReport` e forneça ao agente o +relatório enviado ou o trace ID. + +## Você ainda pode usar isso sem instalar nada + +Se você quiser primeiro uma versão mais leve, envie isto diretamente ao seu agente: + +```text +Before answering, please read https://module-federation.io/llms.txt to learn about the latest Module Federation 2.0 documentation, then answer my question. +``` + +Essa é a forma mais simples de impedir que o modelo tente adivinhar quando a skill ainda não foi instalada. + +## Documentação que você pode passar ao seu agente + +### llms.txt + +[module-federation.io](https://module-federation.io) oferece suporte ao padrão [llms.txt](https://llmstxt.org), que é um bom ponto de entrada para sistemas de AI: + +```text +https://module-federation.io/llms.txt +``` + +### Documentação em Markdown + +Todas as páginas do site de documentação também estão disponíveis em Markdown. Troque `.html` no fim de uma URL de documentação por `.md`: + +```text +# HTML version +https://module-federation.io/guide/basic/runtime.html + +# Markdown version +https://module-federation.io/guide/basic/runtime.md +``` + +## Próximos passos + +Se quiser começar usando esse fluxo de trabalho agora: + +1. Instale `mf` +2. Faça a pergunta que você quer responder +3. Habilite o [Observability Plugin](/plugin/plugins/observability-plugin.html) quando + precisar de observabilidade do carregamento do MF +4. Abra a [documentação das Skills](/ai/skill.html) para ver quais subcomandos ela oferece diff --git a/apps/website-new/docs/pt-BR/ai/skill.mdx b/apps/website-new/docs/pt-BR/ai/skill.mdx new file mode 100644 index 00000000000..64c39e1e4d2 --- /dev/null +++ b/apps/website-new/docs/pt-BR/ai/skill.mdx @@ -0,0 +1,135 @@ +--- +pageType: doc-wide +sidebar: false +--- + +# Skills + +Module Federation agora expõe uma **skill `mf`** unificada. + +Você não precisa escolher uma lista longa de skills separadas nem ler a documentação primeiro para depois repassá-la ao agente. A abordagem mais simples é instalar esta única skill e deixar o agente decidir se deve ler documentação, inspecionar configuração ou solucionar um problema. + +Se ainda não leu, comece pelo [início rápido com AI](/ai/index.html). + +## Instalação + +```bash +npx skills add module-federation/agent-skills --skill mf -y +``` + +Depois disso, a entrada principal é: + +```text +/mf +``` + +Se você não puder usar a CLI, também pode copiar manualmente o diretório do GitHub: + +```text +https://github.com/module-federation/agent-skills/tree/main/skills/mf +``` + +## Como usar + +`mf` tem um único ponto de entrada, mas contém várias capacidades. Você pode informar um subcomando explícito ou simplesmente pedir em linguagem natural. + +Com subcomandos explícitos: + +```text +/mf docs How do I use Module Federation in Modern.js? +/mf integrate +/mf type-check +/mf runtime-error RUNTIME-008 +/mf observability +``` + +Com linguagem natural: + +```text +/mf What's the difference between singleton and requiredVersion in shared? +/mf Help me figure out why this project is not pulling remote types +/mf Add Module Federation to the current project +/mf I saw a Module Federation console error with traceId mf-... +``` + +## O que `mf` oferece + +| Subcomando | Use para | +| --- | --- | +| `docs` | Ler a documentação mais recente antes de responder perguntas sobre configuração, APIs e conceitos | +| `context` | Inspecionar a configuração de MF do projeto atual | +| `module-info` | Inspecionar URLs de módulos remotos, módulos expostos e metadados relacionados | +| `integrate` | Adicionar Module Federation a um projeto existente | +| `type-check` | Solucionar problemas relacionados a tipos | +| `shared-deps` | Solucionar conflitos de dependências compartilhadas e bundling duplicado | +| `perf` | Solucionar lentidão no desenvolvimento local e no HMR | +| `config-check` | Solucionar erros de configuração, arquivos ausentes e incompatibilidades de plugin | +| `bridge-check` | Solucionar problemas de integração com Bridge | +| `runtime-error` | Solucionar códigos explícitos de erro em runtime, especialmente `RUNTIME-001` e `RUNTIME-008` | +| `observability` | Ler relatórios de observabilidade, rastrear fases de carregamento e depurar falhas de carregamento em runtime/build | + +## Fluxos de trabalho mais comuns + +### 1. Leia a documentação antes de responder + +Esse é o caso de uso mais comum e o melhor lugar para começar: + +```text +/mf docs What's the difference between singleton and requiredVersion in shared? +``` + +Isso faz o agente ler a documentação mais recente primeiro, em vez de tentar adivinhar com base em memória desatualizada. + +### 2. Deixe o agente integrar por você + +Se quiser adicionar Module Federation a um projeto existente: + +```text +/mf integrate +``` + +O agente vai inspecionar seu projeto atual e decidir o que fazer em seguida. + +### 3. Deixe o agente depurar diretamente + +Se você já tem um problema concreto: + +```text +/mf type-check +/mf shared-deps +/mf config-check +/mf runtime-error RUNTIME-008 +/mf observability +``` + +Nesse ponto, o objetivo não é você investigar manualmente primeiro. O objetivo é deixar o agente começar o diagnóstico imediatamente. + +### 4. Deixe o agente ler a observabilidade do MF + +Para observabilidade completa do carregamento, instale o [Observability Plugin](/plugin/plugins/observability-plugin.html) +na sua aplicação. Quando um erro no console do navegador imprimir uma `traceId` e um +comando `read:`, passe isso para a skill: + +```text +/mf observability +I saw this Module Federation console error: + +[Module Federation] Observability report generated +traceId: mf-... +read: window.__FEDERATION__.__OBSERVABILITY__["runtime_host"].getReport("mf-...") + +Please read the report and fix the issue. +``` + +Para Node, SSR ou uploads de produção: + +```text +/mf observability +Read .mf/observability/latest.json and explain the likely owner and fix. +``` + +## A única coisa que você realmente precisa lembrar + +Você não precisa ler a documentação primeiro e depois dizer ao agente o que fazer. + +Instale `mf`; depois deixe o agente ler, inspecionar, decidir e agir. diff --git a/apps/website-new/docs/pt-BR/blog/_meta.json b/apps/website-new/docs/pt-BR/blog/_meta.json new file mode 100644 index 00000000000..c69c6a5aca3 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/_meta.json @@ -0,0 +1,16 @@ +[ + "index", + "announcement", + "hoisted-runtime", + "error-load-remote", + { + "type": "file", + "name": "node", + "label": "Module Federation no Node.js, de forma simples" + }, + { + "type": "file", + "name": "v2-stable-version", + "label": "Lançamento estável do MF 2.0" + } +] diff --git a/apps/website-new/docs/pt-BR/blog/announcement.mdx b/apps/website-new/docs/pt-BR/blog/announcement.mdx new file mode 100644 index 00000000000..25fc25f81a5 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/announcement.mdx @@ -0,0 +1,116 @@ +# Announcement de Release + +> April 26, 2024 + +Today, nós são excited para announce o official release de Module Federation 2.0! +Este novo versão é uma collaborative effort entre o [ByteDance Web Infra](https://github.com/web-infra-dev) team, o author de Module Federation, [Zack Jackson](https://github.com/ScriptedAlchemy) +e several de our community members. Special thanks para [@ilteoood](https://github.com/ilteoood), [@patricklafrance](https://github.com/patricklafrance) e [@crutch12](https://github.com/crutch12). +Module Federation 2.0 addresses many issues do previous versão, building upon ByteDance's internal practices e o existente community ecosystem de Module Federation. + + +import AnnouncementVideo from '@components/AnnouncementVideo.tsx'; + + + +## Why Use Module Federation 2.0? + +Introduced by Webpack 5, Module Federation has been uma significant feature for over three years. +As um módulo compartilhamento solution, it has gained widespread adoption, especialmente em large web projetos, enhancing o efficiency e simplicity de developing large aplicações e facilitating team collaboration. +However, com its broader use, novo challenges have emerged. + +Versão 2.0 addresses these challenges com several enhancements: + +- **Best Practices**: Uma novo independent documentation site [here](https://module-federation.io/) includes best practices e configurações esse enhance its uso. +- **Decoupling Runtime de Build Tools**: Este versão decouples o Runtime de ferramenta de build, standardizing implementation across various platforms e increasing o flexibility de módulo carregamento. +- **Tipo Safety**: O updated plugin de build now automatically generates e carrega tipos for TypeScript projetos, com desenvolvimento mode synchronizing tipos para garantir safety. +- **Depuraçãoging Tools**: Enhanced debugging é facilitated por uma nova Chome DevTools, making o process mais convenient e efficient. +- **Implantação Platforms**: O addition do `mf-manifest.json` arquivo protocol simplifies integração com implantação platforms, allowing for better management de versão recursos e versões. + +## Introduction para Features de Module Federation 2.0 + +### New Documentation Site + +O novo documentation fornece uma detailed introduction para o applicable scenarios e capabilities do framework. Ele cobre o entire process de starting uma projeto com Rspack para utilizing its features. Additionally, ele oferece um em-depth discussion e explanation do configuração do seu plugin. + +![](@public/blog/announcement/module-federation-doc.png) + +### Enhanced Módulo Carregamento Flexibility + +O updated versão brings significant changes. O runtime capabilities esse were originally embedded em Webpack have been extracted para form uma standalone SDK. Essa mudança allows for dynamic registration e carregamento de remote e módulos shared sem relying on any ferramenta de build. Moreover, o use de módulo preloading e runtime plugins has been enhanced, providing mais powerful control over o módulo processo de carregamento. + +```typescript +import { init, loadRemote } from '@module-federation/enhanced/runtime'; + +init({ + name: '@demo/app-main', + remotes: [ + { + name: "@demo/app1", + entry: "http://localhost:3005/mf-manifest.json", + alias: "app1" + }, + { + name: "@demo/app2", + entry: "http://localhost:3006/remoteEntry.js", + alias: "app2" + }, + ], +}); + +loadRemote("app2/util").then((md)=>{ + md.add(1,2,3); +}); +``` +### Decoupling Webpack e Supporting Cross-Tool Compartilhamento de Módulos + +O novo versão do Module Federation plugin adopts uma completamente novo Runtime architecture. Essa mudança means esse o ferramenta de build é no longer tightly coupled com o Runtime. Developers pode now freely introduce artifacts produced by diferente ferramenta de build em their projetos e flexibly assemble them for operation. + +Atualmente, multiple ferramenta de build são compatible com it, including Webpack e Rspack. Other ferramenta de build pode também implement Module Federation baseado em este standard, que vai maintain consistency e standardization no runtime. + +### Dica de tipos + +O novo versão introduces uma groundbreaking feature - dynamic módulo tipo hints! Este feature effectively solves o problem de tipo loss quando converting local módulos para dynamic módulos remotos em TypeScript projetos. Now, usando este plugin, você pode não apenas automatically generate e use remote tipos but também achieve uma real-time tipo update experience semelhante a npm link quando all projetos são running locally. + +![](https://module-federation-assest.netlify.app/document/announcement/blog/announcement/demo-type-hint.gif) + +### Chrome DevTools + +O Devtool é uma debugging tool developed specifically for este framework. Ele pode clearly display o dependências entre módulos, as well as o configuração de Exponha e shared. Additionally, o tool suporta proxying módulos de online pages para o local ambiente de desenvolvimento e maintains hot update functionality para forneça uma smooth experiência de desenvolvimento. + +![](https://module-federation-assest.netlify.app/document/announcement/blog/announcement/chrome-devtool-display.gif) + +### Manifest Protocol + +O plugin de build for Module Federation generates uma Manifest arquivo. +Este arquivo contains basic information about o system, such as remoteEntry, shared, exposes, remotes, chunks, e tipo. +Este information é uma cornerstone for analyzing dependências entre projetos e helps us build e optimize o platform. +In este way, nós pode perform fine-grained versão e gray release management de módulos on diferente implantação platforms. +In addition, o plugin de build e runtime pode diretamente use o Manifest arquivo protocol para implement mais advanced features. +Por exemplo, o dynamic tipo hinting feature was developed no mais recente versão based no Manifest arquivo protocol. + +![](https://module-federation-assest.netlify.app/document/announcement/blog/announcement/manifest-file.gif) + +## Acknowledgments + +O desenvolvimento do novo versão de Module Federation could não have been possible sem o inspiration e suporte de many projetos within o community. +Here, nós express our deep respect e gratitude para these projetos: + +- [Webpack Module Federation](https://webpack.js.org/concepts/module-federation/). O novo versão de Module Federation was forked de it, redesigned e implemented on este basis. +- O [Module Federation Universe](https://github.com/module-federation/core) repository, onde o original implementation de Universe é o foundation do novo Module Federation. +- O [Rspack](https://github.com/web-infra-dev/rspack) projeto. O Rspack team implemented Module Federation baseado em Module Federation Runtime, ensuring full compatibility de 2.0 com o Rspack ecosystem. + +## Future Plans + +### Enhancing Developer Experience + +Although o novo versão introduces dynamic tipo hints e Chrome Developer Tools suporte, o current functionality do Chrome Developer Tools é still insufficient. +We plan para enhance o debugging tools for Module Federation, such as adding visualization features for shared reuse. + +### Providing High-Performance Solutions + +As uma solution for micro-frontend architecture, Module Federation também faces o unique "request waterfall problem" inherent para micro-frontend architectures. +To address este issue, Module Federation plans para forneça uma series de high-performance estratégias, including Servidor-Side Rendering (SSR) e Pré-busca de dados. + +### Collaborating com Community Partners + +O novo features de Module Federation 2.0 são currently apenas compatível by Webpack e Rspack, two ferramenta de build. Module Federation fornece uma rich definir de basic SDKs, facilitating other ferramenta de build para extend e encapsulate on este basis. Atualmente, Module Federation é mainly usado as um módulo compartilhamento solution. Our plan é para combine it com upper-layer frameworks para forneça uma series de micro-frontend architecture best practices baseado em Module Federation. Este vai help developers better meet o needs de large web aplicações em micro-frontend architecture desenvolvimento. diff --git a/apps/website-new/docs/pt-BR/blog/error-load-remote.mdx b/apps/website-new/docs/pt-BR/blog/error-load-remote.mdx new file mode 100644 index 00000000000..f167165cd66 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/error-load-remote.mdx @@ -0,0 +1,597 @@ +--- +title: Erro handling for renderização do módulo remoto em Module Federation. +--- + +# Erro handling for renderização do módulo remoto em Module Federation. +import BlogGifGrid from '@components/BlogGifGrid.tsx'; + + +## Background +Remote módulo processo de carregamento may fail due para network recurso carregamento falha ou business logic renderização falha. + +Though Module Federation Runtime fornece detailed informações detalhadas de log de erro e runtime hook para help users locate o cause de carregamento falha, precisamos add erro fallback mechanism para garantir o stability do entire site, preventing o entire site de crashing due para o falha de uma renderização do módulo remoto. + +## Solution + +To build uma robust carregamento de módulo remoto mechanism, nós pode handle possíveis problemas do seguintes three levels: + +> O seguinte solutions pode refer para o exemplos em [router-demo](https://github.com/module-federation/core/tree/main/apps/router-demo). + +### Network layer: Retry mechanism + +Use [`@module-federation/retry-plugin`](https://module-federation.io/zh/plugin/plugins/retry-plugin.html) plugin para tratar problemas relacionados à rede: +- Automatically retry falhou recurso requests +- Configurable retry times e interval + +- Suporte custom tratamento de erros estratégia + +### Carregamento layer: Erro handling hook + +Use Module Federation Runtime fornecido [`errorLoadRemote`](https://module-federation.io/zh/plugin/dev/index.html#errorloadremote) hook para mais granular tratamento de erros: +- Capture erros em diferente carregamento lifecycle +- Forneçum componente de fallback ou backup recurso +- Suporte custom tratamento de erros estratégia + +### Rendering layer: Erro boundary + +Use React's `ErrorBoundary` mechanism para tratar componente renderização exceptions: +- Graceful degradation, display friendly erro prompts +- Isolate erro impact, prevent o entire aplicação de crashing +- Suporte erro recovery e retry carregamento + +Esses three solutions são for diferente scenarios, pode ser usado separadamente, ou combined para forneça uma mais comprehensive tratamento de erros mechanism. Below nós vai introduce o specific implementation de each solution em detail. + + +### Add mecanismo de retry + +For weak network environment ou producer has não started o service, nós pode add mecanismo de retry para solicitar recursos multiple times, que vai increase o probability de recurso carregamento success. + +Module Federation official fornece retry plugin [@module-federation/retry-plugin](https://module-federation.io/zh/plugin/plugins/retry-plugin.html) para suporte mecanismo de retry for recursos, oferece retry para recursos fetch e script. + +#### Registro em runtime puro + +```ts + +import React from 'react'; +import { createInstance, loadRemote } from '@module-federation/enhanced/runtime'; +import { RetryPlugin } from '@module-federation/retry-plugin'; + +const mf = createInstance({ + name: 'host', + remotes: [ + { + name: "remote1", + alias: "remote1" + entry: "http://localhost:2001/mf-manifest.json", + } + ], + plugins: [ + RetryPlugin({ + retryTimes: 3, + retryDelay: 1000, + manifestDomains: ['https://domain1.example.com', 'https://domain2.example.com'], + domains: ['https://cdn1.example.com', 'https://cdn2.example.com'], + addQuery: ({ times, originalQuery }) => `${originalQuery}&retry=${times}`, + onRetry: ({ times, url }) => console.log('retry', times, url), + onSuccess: ({ url }) => console.log('success', url), + onError: ({ url }) => console.log('error', url), + }), + ] +}); + +// Module loading +const Remote1Button = React.lazy(() => mf.loadRemote('remote1/button')); + +export default () => { + return ( + Loading Remote1App...}> + + + ); +} + +// Method/function loading +mf.loadRemote<{add: (...args: Array)=> number }>("remote1/util").then((md)=>{ + md.add(1,2,3); +}); + +``` + +> Para saber mais sobre a configuração de parâmetros de [@module-federation/retry-plugin](https://module-federation.io/zh/plugin/plugins/retry-plugin.html#type) consulte [document](https://module-federation.io/zh/plugin/plugins/retry-plugin.html#type) + +#### Plugin registration + +```ts +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import path from 'path'; + +export default defineConfig({ + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'host', + runtimePlugins: [ + path.join(__dirname, './src/runtime-plugin/retry.ts'), + ], + }), + ], +}); +``` + +```tsx +// src/runtime-plugin/retry.ts +import { RetryPlugin } from '@module-federation/retry-plugin'; + +const retryPlugin = () => + RetryPlugin({ + retryTimes: 3, + retryDelay: 1000, + manifestDomains: ['https://domain1.example.com', 'https://domain2.example.com'], + domains: ['https://cdn1.example.com', 'https://cdn2.example.com'], + addQuery: ({ times, originalQuery }) => `${originalQuery}&retry=${times}`, + onRetry: ({ times, url }) => console.log('retry', times, url), + onSuccess: ({ url }) => console.log('success', url), + onError: ({ url }) => console.log('error', url), + }); +export default retryPlugin; +``` + +Effect as follows: + + + +### errorLoadRemote hook + +Para erros no processo de carregamento de módulos remotos, eles podem ser captured no [`errorLoadRemote`](https://module-federation.io/zh/plugin/dev/index.html#errorloadremote) hook. + +`errorLoadRemote` é o hook for tratamento de erros em Module Federation Runtime. Quando o carregamento de módulo remoto fails, este hook vai ser triggered. It é designed para trigger quando o módulo carregamento fails em diferente lifecycle stages, e allow users para customize tratamento de erros estratégias. + +`errorLoadRemote` suporta returning um componente de fallback for erro fallback, e também suporta returning specific recurso content para garantir subsequent processes render normally. + +We divide o uso de módulo registration e carregamento em "runtime puro + importação dinâmica" e "registro por plugin + importação síncrona". + + +#### Pure runtime + importação dinâmica + +Ao usar registro em runtime puro, o módulo remoto vai não solicitar recursos until depois registration. + +```tsx +import React from 'react'; +import { createInstance, loadRemote } from '@module-federation/enhanced/runtime'; +import { RetryPlugin } from '@module-federation/retry-plugin'; + +// Module registration +const mf = createInstance({ + name: 'host', + remotes: [ + { + name: "remote1", + entry: "http://localhost:2001/mf-manifest.json", + alias: "remote1" + } + ], + plugins: [ + RetryPlugin({ + retryTimes: 3, + retryDelay: 1000, + }), + ] +}); + +// Module loading +const Remote1Button = React.lazy(() => loadRemote('remote1/button')); + +export default () => { + return ( + Loading Remote1App...}> + + + ); +} + +// Method/function loading +loadRemote<{add: (...args: Array)=> number }>("remote1/util").then((md)=>{ + md.add(1,2,3); +}); + +``` + +Use o `errorLoadRemote` hook para capture carregamento de módulo remoto erros (including recurso carregamento erros), e suporte returning `errorBoundary` componente de fallback. + +```tsx +import React from 'react'; +import { createInstance, loadRemote } from '@module-federation/enhanced/runtime'; +import { RetryPlugin } from '@module-federation/retry-plugin'; + +const fallbackPlugin: () => ModuleFederationRuntimePlugin = function () { + return { + name: 'fallback-plugin', + errorLoadRemote(args) { + return { default: () =>
fallback component
}; + }, + }; +}; + +// Module registration +const mf = createInstance({ + name: 'host', + remotes: [ + { + name: "remote1", + alias: "remote1" + entry: "http://localhost:2001/mf-manifest.json", + } + ], + plugins: [ + RetryPlugin({ + retryTimes: 3, + retryDelay: 1000, + }), + fallbackPlugin() + ] +}); + +// Module loading +const Remote1Button = React.lazy(() => mf.loadRemote('remote1/button')); + +export default () => { + return ( + Loading Remote1App...}> + + + ); +} + +// Method/function loading +mf.loadRemote<{add: (...args: Array)=> number }>("remote1/util").then((md)=>{ + md.add(1,2,3); +}); + +``` + +Effect as follows: + + + + +#### Plugin registration + importação síncrona + +Plugin registration suporta usando importação síncrona para carregar módulos, e o momento da solicitação de recursos é earlier than runtime puro, so precisamos registrar o `errorLoadRemote` hook no plugin. + +```tsx +// rsbuild.config.ts +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import path from 'path'; + +export default defineConfig({ + plugins: [ + pluginReact(), + pluginModuleFederation({ + name: 'host', + remotes: { + remote1: 'remote1@http://localhost:2001/mf-manifest.json', + }, + runtimePlugins: [ + path.join(__dirname, './src/runtime-plugin/retry.ts'), + path.join(__dirname, './src/runtime-plugin/fallback.ts'), + ], + ... + }), + ], +}); + +``` + +:::info Tips +O seguinte exemplo shows como para tratar erros em diferente lifecycle stages. + +Se your aplicação scenario é simple, você pode refer para o **simplified versão** below, que fornece uma unified tratamento de erros solution. + +::: + +```tsx +// src/runtime-plugin/fallback.ts +import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime'; + +interface FallbackConfig { + // Backup service address + backupEntryUrl?: string; + // Custom error message + errorMessage?: string; +} + +const fallbackPlugin = (config: FallbackConfig = {}): ModuleFederationRuntimePlugin => { + const { + backupEntryUrl = 'http://localhost:2002/mf-manifest.json', + errorMessage = 'Module loading failed, please try again later' + } = config; + + return { + name: 'fallback-plugin', + async errorLoadRemote(args) { + // Handle component loading errors + if (args.lifecycle === 'onLoad') { + const React = await import('react'); + + // Create a fallback component with error message + const FallbackComponent = React.memo(() => { + return React.createElement( + 'div', + { + style: { + padding: '16px', + border: '1px solid #ffa39e', + borderRadius: '4px', + backgroundColor: '#fff1f0', + color: '#cf1322' + } + }, + errorMessage + ); + }); + + FallbackComponent.displayName = 'ErrorFallbackComponent'; + + return () => ({ + __esModule: true, + default: FallbackComponent + }); + } + + // Handle entry file loading errors + if (args.lifecycle === 'afterResolve') { + try { + // Try to load backup service + const response = await fetch(backupEntryUrl); + if (!response.ok) { + throw new Error(`Failed to fetch backup entry: ${response.statusText}`); + } + const backupManifest = await response.json(); + console.info('Successfully loaded backup manifest'); + return backupManifest; + } catch (error) { + console.error('Failed to load backup manifest:', error); + // If backup service also fails, return original error + return args; + } + } + + return args; + }, + }; +}; + +export default fallbackPlugin; +``` + +- `App.tsx` importação síncrona: `import Remote1App from 'remote1/app';` + +- About `fallback.ts`: + + - `errorLoadRemote` hook receives um `args` parameter, que contains o detailed information do erro. Through `args.lifecycle` nós pode determine o stage do erro occurrence, e take o corresponding processing estratégia: + + - **Handle componente carregamento erros** (`args.lifecycle === 'onLoad'`) + - Este tipo de erro occurs no módulo processo de carregamento other than o entry recurso `mf-manifest.json` + - We pode retornar um componente de fallback com styles: + + ```ts + if (args.lifecycle === 'onLoad') { + const React = await import('react'); + const FallbackComponent = React.memo(() => { + return React.createElement( + 'div', + { + style: { + padding: '16px', + border: '1px solid #ffa39e', + borderRadius: '4px', + backgroundColor: '#fff1f0', + color: '#cf1322' + } + }, + 'fallback component' + ); + }); + FallbackComponent.displayName = 'ErrorFallbackComponent'; + return () => ({ + __esModule: true, + default: FallbackComponent + }); + } + ``` + + - **Handle arquivo de entrada carregamento erros** (`args.lifecycle === 'afterResolve'`) + - Este tipo de erro occurs no entry recurso `mf-manifest.json` processo de carregamento + - We pode handle it no seguintes two formas: + + uma. Try para carregar backup service: + ```ts + if (args.lifecycle === 'afterResolve') { + try { + const response = await fetch('http://localhost:2002/mf-manifest.json'); + if (!response.ok) { + throw new Error(`Failed to fetch backup entry: ${response.statusText}`); + } + const backupManifest = await response.json(); + console.info('Successfully loaded backup manifest'); + return backupManifest; + } catch (error) { + console.error('Failed to load backup manifest:', error); + return args; + } + } + ``` + + b. Use local backup recurso: + ```ts + if (args.lifecycle === 'afterResolve') { + // Use predefined backup清单 + const backupManifest = { + id: 'fallback', + name: 'fallback', + metaData: { + name: 'fallback', + type: 'app', + buildInfo: { + buildVersion: 'local', + buildName: 'fallback', + }, + remoteEntry: { + name: 'remoteEntry.js', + path: '', + type: 'global', + }, + types: { + path: '', + name: '', + zip: '@mf-types.zip', + api: '@mf-types.d.ts', + }, + globalName: 'fallback', + pluginVersion: '1', + publicPath: 'https://example.com/', + }, + shared: [], + remotes: [], + exposes: [], + }; + return backupManifest; + } + ``` + + - **Simplified versão** + + Se você não precisa distinguish entre erro tipos, você pode também use uma generic tratamento de erros solution: + + ```ts + import type { ModuleFederationRuntimePlugin } from '@module-federation/runtime'; + + const fallbackPlugin = (errorMessage = 'Module loading failed, please try again later'): ModuleFederationRuntimePlugin => { + return { + name: 'fallback-plugin', + async errorLoadRemote() { + const React = await import('react'); + const FallbackComponent = React.memo(() => { + return React.createElement( + 'div', + { + style: { + padding: '16px', + border: '1px solid #ffa39e', + borderRadius: '4px', + backgroundColor: '#fff1f0', + color: '#cf1322' + } + }, + errorMessage + ); + }); + FallbackComponent.displayName = 'ErrorFallbackComponent'; + return () => ({ + __esModule: true, + default: FallbackComponent + }); + }, + }; + }; + export default fallbackPlugin; + ``` + +Effect as follows: + + + + +### Set ErrorBoundary for componente + +React's ErrorBoundary é o último line de defense for handling componente-level erros, no dynamic carregamento scenario de módulos remotos (such as carregamento lazy), ele pode help us capture e process o renderização erros de módulos remotos e forneça graceful degradation. + +Setting ErrorBoundary for componentes é suitable for importação dinâmica módulo remoto scenarios, such as carregamento lazy scenarios. + +Moreover, depois setting ErrorBoundary for componentes, você pode avoid relying no errorLoadRemote hook for erro fallback, que é uma feature de React itself para forneça erro fallback for your componentes. + + +- `App.tsx` importação dinâmica módulo remoto + +```tsx +// App.tsx +import React, { + useRef, + useEffect, + ForwardRefExoticComponent, + Suspense, +} from 'react'; + +const Remote1AppWithLoadRemote = React.lazy(() => loadRemote('remote1/app')); +const Remote1AppWithErrorBoundary = React.forwardRef((props, ref) => ( + Error loading Remote1App...}> + Loading Remote1App...}> + + + +)); + +export default function App() { + return ( + <> +
+

Remote1

+ +
+ + ); +} +``` + + +Effect as follows: + + diff --git a/apps/website-new/docs/pt-BR/blog/hoisted-runtime.mdx b/apps/website-new/docs/pt-BR/blog/hoisted-runtime.mdx new file mode 100644 index 00000000000..9d6f13c2559 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/hoisted-runtime.mdx @@ -0,0 +1,77 @@ +import {Tabs, Tab} from '@theme' + +# Async Startup em Module Federation + +> Sep 5, 2024 + +We're excited para announce uma nova experimental feature: `experiments.asyncStartup = true`. + +Este release introduces **asynchronous startup**, enabling automatic async initialization for Module Federation entrypoints. + +## 🚀 Key Features + +### Automatic Async Initialization + +Com async startup habilitado, **dynamic importa (`import()`) at o top de your app são no longer obrigatório**. All entrypoints vai now initialize asynchronously por padrão. Este means: +- No mais eager erros +- No need for "async boundaries" em userland code +- Automatic handling de async initialization + +:::note +Este apenas affects ponto de entrada initialization. Você pode still use dynamic importa normally throughout your aplicação, including for importing módulos remotos. Este feature doesn't change ou limit como dynamic importa work em your code. +::: + +:::tip +**Note:** Asynchronous entrypoints vai always exporte uma promise. Este é particularly relevant se você're manually requiring uma bundled entrypoint ou exposing something like uma UMD library para o global escopo. +::: + +#### Antes & Depois Comparison + +See como o novo async behavior simplifies entrypoints. Click no "Antes" e "Depois" tabs para see o difference. + + + + ```jsx + // entrypoint + import('./bootstrap.js') + + // bootstrap.js + import React from 'react'; + import ReactDOM from 'react-dom/client'; + import App from './App'; + + const root = ReactDOM.createRoot(document.getElementById('root')!); + root.render( + + + , + ); + ``` + + + ```jsx + // entrypoint + import React from 'react'; + import ReactDOM from 'react-dom/client'; + import App from './App'; + + const root = ReactDOM.createRoot(document.getElementById('root')!); + root.render( + + + , + ); + ``` + + + +### Important Notes + +Ao usar async startup: +- All entrypoints initialize asynchronously por padrão +- Exporta de entrypoints vai ser promises esse resolve para o actual exporta +- No manual async boundaries ou dynamic importa needed +- Eager consumption erros são automatically prevented por meio de async initialization + +Esse recurso simplifica Module Federation configuração by removing o need for manual async handling enquanto ensuring proper initialization de módulos federados. + diff --git a/apps/website-new/docs/pt-BR/blog/index.mdx b/apps/website-new/docs/pt-BR/blog/index.mdx new file mode 100644 index 00000000000..37f65225f96 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/index.mdx @@ -0,0 +1,31 @@ +--- +title: Visão geral +sidebar: false +--- +# Module Federation Blog + +Find o mais recente posts e release announcements about Module Federation here. + +## [Module Federation 2.0 Stable Release](/blog/v2-stable-version.html) + +> February 10, 2026 + +Module Federation 2.0 é officially stable, bringing dependência compartilhada tree shaking e uma Modern.js v3 plugin para make integração easier. + +## [Module Federation on Node.js: From Usable to Ergonomic](/blog/node.html) + +> January 23, 2026 + +Aprenda como use Module Federation em Node.js, including runtime-apenas consumption, Rspack/Webpack integração, e producer-side build configuração. + +## [Handling Remote Module Rendering Errors](/blog/error-load-remote.html) + +> September 9, 2025 + +Fallback estratégias for módulo remoto carregue/render falhas: network retries, o errorLoadRemote hook, e React ErrorBoundary. + +## [Release Announcement](/blog/announcement.html) + +> April 26, 2024 + +Announces o official release de Module Federation 2.0 e introduces core capabilities like runtime decoupling, tipo safety, devtools, e o Manifest protocol. diff --git a/apps/website-new/docs/pt-BR/blog/node.mdx b/apps/website-new/docs/pt-BR/blog/node.mdx new file mode 100644 index 00000000000..fcc33beb332 --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/node.mdx @@ -0,0 +1,76 @@ +# {props.name || 'Module Federation'} on Node.js, Made Easy + +import RuntimeConsumerDemo from '@docs/_snippets/node/runtime-consumer-demo'; +import HostRspackConfig from '@docs/_snippets/node/host-rspack-config'; +import HostUsage from '@docs/_snippets/node/host-usage'; +import RemoteRslibConfig from '@docs/_snippets/node/remote-rslib-config'; +import RemoteRspackConfig from '@docs/_snippets/node/remote-rspack-config'; + +{props.name || 'Module Federation'} suporta Node.js out do box. Whether você são consuming módulos em runtime apenas, ou integrating em uma Webpack/Rspack pipeline de build, ele pode ser adopted com uma relativamente small amount de configuração. Este documento walks por meio de formas comuns para usar {props.name || 'Module Federation'} em Node.js. + +## Visão geral + +Em uma Node.js servidor aplicação, você pode carregar módulos remotos via {props.name || 'Module Federation'}. Esses módulos podem ser local arquivos criado em CommonJS format, ou remote services accessed over HTTP. Isso permite uma flexible foundation for do lado do servidor microservices, dynamic feature delivery, e shared recursos. + +## Consumer + +### Runtime-Only + +Se você são apenas consuming módulos em Node.js e não quiser introduce bundlers like Webpack/Rspack, você pode use o runtime-apenas approach. O ideia principal é: **no plugin de build obrigatório**. Você só precisa do APIs fornecido by { props.runtime || '@module-federation/runtime' }. + +Steps: + +1. **Crie um MF instance** com `createInstance`. +2. **Register remotes** via o `remotes` array. +3. **Carregue módulos** via `loadRemote`. + +O seguinte exemplo shows como para carregar um módulo remoto exposto over HTTP: + +{props.runtimeConsumerDemo || } + +### Usando uma Bundler Plugin (Rspack/Webpack) + +Se sua aplicação Node.js é criado com Webpack ou Rspack, integrating {props.name || 'Module Federation'} é straightforward: adicione o plugin e o obrigatório runtime configuração. + +For o Host (consumer), o key é para adicionar `@module-federation/node/runtimePlugin` e definir `remoteType: 'script'` e `target: 'async-node'`, then apply o rest do configuração. + +Rspack exemplo (Webpack é em grande parte o mesmo): + +{props.hostRspackConfig || } + +Depois esse, você pode diretamente `import` módulos remotos em your code: + +{props.hostUsage || } + +## Provider + +No producer side, nós recommend usando Rslib. Você só precisa de para usar o { props.rsbuildPlugin || '@module-federation/rsbuild-plugin' } plugin e definir `target: 'async-node'` para gerar uma remote esse pode ser consumido em Node.js. + +Configuração principal de `apps/node-remote/rslib.config.ts`: + +{props.remoteRslibConfig || } + +Se você não são usando Rslib, você pode também build o remote com Rspack/Webpack (o configuração é em grande parte o mesmo). O pontos principais são: definir `target` para `async-node`, e output `remoteEntry.js` com `library.type = 'commonjs-module'`. + +Rspack exemplo: + +{props.remoteRspackConfig || } + +Webpack configuração é em grande parte o mesmo as o Rspack exemplo above. + +## FAQ + +### 1. What does `target: 'async-node'` do? + +`target: 'async-node'` é uma Webpack alvo de build esse produz uma saída adequada para Node.js com carregamento assíncrono. Este é important for Module Federation’s modelo de carregamento dinâmico e assíncrono—especialmente quando você need top-level `await` enquanto carregamento remotes. + +### 2. Why do I precisa definir `remoteType: 'script'`? + +Atualmente, o MF bundler runtime apenas suporta o `script` carregamento de remote tipo, so for Node.js consumption você precisa explicitamente definir `remoteType: 'script'`. + +## References + +- **Host (Consumer) exemplo configuração**: [`apps/node-host/webpack.config.js`](https://github.com/module-federation/core/blob/main/apps/node-host/webpack.configuração.js) +- **Host (Consumer) exemplo code**: [`apps/node-host/src/main.js`](https://github.com/module-federation/core/blob/main/apps/node-host/src/main.js) +- **Remote (Producer) Rslib exemplo configuração**: [`apps/node-remote/rslib.config.ts`](https://github.com/module-federation/core/blob/main/apps/node-remote/rslib.configuração.ts) +- **Remote (Producer) Webpack exemplo configuração**: [`apps/node-remote/webpack.config.js`](https://github.com/module-federation/core/blob/main/apps/node-remote/webpack.configuração.js) diff --git a/apps/website-new/docs/pt-BR/blog/v2-stable-version.mdx b/apps/website-new/docs/pt-BR/blog/v2-stable-version.mdx new file mode 100644 index 00000000000..c25936a423c --- /dev/null +++ b/apps/website-new/docs/pt-BR/blog/v2-stable-version.mdx @@ -0,0 +1,149 @@ +# MF 2.0 Stable Release: Balancing Developer Productivity e Extreme Performance + +One year ago, nós open-sourced Module Federation 2.0 ([MF 2.0](https://module-federation.io/en/blog/announcement.html)), e since then nós have received uma wealth de valuable feedback e suggestions do community. We believe esse uma mature micro-frontend solution deve não apenas improve collaborative desenvolvimento efficiency, but também forneça uma core engine esse enables extreme performance. Com este em mind, nós have spent o past year deeply refining MF 2.0 e expanding its capabilities. + +Today, nós são pleased para announce esse **MF 2.0 é now officially stable**. O stable release delivers powerful performance optimizations, covers uma broader range de implantação scenarios, e significantly improves o developer experience. + +## End-para-End Performance Optimization System +MF 2.0 systematically restructures o performance pipeline de micro-frontend aplicações across four stages: **build, asset carregamento, renderização, e dados fetching**. + +Esses capabilities não exist em isolation; they work together para form um end-para-end performance optimization system tailored for módulo federation scenarios. + +**All capabilities suporte incremental adoption**. Você pode habilite them gradually as needed sem performing uma big-bang rewrite de your current architecture, e sem compromising o stability de existente systems. + +### Tree Shaking for Shared Dependências +Traditional dependências compartilhadas avoid duplicate carregamento, but para garantir completeness, shared libraries são often **bundled e exposto as whole pacotes**. Even se você apenas use uma small portion, você still have para carregar o entire library, que causes bundle sizes para grow continuously. + +In **MF 2.0**, este problem é addressed: + +**Shared dependências now suporte tree shaking.** + +By simply enabling `treeShaking`, MF pode perform on-demand pruning de dependências compartilhadas sem sacrificing o dynamic nature de módulo federation. It retains apenas o módulos esse são actually likely para ser usado, significantly reducing o size de shared bundles enquanto remaining fully compatible com existente projetos. + +![](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/enable-shared-tree-shaking.png) + +MF 2.0 fornece two modes para fit diferente scenarios: + +- **runtime-infer**: Zero external dependências e ready para usar out do box. Em runtime, MF primeiro attempts para reuse já-carregado tree-shaken shared bundles; se their capabilities são insufficient, it automatically falls back para carregamento o full dependência para garantir functional completeness. Você pode improve reuse effectiveness com `usedExports`. + +- **servidor-calc**: Uma mode onde o servidor ou CI system analyzes dependência uso across multiple aplicações e produces uma globally optimal shared-pruning result, suitable for large systems. + +Uma **visual analysis dashboard** é também fornecido, making it easy para see como dependências compartilhadas são usado e o que bundle size savings they deliver. + +For uma large componente library like **Ant Design**, quando uma aplicação apenas usa o Badge, Button, e List componentes, o shared bundle size é about **1404.2 KB** sem shared-dependência tree shaking. Depois enabling tree shaking, o actual carregado size drops para **344.0 KB**, reducing unnecessary code by approximately **75.5%**. + + +![Configuration](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/definir-configuração.png) +![Analysis result](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/analyze-result.png) + +### Servidor-Side Rendering (SSR) +SSR generates full HTML no servidor e retorna it diretamente para o navegador, so pages pode render sem waiting for do lado do cliente hydration. Este dramatically improves **primeiro-screen performance** e **SEO**. For medium-para-large web aplicações, SSR has effectively become uma standard capability. + +However, em micro-frontend architectures, SSR has historically been difficult para implement. Early MF versões did não cover este capability, forcing developers para choose entre **architectural flexibility** e **performance benefits**. + +In **MF 2.0**, este trade-off é eliminated. + +Você pode use **MF SSR** diretamente within **{ props.framework || 'Modern.js' }**, giving micro-frontend aplicações high-performance SSR capabilities as well. + +{ props.ssr || '' } + +### Isomorphic Pré-busca de dadosing +MF 2.0 introduces uma nova **isomorphic dados fetching solution** esse suporta both **SSR e CSR** scenarios. It fornece built-em **`prefetch`** e **`cache`** APIs for unified dados prefetching e cache management, ensuring stable e predictable performance across diferente renderização modes. + +By leveraging preloading e caching, pages pode prepare critical dados antes renderização, preventing repeated requests e waterfall carregamento, que significantly improves both initial carregue e interactive responsiveness. + +{ props.dataSolution || '' } + + +{ props.serverPreload || '' } + + +### Rust-Powered Capabilities +In large projetos, **manifest generation** often becomes uma performance bottleneck during o build phase. MF 2.0 moves este core capability para uma **Rust implementation**, taking advantage de Rust’s high performance e memory safety para substantially reduce o time obrigatório para gerar manifests. + +At o mesmo time, **AsyncStartUp** has também been rewritten em Rust. Você no longer precisa configure asynchronous ponto de entradas para get equivalent capabilities, e related primeiro-screen performance risks são effectively eliminated, making a aplicação startup caminho simpler, mais stable, e mais efficient. + +{ props.deploy || '' } + +## More Powerful Depuraçãoging System +MF 2.0 builds uma comprehensive debugging system around **observability e debuggability**. It makes dependências compartilhadas, módulo relationships, e potential side effects **visible, traceable, e detectable em advance**, greatly reducing uncertainty quando developing e integrating dynamic aplicações. + +### Side Effect Scanner +Antes consuming um módulo remoto, teams often precisa assess whether it pollutes global variables, registers event listeners, ou affects style escopos—uncertainties esse significantly increase o cost de adopting micro-frontends. + +MF 2.0 fornece uma **Side Effect Scanner** esse statically analyzes build outputs e identifies o seguintes side effects: + +- Global variables +- Event listeners +- CSS selector impact escopo + +O accompanying **CLI tool** pode automatically perform scans e output results, allowing consumers para understand o risks antes integração e thereby significantly lower o cost de onboarding módulos federados. + +### Chrome Extension for Dependência Visualization +We have fully upgraded o existente Chrome extension com uma nova UI e stronger debugging capabilities, making o runtime estado de módulo federation **visible, queryable, e verifiable**. + +- **Smart sidebar sync** +O panel automatically follows o current page sem manual refresh ou reconnection, providing uma smoother debugging experience. + + +- **Shared dependência visualization** +O novo **Shared** panel clearly shows dependência compartilhada carregamento no current page, por exemplo: + - Whether React é successfully shared + - Which shared versão é actually em use + - Whether your compartilhamento estratégia é working as expected +![Shared dependências visualization](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/chrome-shared.png) + +- **Fast dependência graph navigation** +Você pode search for any módulo no dependência graph, e see its upstream e downstream relations em uma clear hierarchy, making complex dependências easy para reason about. + +![Dependency graph](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/chrome-dep.png) + +- **Dados trimming mode** +Quando there são many módulos, você pode habilite trimming mode para reduce o size de proxy dados e avoid injection falhas caused by localStorage limits. +*Trimmed dados apenas affects preloading analysis, não actual behavior, so it é safe para habilite.* + + +## Richer Ecosystem + +MF now suporta o major **bundlers, aplicação frameworks, e UI stacks**, e pode run reliably across diferente technical ecosystems, helping teams introduce módulo federation sem changing their existente technology choices. + +- **Bundler**: Webpack / Rspack / Rollup / Rolldown + +- **Build Tool**: Rsbuild / Vite / Metro + +- **Framework/Tool**: Modern.js / Next.js / Rspress / Rslib / Storybook + +- **UI Library**: React / Vue / React Native + +![MF 2.0 ecosystem](https://module-federation-assest.netlify.app/document/announcement/blog/v2-stable-version/ecosystem.png) + +On top de este, MF 2.0 extends módulo federation capabilities em mais critical desenvolvimento e delivery scenarios: + +### Node.js +Módulo federation pode now ser usado diretamente no **Node.js runtime**, so módulos remotos pode ser consumido não apenas pelo navegador but também by **SSR, BFF, e Node service layers**, enabling uma unified delivery model for módulos across frontend e backend. + +### Rspress Documentation Splitting +In **Rspress**, MF suporta splitting e carregamento módulos remotos by document ou rota, allowing large documentation sites para ser **decomposed e released independently via módulo federation**, que é ideal for multi-team documentation e knowledge platforms. + +### Rstest +Within o **Rstest** testing system, módulo federation pode carregar módulos remotos em uma real runtime manner, enabling micro-frontend e MF aplicações para perform **integração tests e end-para-end tests esse closely mirror production**, avoiding o gap entre tests e real runtime behavior. + +## Changes +### Versão Changes (Minor Changes) +We prioritize **stability e compatibility**, so este upgrade contains no breaking changes e apenas introduces uma few minor updates. O key changes são: + +### Minor Changes + +- O padrão valor de `library.type` é changed de `var` para `global`. +- `runtimePlugins` now suporte configuração parameters. + +## What's Next? +### React Servidor Componentes +React Servidor Componentes (RSC) represent uma revolutionary step forward no React ecosystem. Compared para MF x SSR, o combination de MF x RSC pode deliver even better performance (com much smaller bundles) e safer dados handling. We have já validated este approach em basic demos e vai forneça stronger suporte e integração em Modern.js. + +### AI-friendly Design +We são gradually enriching MF com **o contextual information e metadata obrigatório for AI para usar componentes e módulos**, including capability boundaries, uso constraints, runtime environments, e dependência relationships. We também plan para introduce **quantitative scoring e confidence mechanisms** so esse componente assets pode ser understood, evaluated, e selected by AI. + +{ props.aiFriendly || '' } + +{ props.next || '' } diff --git a/apps/website-new/docs/pt-BR/configure/_meta.json b/apps/website-new/docs/pt-BR/configure/_meta.json new file mode 100644 index 00000000000..d0b2028735b --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/_meta.json @@ -0,0 +1,107 @@ +[ + { + "type": "file", + "name": "index", + "label": "Visão geral" + }, + { + "type": "file", + "name": "name", + "label": "name" + }, + { + "type": "file", + "name": "filename", + "label": "filename" + }, + { + "type": "file", + "name": "library", + "label": "library" + }, + { + "type": "file", + "name": "remotes", + "label": "remotes" + }, + { + "type": "file", + "name": "remotetype", + "label": "remoteType" + }, + { + "type": "file", + "name": "shareScope", + "label": "shareScope" + }, + { + "type": "file", + "name": "exposes", + "label": "exposes" + }, + { + "type": "file", + "name": "shared", + "label": "shared" + }, + { + "type": "file", + "name": "runtimeplugins", + "label": "runtimePlugins" + }, + { + "type": "file", + "name": "getpublicpath", + "label": "getPublicPath" + }, + { + "type": "file", + "name": "implementation", + "label": "implementation" + }, + { + "type": "file", + "name": "dts", + "label": "dts" + }, + { + "type": "file", + "name": "dev", + "label": "dev" + }, + { + "type": "file", + "name": "manifest", + "label": "manifest" + }, + { + "type": "file", + "name": "shareStrategy", + "label": "shareStrategy" + }, + { + "type": "file", + "name": "experiments", + "label": "experiments" + }, + { + "type": "file", + "name": "injectTreeShakingUsedExports", + "label": "injectTreeShakingUsedExports" + }, + { + "type": "file", + "name": "treeShakingDir", + "label": "treeShakingDir" + }, + { + "type": "file", + "name": "treeShakingSharedExcludePlugins", + "label": "treeShakingSharedExcludePlugins" + }, + { + "type": "file", + "name": "treeShakingSharedPlugins", + "label": "treeShakingSharedPlugins" + } +] diff --git a/apps/website-new/docs/pt-BR/configure/dev.mdx b/apps/website-new/docs/pt-BR/configure/dev.mdx new file mode 100644 index 00000000000..e28f5187d15 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/dev.mdx @@ -0,0 +1,40 @@ +# dev + +- Tipo: `boolean | PluginDevOptions` +- Obrigatório: No +- Padrão valor: `true` +- Uso scenario: usado para control `Module Federation` dev behavior + +O `PluginDevOptions` tipos são as seguintes: + +```ts +interface PluginDevOptions { + disableLiveReload?: boolean; + disableHotTypesReload?: boolean; + disableDynamicRemoteTypeHints?: boolean; +} +``` + +## disableHotTypesReload + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `false` + +Whether para disable tipo hot reloading + +## disableLiveReload + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `false` + +Whether para disable `liveReload`, depois setting `true`, any updates do producer vai não trigger o consumer's **page** `liveReload` + +## disableDynamicRemoteTypeHints + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `false` + +Whether para disable tipo hot reloading diff --git a/apps/website-new/docs/pt-BR/configure/dts.mdx b/apps/website-new/docs/pt-BR/configure/dts.mdx new file mode 100644 index 00000000000..5cce1dee362 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/dts.mdx @@ -0,0 +1,394 @@ +# dts + +- Tipo: `boolean | PluginDtsOptions` +- Obrigatório: No +- Padrão valor: `true` +- Usage scenario: used to control {props.brandName || props.name || 'Module Federation'} generation/consumption type behavior + +Depois configuração, o producer vai automatically generate uma compressed tipo arquivo `@mf-types.zip` (padrão name) durante o build, e o consumer vai automatically pull o tipo arquivo de `remotes` e decompress it para `@mf-types` (padrão name). + +O `PluginDtsOptions` tipos são as seguintes: + +```ts +interface PluginDtsOptions { + generateTypes?: boolean | DtsRemoteOptions; + consumeTypes?: boolean | DtsHostOptions; + tsConfigPath?: string; + cwd?: string; +} +``` + +## generateTypes + +- Tipo: `boolean | DtsRemoteOptions` +- Obrigatório: No +- Padrão valor: `true` +- Uso scenario: usado para control `Module Federation` generation tipo behavior + +O `DtsRemoteOptions` tipos são as seguintes: + +```ts +interface DtsRemoteOptions { + tsConfigPath?: string; + typesFolder?: string; + outputDir?: string; + deleteTypesFolder?: boolean; + additionalFilesToCompile?: string[]; + compilerInstance?: 'tsc' | 'vue-tsc'; + compileInChildProcess?: boolean; + generateAPITypes?: boolean; + extractThirdParty?: boolean; + extractRemoteTypes?: boolean; + abortOnError?: boolean; + deleteTsConfig?: boolean; + afterGenerate?: ( + options: DtsGenerateTypesHookOptions, + ) => Promise | void; +} + +interface DtsGenerateTypesHookOptions { + zipTypesPath: string; + apiTypesPath: string; + zipName: string; + apiFileName: string; +} +``` + +Quando configuring `generateTypes` para `true`, o seguintes configuração vai ser generated por padrão: + +```json +{ + "generateAPITypes": true, + "abortOnError": false, + "extractThirdParty": false, + "extractRemoteTypes": false, + "compileInChildProcess": true, + "deleteTsConfig": true +} +``` + +### extractRemoteTypes + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `undefined` +- Uso scenario: Quando o content do producer `exposes` has its own `remotes` módulo esse re-exporta itself, then `extractRemoteTypes: true` pode ensure esse o consumer pode normally obtain o módulo tipo do producer `exposes` +- Exemplo: [Nested type re-export](/guide/basic/type-prompt.html#nested-type-re-export) + +Whether para extract o tipo de `remotes`. + +### extractThirdParty + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `undefined` +- Uso scenario: Quando o content do producer `exposes` contains um módulo containing `antd`, e o consumer does não have `antd` installed, then `extractThirdParty: true` pode ensure esse o consumer pode normally obtain o módulo do producer `exposes` tipo +- Exemplo: [Third-party package type extraction](/guide/basic/type-prompt.html#third-party-package-type-extraction) + +Whether para extract third-party pacote tipos. + +### generateAPITypes + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `undefined` +- Exemplo: [Federation Runtime API type prompt](/guide/basic/type-prompt.html#federation-runtime-api-type-prompt) + +Whether para gerar o `loadRemote` tipo em `Federation Runtime` + +### compileInChildProcess + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `undefined` + +Whether generate tipos em child process + +### abortOnError + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `false` + +Whether para lança um erro quando uma problem é encountered during tipo generation + +### afterGenerate + +- Type: `(options: DtsGenerateTypesHookOptions) => Promise | void` +- Obrigatório: No +- Padrão valor: `undefined` + +Runs depois federated tipos são generated e antes o generated arquivos são emitted. + +```ts title="module-federation.config.ts" +new ModuleFederationPlugin({ + dts: { + generateTypes: { + afterGenerate({ zipTypesPath, apiTypesPath }) { + console.log('zip types:', zipTypesPath); + console.log('api types:', apiTypesPath); + }, + }, + }, +}); +``` + +### tsConfigPath + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `path.join(process.cwd(),'./tsconfig.json')` +> priority: dts.generateTypes.tsConfigPath > dts.tsConfigPath +tsconfig configuração arquivo caminho + +### outputDir + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `undefined` + +Custom base output diretório for generated tipo assets. + +Quando este opção é não definir, Module Federation emits `@mf-types.zip` e +`@mf-types.d.ts` relative para o bundler output diretório. Se your remote entry +é emitted para uma nested subdirectory such as `production/remoteEntry.js`, definir +`dts.generateTypes.outputDir` para o mesmo nested output diretório so o tipo +artifacts são emitted alongside o arquivo de entrada. + +Este keeps o padrão inferred tipo URLs aligned com o remote entry caminho, so +consumers geralmente não need `remoteTypeUrls` just porque o remote entry é +served de uma subdirectory. + +```ts title="module-federation.config.ts" +new ModuleFederationPlugin({ + filename: 'production/remoteEntry.js', + dts: { + generateTypes: { + outputDir: `dist/react/${process.env.DEPLOY_ENVIRONMENT || 'production'}`, + }, + }, +}); +``` + +Com o configuração above, o generated arquivos são emitted para +`dist/react/production/@mf-types.zip` e +`dist/react/production/@mf-types.d.ts`. + +### typesFolder + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `'@mf-types'` + +O name do generated compression tipo arquivo. Por exemplo, se typesFolder é definir para `custom`, then o name do generated compression tipo arquivo é: `custom.zip` + +### deleteTypesFolder + +- Tipo: `boolean` +- Obrigatório: No + -Padrão: `true` + +Whether para delete o generated tipo pasta + +### compilerInstance + +- Tipo: `'tsc' | 'tsgo' | 'vue-tsc' | 'tspc' | string` +- Obrigatório: No +- Padrão valor: `'tsc'` + +Instance de compiled tipo + +### deleteTsConfig + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `true` + +Whether para delete o temporary tsconfig configuração arquivo. + +## consumeTypes + +- Tipo: `boolean | DtsHostOptions` +- Obrigatório: No +- Padrão valor: `true` +- Uso scenario: usado para control `Module Federation` consumption (carregamento) tipo behavior + +O `DtsHostOptions` tipos são as seguintes: + +```ts +interface DtsHostOptions { + typesFolder?: string; + abortOnError?: boolean; + remoteTypesFolder?: string; + deleteTypesFolder?: boolean; + maxRetries?: number; + consumeAPITypes?: boolean; + family?: 0 | 4 | 6; +} +``` + +Quando configuring `consumeTypes` para `true`, o seguintes configuração vai ser generated por padrão: + +```json +{ + "abortOnError": false, + "consumeAPITypes": true +} +``` + +### consumeAPITypes + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `true` +- Exemplo: [Federation Runtime API type prompt](/guide/basic/type-prompt.html#federation-runtime-api-type-prompt) + +Whether para gerar o tipo de runtime `loadRemote` API + +### maxRetries + +- Tipo: `number` +- Obrigatório: No +- Padrão valor: `3` + +Maximum number de retries for falhou carregamento + +### abortOnError + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `false` + +Whether para lança um erro quando uma problem é encountered during tipo carregamento + +### typesFolder + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `'@mf-types'` + +Tipo storage diretório depois successful carregamento + +### deleteTypesFolder + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `true` + +Antes carregamento tipo arquivos, whether para delete o previously carregado `typesFolder` diretório + +### remoteTypesFolder + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `'@mf-types'` + +`typesFolder` corresponding para `remotes` diretório configuração + +### remoteTypeUrls + +- Type: `(() => Promise) | RemoteTypeUrls` +- Obrigatório: No +- Padrão valor:`undefined` + +Usado for getting o address do `remote` tipo arquivo. + +Aplicação scenarios: + +* Only o runtime API é usado para carregar o producer, e no plugin de build é usado. O MF tipo arquivo address é informed by criação uma `module-federation.config.ts` configuração arquivo e setting este configuração. + +```ts title="module-federation.config.ts" +import { createModuleFederationConfig, type moduleFederationPlugin } from '@module-federation/enhanced'; + +export default createModuleFederationConfig({ + // ... + remotes: { + 'remote1-alias': 'remote1@http://localhost:80801/remoteEntry.js' + }, + dts:{ + consumeTypes:{ + remoteTypeUrls: async()=>{ + // Simulate the request interface to obtain the type file address + const data = await new Promise(resolve=>{ + setTimeout(()=>{ + resolve({ + remote1:{ + alias: 'remote1-alias', + api:'http://localhost:8081/custom-dir/@mf-types.d.ts', + zip:'http://localhost:8081/custom-dir/@mf-types.zip' + } + } ) + },1000) + }); + + return data; + } + } + } +}); +``` + + +* Quando remote é `remoteEntry.js`, o tipo arquivo address geralmente diretamente replaces o js arquivo com o corresponding tipo arquivo, such as `@mf-types.zip`, but o actual uploaded tipo arquivo address é não este, so você pode tell MF o real tipo arquivo address by setting este configuração. + +```ts title="module-federation.config.ts" +import { createModuleFederationConfig } from '@module-federation/enhanced'; + +export default createModuleFederationConfig({ + // ... + remotes: { + 'remote1-alias': 'remote1@http://localhost:80801/remoteEntry.js' + }, + dts:{ + consumeTypes:{ + remoteTypeUrls: { + // remote name + remote1:{ + alias: 'remote1-alias', + api:'http://localhost:8081/custom-dir/@mf-types.d.ts', + zip:'http://localhost:8081/custom-dir/@mf-types.zip' + } + } + } + } +}); +``` + +### family + +- Tipo: `0 | 4 | 6` +- Obrigatório: No +- Padrão valor: `0` + +Configure o IP versão family esse vai ser usado for network operations. + +### typesOnBuild +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Por padrão, Module Federation does não carregue tipo arquivos em produção ( process.env.NODE_ENV === 'production' ). To habilite tipo carregamento em produção builds, definir typesOnBuild para true. + +## tsConfigPath + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `path.join(process.cwd(),'./tsconfig.json')` + +tsconfig configuração arquivo caminho + +## cwd + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `undefined` + +O working diretório para run o compiler + +## displayErrorInTerminal + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `true` + +Whether print erro log em terminal diff --git a/apps/website-new/docs/pt-BR/configure/experiments.mdx b/apps/website-new/docs/pt-BR/configure/experiments.mdx new file mode 100644 index 00000000000..af14fe7fe3b --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/experiments.mdx @@ -0,0 +1,103 @@ +# experiments + +O `experiments` configuração enables advanced e experimental capabilities no plugin. + +## asyncStartup + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Quando `asyncStartup` é habilitado, all Module Federation entrypoints vai initialize asynchronously por padrão. Este means: + +- No need for manual `import()` statements at o top de your app (e.g., `import('./bootstrap')`) +- All entrypoints automatically handle async initialization +- Prevention de "eager consumption" erros por meio de automatic async handling + +:::warning + +Ao usar este mode, all entrypoints vai initialize asynchronously. Se você're manually requiring uma bundled entrypoint ou exposing uma UMD library, it vai retornar uma promise resolving para o exporta. + +::: + +## externalRuntime + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Quando definir para `true`, `@module-federation/runtime-core` vai ser treated as um external e read do global `_FEDERATION_RUNTIME_CORE` em runtime. Ensure o consumer fornece este global (typically usado together com `provideExternalRuntime`), caso contrário it vai não work. + +## provideExternalRuntime + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Only for pure consumer scenarios (no `exposes`). Quando habilitado, automatically injects `@module-federation/inject-external-runtime-core-plugin` para forneça o external runtime at execution time. + +:::warning Notes + +- Usando este together com `exposes` vai lança um erro — apenas pure consumers pode habilite it. +- Prefer configuring it at o topmost consumer para avoid multiple injections. + +::: + +## optimization + +Este objeto contains flags related para build-time optimizations esse pode affect o Module Federation runtime's size e behavior. + +### disableSnapshot + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Quando definir para `true`, este opção defines o `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during o build. No `@module-federation/runtime-core`, este prevents o `snapshotPlugin()` e `generatePreloadAssetsPlugin()` de being included e initialized within o Module Federation instance. + +**Impact:** +* **Benefit:** Can reduce o overall bundle size do Module Federation runtime by excluding o code for these two plugins. +* **Cost:** Disables o functionality fornecido by these plugins. O `snapshotPlugin` é crucial para o "mf-manifest protocol" – it's responsible for generating ou providing runtime access para uma build manifest (e.g., `mf-manifest.json`) containing metadata about módulo expostos, dependências compartilhadas, versões, e remotes. Disabling it means: + * O runtime loses access para este build manifest dados. + * Features relying no manifest, such as dynamic remote discovery, manifest-based versão compatibility checks, advanced asset preloading (também handled pelo removed `generatePreloadAssetsPlugin`), e potentially runtime debugging/introspection tools, vai não função correctly ou vai ser unavailable. + * Use este opção apenas se você não rely on these manifest-driven features e prioritize uma minimal runtime footprint. + +:::warning +**Caution:** Setting `disableSnapshot: true` vai disable o mf-manifest protocol. Este means você vai lose TypeScript syncing suporte e hot módulo replacement (HMR) for módulos federados. Se você são apenas usando `.js` remotes (não manifest-based remotes), você vai não lose any functionality as o `js` remotes não suporte these capabilities anyways. +::: + +### target + +- Tipo: `'web' | 'node'` +- Obrigatório: No +- Padrão: Inferred de Webpack's `target` opção (geralmente `'web'`) + +Este opção defines o `ENV_TARGET` global constant during o build, specifying o intended execution environment. + +**Impact:** +* **`target: 'web'`**: Optimizes o build for navegador environments. + * Ensures navegador-specific remote entry carregamento mechanisms são usado (`loadEntryDom`). + * Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within o `@module-federation/sdk`. Funções like `createScriptNode` e `loadScriptNode`, along com their obrigatório Node.js built-em módulos (e.g., `vm`, `path`, `http`), são completamente removed do bundle, significantly reducing its size. +* **`target: 'node'`**: Optimizes o build for Node.js environments. + * Ensures Node.js-specific remote entry carregamento mechanisms são usado (`loadEntryNode`). + * Includes o necessário Node.js-specific funções do SDK (`createScriptNode`, `loadScriptNode`) no bundle, allowing o federated aplicação para função correctly em Node.js. + +Explicitly setting este valor é recomendado para garantir o intended optimizations são applied, especialmente em universal ou do lado do servidor renderização scenarios. + +### Impact de Optimization Flags on `remoteEntry.js` Size + +O seguinte table demonstrates como diferente combinations do `disableSnapshot`, `target: 'web'`, e `externalRuntime` optimization flags affect o size do generated `remoteEntry.js` arquivo. Esses measurements pode help você choose o right trade-off entre runtime features e bundle size for your use case. + +| Optimization Flags | remoteEntry.js | Gzip Size | Brotli Size | +|---------------------------------------------|:--------------:|:---------:|:-----------:| +| No optimization flags habilitado | 69K | 21437 B | 19024 B | +| `disableSnapshot: true` | 65K | 20096 B | 17860 B | +| `target: 'web'` | 60K | 19314 B | 17105 B | +| Both habilitado | 56K | 17998 B | 15982 B | +| Both habilitado + `externalRuntime: true` | 14K | 5381 B | 4703 B | +| Both disabled + `externalRuntime: true` | 22K | 8222 B | 7269 B | + +**Notes:** +- Enabling both `disableSnapshot` e `target: 'web'` fornece uma ferramenta greatest reduction em bundle size, especialmente quando combined com `externalRuntime: true`. +- Usando o external runtime (`externalRuntime: true`) pode dramatically reduce o size de your remote entry, but requires esse o consumer fornece uma ferramenta runtime. +- Smaller bundle sizes pode lead para faster carregue times e improved performance, but may disable certain features (see above for details no que each flag does). diff --git a/apps/website-new/docs/pt-BR/configure/exposes.mdx b/apps/website-new/docs/pt-BR/configure/exposes.mdx new file mode 100644 index 00000000000..8d0fbfeba0b --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/exposes.mdx @@ -0,0 +1,44 @@ +# exposes + +- Tipo: `PluginExposesOptions` +- Obrigatório: No +- Padrão valor: `undefined` +- Usage: Determines the modules and file entries exposed by {props.brandName || props.name || 'Module Federation'}. + +:::tip +Uma producer-specific parameter, setting `exposes` indicates esse este é uma producer. + +::: + +Depois configuração, o módulo expostos vai ser separated em uma distinct chunk, e se there são any asynchronous chunks, they vai ser extracted em individual chunks as well (o specific extraction behavior depends no chunk splitting rules). + +O `PluginExposesOptions` tipo é as follows: + +```tsx +interface PluginExposesOptions { + [exposeKey: string]: string | ExposesConfig; +} + +interface ExposesConfig { + // File entry + import: string; +} +``` + +O `exposeKey` é essentially consistent com o [Package Entry Points](https://nodejs.org/api/packages.html#package-entry-points) specification (except for não supporting regular expression matching). Exemplo uso: + +```jsx +module.exports = { + plugins: [ + new ModuleFederationPlugin({ + name: 'provider', + exposes: { + // Note: "./" is not supported. Exporting as `.` indicates a default export + '.': './src/index.tsx', + './add': './src/utils/add.ts', + './Button': './src/components/Button.tsx', + }, + }), + ], +}; +``` diff --git a/apps/website-new/docs/pt-BR/configure/filename.mdx b/apps/website-new/docs/pt-BR/configure/filename.mdx new file mode 100644 index 00000000000..9d083145c87 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/filename.mdx @@ -0,0 +1,6 @@ +# filename + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `remoteEntry.js` +- Uso: Determines o filename do generated `remoteEntry`. diff --git a/apps/website-new/docs/pt-BR/configure/getpublicpath.mdx b/apps/website-new/docs/pt-BR/configure/getpublicpath.mdx new file mode 100644 index 00000000000..36635847528 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/getpublicpath.mdx @@ -0,0 +1,37 @@ +# getPublicPath + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `undefined` +- Effective condition: apenas effective quando `exposes` é definir + + +Usado para definir uma dynamic `publicPath`. O valor deve ser uma stringified função ou uma stringified retornar expression. Quando other consumers carregue este provider, o string em `getPublicPath` vai ser executed via `new Function` para obtain o retornar valor, que vai ser usado as o `publicPath` prefix para o módulo’s static assets. Por exemplo, se your deployed projeto receives uma dynamic `cdn_prefix`, você pode configure it as: + +- Função form: ``function(){ retornar window.cdn_prefix }`` +- Return form: ``retornar "https:" + window.navigator.cdn_host + "/recurso/app/"`` + +No exemplo below, `getPublicPath` é definir. Quando other consumers carregue este provider, o string em `getPublicPath` vai ser executed usando `new Function` para obtain o valor, que vai ser usado as o `publicPath` prefix para o módulo’s static assets. + +:::tip NOTE +`getPublicPath` deve ser uma stringified função ou uma stringified retornar expression. +::: + +:::tip NOTE +Se você're usando o módulo federation webpack plugin e want para definir uma dynamic publicPath, você deve definir `__webpack_public_path__ = window.cdn_prefix` no `getPublicPath` função body. +::: + +```ts title="rspack.config.ts" +module.exports = { + plugins: [ + new ModuleFederationPlugin({ + name: 'provider', + exposes: { + './Button': './src/components/Button.tsx', + }, + // ... + getPublicPath: `function() {return "https:" + window.navigator.cdn_host + "/resource/app/"}`, + }), + ], +}; +``` diff --git a/apps/website-new/docs/pt-BR/configure/implementation.mdx b/apps/website-new/docs/pt-BR/configure/implementation.mdx new file mode 100644 index 00000000000..fd6d586a204 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/implementation.mdx @@ -0,0 +1,25 @@ +# implementation + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `undefined` + +O `implementation` opção é usado para modificar o actual bundler runtime versão. It deve ser definir para o caminho de `@module-federation/runtime-tools`. + +Quando working com Module Federation, o runtime é responsible for handling o carregamento e compartilhamento de módulos remotos. Por padrão, o bundler usa uma specific versão do runtime esse é compatible com its versão. However, em some cases, você might precisa use uma diferente versão do runtime ou uma custom implementation. + +By specifying o `implementation` opção, você pode forneça uma caminho para o desired runtime implementation. Este é particularly useful se você precisa use features de uma newer ou older versão do runtime esse não são disponível no padrão versão fornecido pelo bundler. + +Por exemplo, se você quiser use uma specific versão de `@module-federation/runtime-tools`, você pode definir o `implementation` opção em your configuração arquivo: + +```javascript +module.exports = { + // ...other configurations + plugins: [ + new ModuleFederationPlugin({ + // ...other Module Federation options + implementation: require.resolve('@module-federation/runtime-tools'), + }), + ], +}; +``` diff --git a/apps/website-new/docs/pt-BR/configure/index.mdx b/apps/website-new/docs/pt-BR/configure/index.mdx new file mode 100644 index 00000000000..1d07803a974 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/index.mdx @@ -0,0 +1,38 @@ +# Visão geral da configuração + +Esta página lista todas as opções de configuração do `Module Federation`. Para instalação de pacotes e configuração de plugins em diferentes tipos de projeto, consulte Integrações. + +```ts +type ModuleFederationOptions = { + // Nome para module federation + name: string; + // Escopo(s) de compartilhamento para a aplicação atual (padrão: 'default') + shareScope?: string | string[]; + // Nome do arquivo remoteEntry + filename?: string; + // Configuração de módulos remotos e informações de entrada em module federation + remotes?: Array; + // Informações de módulos expostos por module federation + exposes?: PluginExposesOptions; + // Configuração de dependências compartilhadas + shared?: ShareInfos; + // publicPath dinâmico + getPublicPath?: string; + // Plugins de runtime + runtimePlugins?: Array]>; + // Implementação de runtime a ser usada + implementation?: string; + // Configuração de manifest + manifest?: boolean | PluginManifestOptions; + // Controla liveReload da página e hot reload de tipos + dev?: boolean | PluginDevOptions; + // Controla tipos + dts?: boolean | PluginDtsOptions; + // Usa um ponto de entrada de runtime virtual em vez de gravar um arquivo temporário em disco + virtualRuntimeEntry?: boolean; + injectTreeShakingUsedExports?: boolean; + treeShakingDir?: string; + treeShakingSharedPlugins?: Array; + treeShakingSharedExcludePlugins?: Array; +}; +``` diff --git a/apps/website-new/docs/pt-BR/configure/injectTreeShakingUsedExports.mdx b/apps/website-new/docs/pt-BR/configure/injectTreeShakingUsedExports.mdx new file mode 100644 index 00000000000..ead29442db5 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/injectTreeShakingUsedExports.mdx @@ -0,0 +1,11 @@ +# injectTreeShakingUsedExports + +Whether para inject o exporta usado by `shared` no bundler runtime. + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `undefined` + +Este opção controls whether o actual usado exporta de módulos shared são injected no bundler runtime, enabling mais precise dependência management e optimizations. + +Se você são usando `mode: 'server-calc'`, it é recomendado para definir este opção para `false`. diff --git a/apps/website-new/docs/pt-BR/configure/library.mdx b/apps/website-new/docs/pt-BR/configure/library.mdx new file mode 100644 index 00000000000..85a5cb710b5 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/library.mdx @@ -0,0 +1,101 @@ +# library + +`library` configures o output library format do Module Federation container, determining como o container é exposto para external consumers. + +- Tipo: `LibraryOptions` +- Obrigatório: No +- Padrão: `undefined` + +```ts +interface LibraryOptions { + type: LibraryType; + name?: string | string[] | { amd?: string; commonjs?: string; root?: string | string[] }; + export?: string | string[]; + umdNamedDefine?: boolean; + amdContainer?: string; + auxiliaryComment?: string | { + amd?: string; + commonjs?: string; + commonjs2?: string; + root?: string; + }; +} + +type LibraryType = + | 'var' | 'module' | 'assign' | 'assign-properties' + | 'this' | 'window' | 'self' | 'global' + | 'commonjs' | 'commonjs2' | 'commonjs-module' | 'commonjs-static' + | 'amd' | 'amd-require' | 'umd' | 'umd2' + | 'jsonp' | 'system' | string; +``` + +## tipo + +- Tipo: `LibraryType` +- Obrigatório: Yes +- Padrão: - + +Specifies o output library tipo para o container. Common valores: + +| Valor | Description | +|---|---| +| `'var'` | Assigns para uma global variable (padrão) | +| `'module'` | ESM output (requires `experiments.outputModule: true`) | +| `'commonjs2'` | CommonJS via `module.exports` | +| `'umd'` | Compatible com AMD, CommonJS, e global variable | +| `'global'` | Attaches para o `global` objeto | +| `'window'` | Attaches para o `window` objeto | +| `'self'` | Attaches para o `self` objeto | +| `'system'` | SystemJS módulo format | + +## name + +- Tipo: `string | string[] | LibraryCustomUmdObject` +- Obrigatório: No +- Padrão: `undefined` + +O name do library. For `umd` tipo, você pode specify separate names for amd, commonjs, e o global variable. + +## exporte + +- Tipo: `string | string[]` +- Obrigatório: No +- Padrão: `undefined` + +Specifies que exporte deve ser exposto as o library. + +## umdNamedDefine + +- Tipo: `boolean` +- Obrigatório: No +- Padrão: `false` + +Quando `type` é `'umd'`, whether para name o AMD módulo (i.e. pass o módulo name em `define()`). + +## amdContainer + +- Tipo: `string` +- Obrigatório: No +- Padrão: `undefined` + +Add uma container prefix for `define`/`require` funções no AMD módulo. + +## auxiliaryComment + +- Tipo: `string | object` +- Obrigatório: No +- Padrão: `undefined` + +Add uma comment no UMD wrapper for each módulo format. + +## Exemplo + +```ts +new ModuleFederationPlugin({ + name: '@demo/provider', + library: { type: 'var', name: 'provider' }, + exposes: { + './Button': './src/Button', + }, +}); +``` diff --git a/apps/website-new/docs/pt-BR/configure/manifest.mdx b/apps/website-new/docs/pt-BR/configure/manifest.mdx new file mode 100644 index 00000000000..ed24a769b7f --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/manifest.mdx @@ -0,0 +1,52 @@ +# manifest + +- Tipo: `boolean | PluginManifestOptions` +- Obrigatório: No +- Padrão valor: `undefined` + +Controls whether the plugin generates manifest artifacts and how they are produced. Quando enabled, the plugin emits {props.manifest || 'mf-manifest.json' } and {props.stats || 'mf-stats.json' } (names can be customized via `fileName`) on every build so that other tools can consume them diretamente por meio de `processAssets` or from the final build output. + +- {props.stats || 'mf-stats.json'}: captures the full build statistics, including the assets for exposes/shared/remotes, `metaData` (plugin version, build info, `remoteEntry`, etc.), and any additional asset analysis. Ideal for debugging or merging stats across environments, see field references: [{props.stats || 'mf-stats.json'}](/guide/advanced/stats-fields.html). +- {props.manifest || 'mf-manifest.json'}: a runtime-oriented manifest distilled from the stats. It keeps the stable structure that {props.brandName || 'Module Federation'} consumers read quando carregamento remote modules. The exposes/shared/remotes entries describe what is actually available to consumers, see field references: [{props.manifest || 'mf-manifest.json'}](/guide/advanced/manifest-fields.html). + +O `PluginManifestOptions` tipos são as seguintes: + +```ts +interface PluginManifestOptions { + filePath?: string; + disableAssetsAnalyze?: boolean; + fileName?: string; +} +``` + +## filePath + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `undefined` + +manifest filePath + +## fileName + +- Tipo: `string` +- Obrigatório: No +- Padrão valor: `'mf-manifest.json'` + +manifest fileName + +Se `fileName` é fornecido, o companion stats arquivo automatically receives uma `-stats` suffix (por exemplo, `fileName: 'mf.json'` produces both `mf.json` e `mf-stats.json`). Generated arquivos são written under `filePath` quando esse opção é definir. + +## disableAssetsAnalyze + +:::warning +It é não recomendado para definir este configuração. Depois setting, o preload função vai ser disabled! +::: + +- Tipo: `boolean` +- Obrigatório: No +- Padrão valor: `undefined` + +Quando analyzing assets em complex projetos, ele pode take uma long time. By setting este opção para `true`, asset analysis vai ser disabled, optimizing build time. +Se o projeto é purely consumer-oriented, it vai ser definir para `true` em dev por padrão. +Se definir para `true`, o `shared` e `exposes` fields vai não ser present no manifest, e `assets` vai não ser present em `remotes`. diff --git a/apps/website-new/docs/pt-BR/configure/name.mdx b/apps/website-new/docs/pt-BR/configure/name.mdx new file mode 100644 index 00000000000..22ff6d0cd4e --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/name.mdx @@ -0,0 +1,8 @@ +# name + +- Tipo: `string` +- Obrigatório: Yes + +`Module Federation` módulo name, o name deve ser unique. + +`Module Federation` usa o name for runtime dados retrieval e global chunk storage variable references. diff --git a/apps/website-new/docs/pt-BR/configure/remotes.mdx b/apps/website-new/docs/pt-BR/configure/remotes.mdx new file mode 100644 index 00000000000..f2cb4c2e26e --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/remotes.mdx @@ -0,0 +1,77 @@ +# remotes + +- Tipo: `PluginRemoteOptions` +- Obrigatório: No +- Padrão: `undefined` +- Usage: Used for consuming producer modules with {props.brandName || props.name || 'Module Federation'} + +:::tip +Uma parameter unique para consumers. Se `remotes` é definir, ele pode ser considered esse este é uma consumer. +::: + +O `PluginRemoteOptions` tipo é as follows: + +```tsx +type ModuleFederationInfo = string; +type ShareScope = string | string[]; + +type RemoteConfig = { + external: ModuleFederationInfo | ModuleFederationInfo[]; + shareScope?: ShareScope; +}; + +interface PluginRemoteOptions { + [remoteAlias: string]: ModuleFederationInfo | RemoteConfig; +} +``` + +- `remoteAlias` é o name actually usado for reference pelo consumer e pode ser configured as needed. Por exemplo, se `remoteAlias` é definir para `demo`, then o consumption método would ser `import xx from 'demo'`. +- `ModuleFederationInfo` é composed de `ModuleFederation name` + `@` + `ModuleFederation entry` + - `ModuleFederation name` é o name definir pelo producer + - `entry` pode ser either `mf-manifest.json` ou `remoteEntry.js` + - Quando `entry` é `mf-manifest.json`, it has o seguintes additional capabilities: + - Dynamic módulo tipo hints + - Resource preloading + - Chrome devtool debugging tool + +```js +module.exports = { + plugins: [ + new ModuleFederationPlugin({ + name: 'host', + // The `remotes` below defines two producers, named `manifest-provider` for the project started on port 3011 and `js-entry-provider` for the project started on port 3012 + remotes: { + 'manifest-provider': + 'manifest_provider@http://localhost:3011/mf-manifest.json', + 'js-entry-provider': + 'js_entry_provider@http://localhost:3012/remoteEntry.js', + }, + }), + ], +}; +``` + +## shareScope + +- Tipo: `string | string[]` +- Obrigatório: No +- Padrão: `'default'` + +Defines que compartilhe escopos (Compartilhe Escopo) o consumer aligns com uma given producer. Este é useful for isolating certain dependências compartilhadas away do padrão pool (por exemplo, putting um internal design system em `scope1` enquanto keeping React em `default`). + +```ts +new ModuleFederationPlugin({ + name: 'host', + remotes: { + remote: { + external: 'app_remote@http://localhost:2001/remoteEntry.js', + shareScope: ['default', 'scope1'], + }, + }, +}); +``` + +Related configuração: + +- O producer deve declare que escopos it initializes via [shareScope](/configure/shareScope.html). +- Each dependência compartilhada chooses its escopo via [shared.shareScope](/configure/shared.html#sharescope). diff --git a/apps/website-new/docs/pt-BR/configure/remotetype.mdx b/apps/website-new/docs/pt-BR/configure/remotetype.mdx new file mode 100644 index 00000000000..76b6fa80230 --- /dev/null +++ b/apps/website-new/docs/pt-BR/configure/remotetype.mdx @@ -0,0 +1,59 @@ +# remoteType + +`remoteType` specifies o external módulo tipo for remote containers, determining como o runtime carrega remote entries. + +- Tipo: `ExternalsType` +- Obrigatório: No +- Padrão: `'script'` + +```ts +type ExternalsType = + | 'var' | 'module' | 'assign' + | 'this' | 'window' | 'self' | 'global' + | 'commonjs' | 'commonjs2' | 'commonjs-module' | 'commonjs-static' + | 'amd' | 'amd-require' + | 'umd' | 'umd2' + | 'jsonp' | 'system' + | 'promise' | 'import' | 'module-import' + | 'script' | 'node-commonjs'; +``` + +## Uso + +`remoteType` controls como webpack/rspack carrega remote container scripts em runtime. Common valores: + +| Valor | Description | +|---|---| +| `'script'` | Loads via `\n', - }, - ); + it('infers ts files for multi-dot expose paths', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.generated', + { + 'src/components/foo.generated.ts': 'export const foo = 1;\n', + }, + ); - expect(resolvedPath).toBe( - resolve(context, 'src/components/foo.generated.vue'), - ); - }); + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.generated.ts'), + ); + }); - it('infers jsx files for multi-dot expose paths', () => { - const { context, resolvedPath } = resolveExpose( - './src/components/foo.generated', - { - 'src/components/foo.generated.jsx': - 'export const Foo = () => null;\n', - }, - ); + it('preserves explicit multi-dot ts paths', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.generated.ts', + { + 'src/components/foo.generated.ts': 'export const foo = 1;\n', + }, + ); - expect(resolvedPath).toBe( - resolve(context, 'src/components/foo.generated.jsx'), - ); - }); + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.generated.ts'), + ); + }); - it('falls back to dotted directory index files', () => { - const { context, resolvedPath } = resolveExpose( - './src/components/foo.bar', - { - 'src/components/foo.bar/index.ts': 'export const foo = 1;\n', - }, - ); + it('infers tsx files for multi-dot expose paths', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.generated', + { + 'src/components/foo.generated.tsx': + 'export const Foo = () => null;\n', + }, + ); - expect(resolvedPath).toBe( - resolve(context, 'src/components/foo.bar/index.ts'), - ); - }); + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.generated.tsx'), + ); + }); - it('falls back to normal directory index files', () => { - const { context, resolvedPath } = resolveExpose( - './src/components/foo', - { - 'src/components/foo/index.ts': 'export const foo = 1;\n', - }, - ); + it('infers vue files for multi-dot expose paths', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.generated', + { + 'src/components/foo.generated.vue': + '\n', + }, + ); - expect(resolvedPath).toBe( - resolve(context, 'src/components/foo/index.ts'), - ); - }); - }); - }); + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.generated.vue'), + ); + }); - describe('successfully parse tsconfig with project references', () => { - it.each([ - { - tsConfigFile: './testconfig-reference.test.json', - expectedRootDir: resolve(__dirname), - }, - { - tsConfigFile: './testconfig-reference-2.test.json', - expectedRootDir: resolve(__dirname), - }, - { - tsConfigFile: './testconfig-reference-relative.test.json', - expectedRootDir: resolve(__dirname, '..'), - }, - ])( - 'infers rootDir from project references', - ({ tsConfigFile, expectedRootDir }) => { - const tsConfigPath = join(__dirname, tsConfigFile); - const { tsConfig } = retrieveRemoteConfig({ - moduleFederationConfig, - tsConfigPath, + it('infers jsx files for multi-dot expose paths', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.generated', + { + 'src/components/foo.generated.jsx': + 'export const Foo = () => null;\n', + }, + ); + + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.generated.jsx'), + ); }); - expect(tsConfig.compilerOptions.rootDir).toBe(expectedRootDir); - }, - ); + it('falls back to dotted directory index files', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo.bar', + { + 'src/components/foo.bar/index.ts': 'export const foo = 1;\n', + }, + ); + + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo.bar/index.ts'), + ); + }); + + it('falls back to normal directory index files', () => { + const { context, resolvedPath } = resolveExpose( + './src/components/foo', + { + 'src/components/foo/index.ts': 'export const foo = 1;\n', + }, + ); + + expect(resolvedPath).toBe( + resolve(context, 'src/components/foo/index.ts'), + ); + }); + }); + } }); + + for (const scenario of typeScriptScenarios) { + describe(`successfully parse tsconfig with project references using ${scenario.name}`, () => { + it.each([ + { + tsConfigFile: './testconfig-reference.test.json', + expectedRootDir: resolve(__dirname), + }, + { + tsConfigFile: './testconfig-reference-2.test.json', + expectedRootDir: resolve(__dirname), + }, + { + tsConfigFile: './testconfig-reference-relative.test.json', + expectedRootDir: resolve(__dirname, '..'), + }, + ])( + 'infers rootDir from project references', + ({ tsConfigFile, expectedRootDir }) => { + const tsConfigPath = join(__dirname, tsConfigFile); + const typeScriptContext = createTemporaryProject({}); + const { tsConfig } = retrieveRemoteConfig({ + moduleFederationConfig: withTypeScriptScenario( + scenario, + typeScriptContext, + moduleFederationConfig, + ), + tsConfigPath, + }); + + expect(tsConfig.compilerOptions.rootDir).toBe(expectedRootDir); + }, + ); + }); + } }); diff --git a/packages/dts-plugin/src/core/configurations/remotePlugin.ts b/packages/dts-plugin/src/core/configurations/remotePlugin.ts index 180231d9fd9..0a160e4e755 100644 --- a/packages/dts-plugin/src/core/configurations/remotePlugin.ts +++ b/packages/dts-plugin/src/core/configurations/remotePlugin.ts @@ -1,11 +1,67 @@ -import { existsSync } from 'fs'; -import { dirname, join, resolve, extname, isAbsolute } from 'path'; +import crypto from 'crypto'; +import { execFileSync } from 'child_process'; +import { existsSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'fs'; +import { + dirname, + join, + resolve, + extname, + isAbsolute, + normalize, + relative, + sep, +} from 'path'; import { utils } from '@module-federation/managers'; -import typescript from 'typescript'; +import { TEMP_DIR } from '@module-federation/sdk'; import { RemoteOptions } from '../interfaces/RemoteOptions'; import { validateOptions } from '../lib/utils'; -import { TsConfigJson } from '../interfaces/TsConfigJson'; +import { + TsConfigCompilerOptions, + TsConfigJson, +} from '../interfaces/TsConfigJson'; +import { + getTypeScriptPackageInfo, + requireTypeScript, +} from '../lib/typeScriptResolver'; +import { logger } from '../../server'; + +interface ProjectReference { + path: string; + originalPath?: string; +} + +interface ParsedConfigContent { + options: TsConfigCompilerOptions; + fileNames: string[]; + projectReferences: ProjectReference[]; +} + +interface LegacyTypeScriptApi { + sys: { + readFile: (path: string) => string | undefined; + }; + readConfigFile: ( + fileName: string, + readFile: (path: string) => string | undefined, + ) => { + config?: TsConfigJson; + error?: { + messageText: string | { toString(): string }; + }; + }; + parseJsonConfigFileContent: ( + json: TsConfigJson, + host: LegacyTypeScriptApi['sys'], + basePath: string, + ) => ParsedConfigContent; + createProgram: ( + rootNames: string[], + options: TsConfigCompilerOptions, + ) => { + getSourceFiles: () => Array<{ fileName: string }>; + }; +} const defaultOptions = { tsConfigPath: './tsconfig.json', @@ -26,9 +82,7 @@ const defaultOptions = { deleteTsConfig: true, } satisfies Partial; -function getEffectiveRootDir( - parsedCommandLine: typescript.ParsedCommandLine, -): string { +function getEffectiveRootDir(parsedCommandLine: ParsedConfigContent): string { const compilerOptions = parsedCommandLine.options; if (compilerOptions.rootDir) { @@ -76,48 +130,326 @@ function getEffectiveRootDir( const getDependentFiles = ( rootFiles: string[], - configContent: typescript.ParsedCommandLine, + configContent: ParsedConfigContent, rootDir: string, + typescript: LegacyTypeScriptApi, ): string[] => { const program = typescript.createProgram(rootFiles, configContent.options); const sourceFiles = program.getSourceFiles(); const dependentFiles = sourceFiles .map((file) => file.fileName) .filter( - (file) => !file.endsWith('.d.ts') && file.startsWith(rootDir + '/'), - ); + (file) => !file.endsWith('.d.ts') && isFileWithinRootDir(file, rootDir), + ) + .map((file) => normalizeFileToRootDir(file, rootDir)); return dependentFiles.length ? dependentFiles : rootFiles; }; +const normalizeForComparison = (value: string) => { + try { + return normalize(realpathSync.native(value)); + } catch { + return normalize(value); + } +}; + +const isFileWithinRootDir = (file: string, rootDir: string) => { + const normalizedFile = normalizeForComparison(file); + const normalizedRootDir = normalizeForComparison(rootDir); + return ( + normalizedFile === normalizedRootDir || + normalizedFile.startsWith( + normalizedRootDir.endsWith(sep) + ? normalizedRootDir + : `${normalizedRootDir}${sep}`, + ) + ); +}; + +const normalizeFileToRootDir = (file: string, rootDir: string) => { + const normalizedFile = normalizeForComparison(file); + const normalizedRootDir = normalizeForComparison(rootDir); + if ( + normalizedFile === normalizedRootDir || + normalizedFile.startsWith( + normalizedRootDir.endsWith(sep) + ? normalizedRootDir + : `${normalizedRootDir}${sep}`, + ) + ) { + return normalize( + join(rootDir, relative(normalizedRootDir, normalizedFile)), + ); + } + return normalize(file); +}; + +const getTypeScriptContext = ({ + context, + moduleFederationConfig, +}: Required) => { + const dtsOptions = moduleFederationConfig.dts; + return typeof dtsOptions !== 'boolean' && dtsOptions?.cwd + ? dtsOptions.cwd + : context; +}; + +const resolveFromConfigDir = (value: unknown, configDir: string) => { + if (typeof value !== 'string') { + return value; + } + return isAbsolute(value) ? normalize(value) : resolve(configDir, value); +}; + +const normalizeCompilerOptions = ( + compilerOptions: TsConfigCompilerOptions = {}, + configDir: string, +): TsConfigCompilerOptions => { + const normalizedOptions = { ...compilerOptions }; + for (const pathOption of [ + 'rootDir', + 'outDir', + 'declarationDir', + 'tsBuildInfoFile', + ]) { + if (typeof normalizedOptions[pathOption] === 'string') { + normalizedOptions[pathOption] = resolveFromConfigDir( + normalizedOptions[pathOption], + configDir, + ); + } + } + if ( + normalizedOptions['moduleResolution'] === 'node' || + normalizedOptions['moduleResolution'] === 'node10' + ) { + // TS 7 still prints legacy node resolution from --showConfig, but rejects it for --project. + normalizedOptions['moduleResolution'] = 'bundler'; + } + return normalizedOptions; +}; + +const parseShowConfigOutput = ( + stdout: string, + resolvedTsConfigPath: string, +): { + rawTsConfigJson: TsConfigJson; + configContent: ParsedConfigContent; +} => { + const configDir = dirname(resolvedTsConfigPath); + const shownConfig = JSON.parse(stdout) as TsConfigJson; + const compilerOptions = normalizeCompilerOptions( + shownConfig.compilerOptions, + configDir, + ); + const fileNames = (shownConfig.files || []).map((file) => + resolveFromConfigDir(file, configDir), + ) as string[]; + const projectReferences = (shownConfig.references || []).map((reference) => ({ + ...reference, + path: resolveFromConfigDir(reference.path, configDir) as string, + originalPath: reference.path, + })); + + return { + rawTsConfigJson: { + ...shownConfig, + compilerOptions, + }, + configContent: { + options: compilerOptions, + fileNames, + projectReferences, + }, + }; +}; + +const readTsConfigWithTsc = ( + resolvedTsConfigPath: string, + typeScriptContext: string, +) => { + const typeScriptPackageInfo = getTypeScriptPackageInfo(typeScriptContext); + const stdout = execFileSync( + process.execPath, + [ + typeScriptPackageInfo.tscBinPath, + '--showConfig', + '--project', + resolvedTsConfigPath, + ], + { + cwd: typeScriptContext, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }, + ); + return parseShowConfigOutput(stdout, resolvedTsConfigPath); +}; + +const writeListFilesTsConfig = ( + rootFiles: string[], + resolvedTsConfigPath: string, + context: string, + compilerOptions?: TsConfigCompilerOptions, +) => { + const hash = crypto + .createHash('md5') + .update(`${JSON.stringify(rootFiles)}${resolvedTsConfigPath}${Date.now()}`) + .digest('hex'); + const tempTsConfigJsonPath = resolve( + context, + 'node_modules', + TEMP_DIR, + `tsconfig.list-files.${hash}.json`, + ); + mkdirSync(dirname(tempTsConfigJsonPath), { recursive: true }); + const listFilesConfig: TsConfigJson = compilerOptions + ? { + compilerOptions, + files: rootFiles.map((file) => + isAbsolute(file) ? file : resolve(context, file), + ), + } + : { + extends: resolvedTsConfigPath, + files: rootFiles.map((file) => + isAbsolute(file) ? file : resolve(context, file), + ), + }; + writeFileSync(tempTsConfigJsonPath, JSON.stringify(listFilesConfig, null, 2)); + return tempTsConfigJsonPath; +}; + +const formatCompilerError = (error: unknown) => { + const readOutput = (value: unknown) => { + if (Buffer.isBuffer(value)) { + return value.toString('utf8'); + } + return typeof value === 'string' ? value : ''; + }; + + if (typeof error === 'object' && error !== null) { + const processError = error as { + stderr?: unknown; + stdout?: unknown; + message?: unknown; + }; + const stderr = readOutput(processError.stderr).trim(); + if (stderr) { + return stderr.split(/\r?\n/)[0]; + } + const stdout = readOutput(processError.stdout).trim(); + if (stdout) { + return stdout.split(/\r?\n/)[0]; + } + if (typeof processError.message === 'string') { + return processError.message; + } + } + + return String(error); +}; + +const getDependentFilesWithTsc = ( + rootFiles: string[], + rootDir: string, + resolvedTsConfigPath: string, + compilerOptions: TsConfigCompilerOptions, + context: string, + typeScriptContext: string, +): string[] => { + if (!rootFiles.length) { + return []; + } + + const typeScriptPackageInfo = getTypeScriptPackageInfo(typeScriptContext); + const listFilesTsConfigPath = writeListFilesTsConfig( + rootFiles, + resolvedTsConfigPath, + context, + compilerOptions, + ); + try { + const stdout = execFileSync( + process.execPath, + [ + typeScriptPackageInfo.tscBinPath, + '--listFilesOnly', + '--project', + listFilesTsConfigPath, + ], + { + cwd: typeScriptContext, + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], + }, + ); + const dependentFiles = stdout + .split(/\r?\n/) + .map((file) => file.trim()) + .filter(Boolean) + .map((file) => (isAbsolute(file) ? file : resolve(context, file))) + .filter( + (file) => !file.endsWith('.d.ts') && isFileWithinRootDir(file, rootDir), + ) + .map((file) => normalizeFileToRootDir(file, rootDir)); + return dependentFiles.length ? dependentFiles : rootFiles; + } catch (error) { + logger.warn( + `Failed to collect TypeScript dependency files with "tsc --listFilesOnly"; falling back to exposed files only. ${formatCompilerError( + error, + )}`, + ); + return rootFiles; + } finally { + rmSync(listFilesTsConfigPath, { force: true }); + } +}; + const readTsConfig = ( - { + remoteOptions: Required, + mapComponentsToExpose: Record, +): TsConfigJson => { + const { tsConfigPath, typesFolder, compiledTypesFolder, context, additionalFilesToCompile, outputDir, - }: Required, - mapComponentsToExpose: Record, -): TsConfigJson => { + } = remoteOptions; const resolvedTsConfigPath = resolve(context, tsConfigPath); + const typeScriptContext = getTypeScriptContext(remoteOptions); + const typeScriptPackageInfo = getTypeScriptPackageInfo(typeScriptContext); + + let rawTsConfigJson: TsConfigJson; + let configContent: ParsedConfigContent; + let typescript: LegacyTypeScriptApi | undefined; + + if (typeScriptPackageInfo.majorVersion === 7) { + ({ rawTsConfigJson, configContent } = readTsConfigWithTsc( + resolvedTsConfigPath, + typeScriptContext, + )); + } else { + typescript = requireTypeScript(typeScriptContext); + const readResult = typescript.readConfigFile( + resolvedTsConfigPath, + typescript.sys.readFile, + ); - const readResult = typescript.readConfigFile( - resolvedTsConfigPath, - typescript.sys.readFile, - ); + if (readResult.error) { + throw new Error(readResult.error.messageText.toString()); + } - if (readResult.error) { - throw new Error(readResult.error.messageText.toString()); + rawTsConfigJson = readResult.config || {}; + configContent = typescript.parseJsonConfigFileContent( + rawTsConfigJson, + typescript.sys, + dirname(resolvedTsConfigPath), + ); + configContent.projectReferences = configContent.projectReferences || []; } - - const rawTsConfigJson: TsConfigJson = readResult.config; - - const configContent = typescript.parseJsonConfigFileContent( - rawTsConfigJson, - typescript.sys, - dirname(resolvedTsConfigPath), - ); const rootDir = getEffectiveRootDir(configContent); const outDir = resolve( @@ -127,7 +459,7 @@ const readTsConfig = ( compiledTypesFolder, ); - const defaultCompilerOptions: typescript.CompilerOptions = { + const defaultCompilerOptions: TsConfigCompilerOptions = { rootDir, emitDeclarationOnly: true, noEmit: false, @@ -165,7 +497,16 @@ const readTsConfig = ( ); const filesToCompile = [ - ...getDependentFiles(rootFiles, configContent, rootDir), + ...(typescript + ? getDependentFiles(rootFiles, configContent, rootDir, typescript) + : getDependentFilesWithTsc( + rootFiles, + rootDir, + resolvedTsConfigPath, + configContent.options, + context, + typeScriptContext, + )), ...configContent.fileNames.filter( (filename) => filename.endsWith('.d.ts') && diff --git a/packages/dts-plugin/src/core/configurations/tsconfig.test.json b/packages/dts-plugin/src/core/configurations/tsconfig.test.json index a9fbdb1de98..29a505a4e90 100644 --- a/packages/dts-plugin/src/core/configurations/tsconfig.test.json +++ b/packages/dts-plugin/src/core/configurations/tsconfig.test.json @@ -3,7 +3,6 @@ "target": "es2017", "module": "esnext", "lib": ["esnext"], - "moduleResolution": "node10", "esModuleInterop": true, "strict": true, "strictNullChecks": true, diff --git a/packages/dts-plugin/src/core/interfaces/TsConfigJson.ts b/packages/dts-plugin/src/core/interfaces/TsConfigJson.ts index 6744ed727fe..55cbeaf78e4 100644 --- a/packages/dts-plugin/src/core/interfaces/TsConfigJson.ts +++ b/packages/dts-plugin/src/core/interfaces/TsConfigJson.ts @@ -1,9 +1,19 @@ -import ts from 'typescript'; +export type TsConfigCompilerOptions = Record & { + rootDir?: string; + outDir?: string; + declarationDir?: string; + tsBuildInfoFile?: string; + incremental?: boolean; + paths?: Record; + baseUrl?: string; +}; export interface TsConfigJson { extends?: string; - compilerOptions?: ts.CompilerOptions; + compilerOptions?: TsConfigCompilerOptions; exclude?: string[]; include?: string[]; files?: string[]; + references?: Array<{ path: string }>; + [key: string]: any; } diff --git a/packages/dts-plugin/src/core/lib/DTSManager.advance.spec.ts b/packages/dts-plugin/src/core/lib/DTSManager.advance.spec.ts index 9cda89c3962..cd4f2ebc353 100644 --- a/packages/dts-plugin/src/core/lib/DTSManager.advance.spec.ts +++ b/packages/dts-plugin/src/core/lib/DTSManager.advance.spec.ts @@ -197,6 +197,9 @@ describe('DTSManager advance usage', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, diff --git a/packages/dts-plugin/src/core/lib/DTSManager.spec.ts b/packages/dts-plugin/src/core/lib/DTSManager.spec.ts index 15a53974e88..1840d4bd46a 100644 --- a/packages/dts-plugin/src/core/lib/DTSManager.spec.ts +++ b/packages/dts-plugin/src/core/lib/DTSManager.spec.ts @@ -145,6 +145,9 @@ describe('DTSManager', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, @@ -269,6 +272,9 @@ describe('DTSManager', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, @@ -504,6 +510,9 @@ describe('DTSManager', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, @@ -651,6 +660,9 @@ describe('DTSManager', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, diff --git a/packages/dts-plugin/src/core/lib/DtsWorker.spec.ts b/packages/dts-plugin/src/core/lib/DtsWorker.spec.ts index e09bede256e..28b8020c37a 100644 --- a/packages/dts-plugin/src/core/lib/DtsWorker.spec.ts +++ b/packages/dts-plugin/src/core/lib/DtsWorker.spec.ts @@ -158,6 +158,9 @@ describe('generateTypesInChildProcess', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, diff --git a/packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts b/packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts index 5340e776bfb..32ab9fb49e0 100644 --- a/packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts +++ b/packages/dts-plugin/src/core/lib/typeScriptCompiler.test.ts @@ -1,11 +1,20 @@ import dirTree from 'directory-tree'; -import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'fs'; +import { + existsSync, + mkdirSync, + readFileSync, + rmSync, + symlinkSync, + writeFileSync, +} from 'fs'; +import { createRequire } from 'module'; import os from 'os'; -import { join, resolve, sep } from 'path'; +import { dirname, join, resolve, sep } from 'path'; import util from 'util'; import { afterEach, describe, expect, it, rs } from '@rstest/core'; import type { TsConfigJson } from '../interfaces/TsConfigJson'; +import { retrieveRemoteConfig } from '../configurations/remotePlugin'; import { RemoteOptions } from '../interfaces/RemoteOptions'; import { compileTs, @@ -14,7 +23,19 @@ import { } from './typeScriptCompiler'; describe('typeScriptCompiler', () => { + const requireFromTest = createRequire(__filename); const tmpDir = join(os.tmpdir(), 'typeScriptCompiler'); + const linkTypeScriptPackage = (projectDir: string, packageName: string) => { + const typeScriptRoot = dirname( + requireFromTest.resolve(`${packageName}/package.json`), + ); + mkdirSync(join(projectDir, 'node_modules'), { recursive: true }); + symlinkSync( + typeScriptRoot, + join(projectDir, 'node_modules/typescript'), + 'junction', + ); + }; const readJSONSync = (filePath: string) => JSON.parse(readFileSync(filePath, 'utf-8')); @@ -123,7 +144,7 @@ describe('typeScriptCompiler', () => { // no files generate if empty mapToExpose }); - it('use shell option on windows when invoking compiler', async () => { + it('does not use shell option on windows when invoking direct TypeScript compiler', async () => { const execPromise = rs.fn().mockResolvedValue({}); rs.spyOn(util, 'promisify').mockReturnValue( execPromise as unknown as ReturnType, @@ -145,9 +166,9 @@ describe('typeScriptCompiler', () => { } expect(execPromise).toHaveBeenCalledWith( - 'npx', + process.execPath, expect.any(Array), - expect.objectContaining({ shell: true }), + expect.objectContaining({ cwd: projectRoot, shell: false }), ); }); @@ -173,9 +194,9 @@ describe('typeScriptCompiler', () => { } expect(execPromise).toHaveBeenCalledWith( - 'npx', + process.execPath, expect.any(Array), - expect.objectContaining({ shell: false }), + expect.objectContaining({ cwd: projectRoot, shell: false }), ); }); @@ -201,11 +222,78 @@ describe('typeScriptCompiler', () => { } const args = execPromise.mock.calls[0]?.[1] as string[]; - expect(args.slice(0, 3)).toEqual(['tsc', '--pretty', 'false']); + expect(args[0]).toMatch(/typescript[/\\]bin[/\\]tsc$/); + expect(args.slice(1, 3)).toEqual(['--pretty', 'false']); expect(args[3]).toBe('--project'); expect(args[4]).toEqual(expect.any(String)); }); + it('keeps custom compilerInstance invocations through the package manager', async () => { + const execPromise = rs.fn().mockResolvedValue({}); + rs.spyOn(util, 'promisify').mockReturnValue( + execPromise as unknown as ReturnType, + ); + const restorePlatform = withProcessPlatform('linux'); + const filepath = join(__dirname, './typeScriptCompiler.ts'); + const mapToExpose = { + tsCompiler: filepath, + }; + + try { + await compileTs( + mapToExpose, + { ...tsConfig, files: [filepath] }, + { + ...remoteOptions, + compilerInstance: 'vue-tsc --declaration false', + }, + ); + } finally { + restorePlatform(); + } + + const args = execPromise.mock.calls[0]?.[1] as string[]; + expect(execPromise).toHaveBeenCalledWith( + 'npx', + expect.any(Array), + expect.objectContaining({ cwd: projectRoot, shell: false }), + ); + expect(args.slice(0, 3)).toEqual(['vue-tsc', '--declaration', 'false']); + expect(args[3]).toBe('--project'); + expect(args[4]).toEqual(expect.any(String)); + }); + + it('uses shell option on windows for custom compilerInstance invocations', async () => { + const execPromise = rs.fn().mockResolvedValue({}); + rs.spyOn(util, 'promisify').mockReturnValue( + execPromise as unknown as ReturnType, + ); + const restorePlatform = withProcessPlatform('win32'); + const filepath = join(__dirname, './typeScriptCompiler.ts'); + const mapToExpose = { + tsCompiler: filepath, + }; + + try { + await compileTs( + mapToExpose, + { ...tsConfig, files: [filepath] }, + { + ...remoteOptions, + compilerInstance: 'vue-tsc --declaration false', + }, + ); + } finally { + restorePlatform(); + } + + expect(execPromise).toHaveBeenCalledWith( + 'npx', + expect.any(Array), + expect.objectContaining({ cwd: projectRoot, shell: true }), + ); + }); + it('does not wrap project path in single quotes on Windows (#4133)', async () => { const execPromise = rs.fn().mockRejectedValue(new Error('tsc error')); rs.spyOn(util, 'promisify').mockReturnValue( @@ -241,6 +329,7 @@ describe('typeScriptCompiler', () => { const projectDir = join(tmpDir, 'declarationDirProject'); const srcDir = join(projectDir, 'src'); mkdirSync(srcDir, { recursive: true }); + linkTypeScriptPackage(projectDir, 'typescript'); const entryFile = join(srcDir, 'hello.ts'); writeFileSync(entryFile, 'export const hello = 1;\n'); @@ -351,6 +440,9 @@ describe('typeScriptCompiler', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, ], name: 'lib', }, @@ -377,6 +469,7 @@ describe('typeScriptCompiler', () => { const projectDir = join(tmpDir, 'multiDotExposeProject'); const srcDir = join(projectDir, 'src', 'components'); mkdirSync(srcDir, { recursive: true }); + linkTypeScriptPackage(projectDir, 'typescript'); const entryFile = join(srcDir, 'foo.generated.ts'); writeFileSync(entryFile, 'export const foo = 1;\n'); @@ -458,6 +551,90 @@ describe('typeScriptCompiler', () => { ); }); + it('generates declarations with TypeScript 7', async () => { + const projectDir = join(tmpDir, 'typescript7Project'); + const srcDir = join(projectDir, 'src'); + mkdirSync(srcDir, { recursive: true }); + + linkTypeScriptPackage(projectDir, 'typescript-7'); + + const entryFile = join(srcDir, 'button.ts'); + const dependencyFile = join(srcDir, 'dependency.ts'); + const unusedFile = join(srcDir, 'unused.ts'); + writeFileSync(entryFile, "export { dependency } from './dependency';\n"); + writeFileSync(dependencyFile, 'export const dependency = 1;\n'); + writeFileSync(unusedFile, 'export const unused = 1;\n'); + + writeFileSync( + join(projectDir, 'tsconfig.json'), + JSON.stringify( + { + compilerOptions: { + target: 'es2017', + module: 'commonjs', + moduleResolution: 'node10', + rootDir: './src', + outDir: './dist', + strict: true, + }, + include: ['src'], + }, + null, + 2, + ), + ); + + const { tsConfig, mapComponentsToExpose, remoteOptions } = + retrieveRemoteConfig({ + context: projectDir, + tsConfigPath: './tsconfig.json', + typesFolder: 'typesRemoteFolder', + compiledTypesFolder: 'compiledTypesFolder', + moduleFederationConfig: { + name: 'typescript7Remote', + filename: 'remoteEntry.js', + exposes: { + './button': './src/button.ts', + }, + dts: { + cwd: projectDir, + }, + }, + }); + + expect(tsConfig.compilerOptions.moduleResolution).toBe('bundler'); + + await compileTs(mapComponentsToExpose, tsConfig, remoteOptions); + + expect( + existsSync( + join( + projectDir, + 'dist/typesRemoteFolder/compiledTypesFolder/button.d.ts', + ), + ), + ).toBe(true); + expect( + existsSync( + join( + projectDir, + 'dist/typesRemoteFolder/compiledTypesFolder/dependency.d.ts', + ), + ), + ).toBe(true); + expect( + existsSync(join(projectDir, 'dist/typesRemoteFolder/button.d.ts')), + ).toBe(true); + expect( + existsSync( + join( + projectDir, + 'dist/typesRemoteFolder/compiledTypesFolder/unused.d.ts', + ), + ), + ).toBe(false); + }); + it('with additionalFilesToCompile', async () => { const filepath = join(__dirname, './typeScriptCompiler.ts'); @@ -546,6 +723,9 @@ describe('typeScriptCompiler', () => { { name: 'typeScriptCompiler.d.ts', }, + { + name: 'typeScriptResolver.d.ts', + }, { name: 'utils.d.ts', }, diff --git a/packages/dts-plugin/src/core/lib/typeScriptCompiler.ts b/packages/dts-plugin/src/core/lib/typeScriptCompiler.ts index 9127629e36c..f65ff46472a 100644 --- a/packages/dts-plugin/src/core/lib/typeScriptCompiler.ts +++ b/packages/dts-plugin/src/core/lib/typeScriptCompiler.ts @@ -21,6 +21,7 @@ import { TEMP_DIR } from '@module-federation/sdk'; import { RemoteOptions } from '../interfaces/RemoteOptions'; import { TsConfigJson } from '../interfaces/TsConfigJson'; import { logger } from '../../server'; +import { getTypeScriptPackageInfo } from './typeScriptResolver'; const STARTS_WITH_SLASH = /^\//; @@ -239,6 +240,49 @@ const formatCommandForDisplay = (executable: string, args: string[]) => { return [executable, ...args].map(formatArg).join(' '); }; +const getTypeScriptContext = (remoteOptions: Required) => { + const dtsOptions = remoteOptions.moduleFederationConfig.dts; + return typeof dtsOptions !== 'boolean' && dtsOptions?.cwd + ? dtsOptions.cwd + : remoteOptions.context; +}; + +const resolveCompilerCommand = ( + remoteOptions: Required, + tempTsConfigJsonPath: string, +) => { + const compilerArgs = splitCommandArgs(remoteOptions.compilerInstance); + const resolvedCompilerArgs = + compilerArgs.length > 0 ? compilerArgs : [remoteOptions.compilerInstance]; + + if (resolvedCompilerArgs[0] === 'tsc') { + const typeScriptPackageInfo = getTypeScriptPackageInfo( + getTypeScriptContext(remoteOptions), + ); + const args = [ + typeScriptPackageInfo.tscBinPath, + ...resolvedCompilerArgs.slice(1), + '--project', + tempTsConfigJsonPath, + ]; + return { + executable: process.execPath, + args, + displayCommand: formatCommandForDisplay(process.execPath, args), + shell: false, + }; + } + + const executable = resolvePackageManagerExecutable(); + const args = [...resolvedCompilerArgs, '--project', tempTsConfigJsonPath]; + return { + executable, + args, + displayCommand: formatCommandForDisplay(executable, args), + shell: process.platform === 'win32', + }; +}; + export const compileTs = async ( mapComponentsToExpose: Record, tsConfig: TsConfigJson, @@ -268,23 +312,14 @@ export const compileTs = async ( : undefined, }); const execPromise = util.promisify(execFile); - const pmExecutable = resolvePackageManagerExecutable(); - const compilerArgs = splitCommandArgs(remoteOptions.compilerInstance); - const resolvedCompilerArgs = - compilerArgs.length > 0 ? compilerArgs : [remoteOptions.compilerInstance]; - const cmdArgs = [ - ...resolvedCompilerArgs, - '--project', + const compilerCommand = resolveCompilerCommand( + remoteOptions, tempTsConfigJsonPath, - ]; - const cmd = formatCommandForDisplay(pmExecutable, cmdArgs); + ); try { - await execPromise(pmExecutable, cmdArgs, { - cwd: - typeof remoteOptions.moduleFederationConfig.dts !== 'boolean' - ? (remoteOptions.moduleFederationConfig.dts?.cwd ?? undefined) - : undefined, - shell: process.platform === 'win32', + await execPromise(compilerCommand.executable, compilerCommand.args, { + cwd: getTypeScriptContext(remoteOptions), + shell: compilerCommand.shell, }); } catch (err) { if (compilerOptions.tsBuildInfoFile) { @@ -297,7 +332,7 @@ export const compileTs = async ( logAndReport( TYPE_001, typeDescMap, - { cmd }, + { cmd: compilerCommand.displayCommand }, (msg) => { throw new Error(msg); }, diff --git a/packages/dts-plugin/src/core/lib/typeScriptResolver.ts b/packages/dts-plugin/src/core/lib/typeScriptResolver.ts new file mode 100644 index 00000000000..831f1bdad20 --- /dev/null +++ b/packages/dts-plugin/src/core/lib/typeScriptResolver.ts @@ -0,0 +1,98 @@ +import { createRequire } from 'module'; +import { dirname, resolve } from 'path'; + +interface TypeScriptPackageJson { + version?: string; + bin?: string | Record; +} + +interface ResolvedTypeScriptPackage { + packageJsonPath: string; + packageJson: TypeScriptPackageJson; + requireFromContext: NodeJS.Require; +} + +export interface TypeScriptPackageInfo { + packageJsonPath: string; + packageRoot: string; + version: string; + majorVersion: number; + tscBinPath: string; +} + +const parseMajorVersion = (version: string): number => { + const major = Number.parseInt(version.split('.')[0], 10); + return Number.isNaN(major) ? 0 : major; +}; + +const isMissingTypeScriptPackage = (error: unknown) => + typeof error === 'object' && + error !== null && + 'code' in error && + error.code === 'MODULE_NOT_FOUND' && + 'message' in error && + typeof error.message === 'string' && + error.message.includes('typescript/package.json'); + +const resolveTypeScriptPackage = ( + context = process.cwd(), +): ResolvedTypeScriptPackage => { + const candidateContexts = [...new Set([context, process.cwd()])]; + let missingTypeScriptError: unknown; + + for (const candidateContext of candidateContexts) { + const requireFromContext = createRequire( + resolve(candidateContext, 'package.json'), + ); + try { + const packageJsonPath = requireFromContext.resolve( + 'typescript/package.json', + ); + return { + packageJsonPath, + packageJson: requireFromContext( + 'typescript/package.json', + ) as TypeScriptPackageJson, + requireFromContext, + }; + } catch (error) { + if (!isMissingTypeScriptPackage(error)) { + throw error; + } + missingTypeScriptError = error; + } + } + + throw missingTypeScriptError; +}; + +export const getTypeScriptPackageInfo = ( + context = process.cwd(), +): TypeScriptPackageInfo => { + const { packageJsonPath, packageJson } = resolveTypeScriptPackage(context); + const version = packageJson.version || '0.0.0'; + const packageRoot = dirname(packageJsonPath); + const bin = + typeof packageJson.bin === 'string' + ? packageJson.bin + : (packageJson.bin?.['tsc'] ?? './bin/tsc'); + + return { + packageJsonPath, + packageRoot, + version, + majorVersion: parseMajorVersion(version), + tscBinPath: resolve(packageRoot, bin), + }; +}; + +export const getTypeScriptMajorVersion = (context = process.cwd()) => + getTypeScriptPackageInfo(context).majorVersion; + +export const isTypeScript7 = (context = process.cwd()) => + getTypeScriptMajorVersion(context) === 7; + +export const requireTypeScript = (context = process.cwd()): T => { + const { requireFromContext } = resolveTypeScriptPackage(context); + return requireFromContext('typescript') as T; +}; diff --git a/packages/dts-plugin/tsconfig.json b/packages/dts-plugin/tsconfig.json index d52044821a7..3d118b9d2c0 100644 --- a/packages/dts-plugin/tsconfig.json +++ b/packages/dts-plugin/tsconfig.json @@ -4,7 +4,6 @@ "sourceMap": false, "target": "es6", "module": "esnext", - "moduleResolution": "node10", "esModuleInterop": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, diff --git a/packages/enhanced/package.json b/packages/enhanced/package.json index 373b9a0d0d6..50a20300ab8 100644 --- a/packages/enhanced/package.json +++ b/packages/enhanced/package.json @@ -21,7 +21,7 @@ "access": "public" }, "peerDependencies": { - "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0", + "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vue-tsc": ">=1.0.24", "webpack": "^5.0.0" }, @@ -80,7 +80,7 @@ "fast-glob": "3.3.3", "memfs": "4.46.0", "terser": "^5.37.0", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "dependencies": { "@module-federation/webpack-bundler-runtime": "workspace:*", diff --git a/packages/enhanced/src/lib/Constants.d.ts b/packages/enhanced/src/lib/Constants.d.ts new file mode 100644 index 00000000000..5c529e1a053 --- /dev/null +++ b/packages/enhanced/src/lib/Constants.d.ts @@ -0,0 +1,117 @@ +/** + * @type {Readonly<"javascript/auto">} + */ +export declare const JAVASCRIPT_MODULE_TYPE_AUTO: Readonly<'javascript/auto'>; +/** + * @type {Readonly<"javascript/dynamic">} + */ +export declare const JAVASCRIPT_MODULE_TYPE_DYNAMIC: Readonly<'javascript/dynamic'>; +/** + * @type {Readonly<"javascript/esm">} + * This is the module type used for _strict_ ES Module syntax. This means that all legacy formats + * that webpack supports (CommonJS, AMD, SystemJS) are not supported. + */ +export declare const JAVASCRIPT_MODULE_TYPE_ESM: Readonly<'javascript/esm'>; +/** + * @type {Readonly<"json">} + * This is the module type used for JSON files. JSON files are always parsed as ES Module. + */ +export declare const JSON_MODULE_TYPE: Readonly<'json'>; +/** + * @type {Readonly<"webassembly/async">} + * This is the module type used for WebAssembly modules. In webpack 5 they are always treated as async modules. + * + */ +export declare const WEBASSEMBLY_MODULE_TYPE_ASYNC: Readonly<'webassembly/async'>; +/** + * @type {Readonly<"webassembly/sync">} + * This is the module type used for WebAssembly modules. In webpack 4 they are always treated as sync modules. + * There is a legacy option to support this usage in webpack 5 and up. + */ +export declare const WEBASSEMBLY_MODULE_TYPE_SYNC: Readonly<'webassembly/sync'>; +/** + * @type {Readonly<"css">} + * This is the module type used for CSS files. + */ +export declare const CSS_MODULE_TYPE: Readonly<'css'>; +/** + * @type {Readonly<"css/global">} + * This is the module type used for CSS modules files where you need to use `:local` in selector list to hash classes. + */ +export declare const CSS_MODULE_TYPE_GLOBAL: Readonly<'css/global'>; +/** + * @type {Readonly<"css/module">} + * This is the module type used for CSS modules files, by default all classes are hashed. + */ +export declare const CSS_MODULE_TYPE_MODULE: Readonly<'css/module'>; +/** + * @type {Readonly<"css/auto">} + * This is the module type used for CSS files, the module will be parsed as CSS modules if it's filename contains `.module.` or `.modules.`. + */ +export declare const CSS_MODULE_TYPE_AUTO: Readonly<'css/auto'>; +/** + * @type {Readonly<"asset">} + * This is the module type used for automatically choosing between `asset/inline`, `asset/resource` based on asset size limit (8096). + */ +export declare const ASSET_MODULE_TYPE: Readonly<'asset'>; +/** + * @type {Readonly<"asset/inline">} + * This is the module type used for assets that are inlined as a data URI. This is the equivalent of `url-loader`. + */ +export declare const ASSET_MODULE_TYPE_INLINE: Readonly<'asset/inline'>; +/** + * @type {Readonly<"asset/resource">} + * This is the module type used for assets that are copied to the output directory. This is the equivalent of `file-loader`. + */ +export declare const ASSET_MODULE_TYPE_RESOURCE: Readonly<'asset/resource'>; +/** + * @type {Readonly<"asset/source">} + * This is the module type used for assets that are imported as source code. This is the equivalent of `raw-loader`. + */ +export declare const ASSET_MODULE_TYPE_SOURCE: Readonly<'asset/source'>; +/** + * @type {Readonly<"asset/raw-data-url">} + * TODO: Document what this asset type is for. See css-loader tests for its usage. + */ +export declare const ASSET_MODULE_TYPE_RAW_DATA_URL: Readonly<'asset/raw-data-url'>; +/** + * @type {Readonly<"runtime">} + * This is the module type used for the webpack runtime abstractions. + */ +export declare const WEBPACK_MODULE_TYPE_RUNTIME: Readonly<'runtime'>; +/** + * @type {Readonly<"fallback-module">} + * This is the module type used for the ModuleFederation feature's FallbackModule class. + * TODO: Document this better. + */ +export declare const WEBPACK_MODULE_TYPE_FALLBACK: Readonly<'fallback-module'>; +/** + * @type {Readonly<"remote-module">} + * This is the module type used for the ModuleFederation feature's RemoteModule class. + * TODO: Document this better. + */ +export declare const WEBPACK_MODULE_TYPE_REMOTE: Readonly<'remote-module'>; +/** + * @type {Readonly<"provide-module">} + * This is the module type used for the ModuleFederation feature's ProvideModule class. + * TODO: Document this better. + */ +export declare const WEBPACK_MODULE_TYPE_PROVIDE: Readonly<'provide-module'>; +/** + * @type {Readonly<"consume-shared-module">} + * This is the module type used for the ModuleFederation feature's ConsumeSharedModule class. + */ +export declare const WEBPACK_MODULE_TYPE_CONSUME_SHARED_MODULE: Readonly<'consume-shared-module'>; +/** + * @type {Readonly<"lazy-compilation-proxy">} + * Module type used for `experiments.lazyCompilation` feature. See `LazyCompilationPlugin` for more information. + */ +export declare const WEBPACK_MODULE_TYPE_LAZY_COMPILATION_PROXY: Readonly<'lazy-compilation-proxy'>; +/** @typedef {"javascript/auto" | "javascript/dynamic" | "javascript/esm"} JavaScriptModuleTypes */ +/** @typedef {"json"} JSONModuleType */ +/** @typedef {"webassembly/async" | "webassembly/sync"} WebAssemblyModuleTypes */ +/** @typedef {"css" | "css/global" | "css/module"} CSSModuleTypes */ +/** @typedef {"asset" | "asset/inline" | "asset/resource" | "asset/source" | "asset/raw-data-url"} AssetModuleTypes */ +/** @typedef {"runtime" | "fallback-module" | "remote-module" | "provide-module" | "consume-shared-module" | "lazy-compilation-proxy"} WebpackModuleTypes */ +/** @typedef {string} UnknownModuleTypes */ +/** @typedef {JavaScriptModuleTypes | JSONModuleType | WebAssemblyModuleTypes | CSSModuleTypes | AssetModuleTypes | WebpackModuleTypes | UnknownModuleTypes} ModuleTypes */ diff --git a/packages/enhanced/src/lib/container/ContainerEntryModule.d.ts b/packages/enhanced/src/lib/container/ContainerEntryModule.d.ts new file mode 100644 index 00000000000..bea8cc919db --- /dev/null +++ b/packages/enhanced/src/lib/container/ContainerEntryModule.d.ts @@ -0,0 +1,111 @@ +import type { Compilation } from 'webpack'; +import type { + InputFileSystem, + LibIdentOptions, + NeedBuildContext, + ObjectDeserializerContext, + ObjectSerializerContext, + RequestShortener, + ResolverWithOptions, + WebpackOptions, +} from 'webpack/lib/Module'; +import type WebpackError from 'webpack/lib/WebpackError'; +declare const Module: typeof import('webpack').Module; +export type ExposeOptions = { + /** + * requests to exposed modules (last one is exported) + */ + import: string[]; + /** + * custom chunk name for the exposed module + */ + name: string; +}; +declare class ContainerEntryModule extends Module { + private _name; + private _exposes; + private _shareScope; + private _injectRuntimeEntry; + /** + * @param {string} name container entry name + * @param {[string, ExposeOptions][]} exposes list of exposed modules + * @param {string|string[]} shareScope name of the share scope + * @param {string} injectRuntimeEntry the path of injectRuntime file. + */ + constructor( + name: string, + exposes: [string, ExposeOptions][], + shareScope: string | string[], + injectRuntimeEntry: string, + ); + /** + * @param {ObjectDeserializerContext} context context + * @returns {ContainerEntryModule} deserialized container entry module + */ + static deserialize(context: ObjectDeserializerContext): ContainerEntryModule; + /** + * @returns {Set} types available (do not mutate) + */ + getSourceTypes(): Set; + /** + * @returns {string} a unique identifier of the module + */ + identifier(): string; + /** + * @param {RequestShortener} requestShortener the request shortener + * @returns {string} a user readable identifier of the module + */ + readableIdentifier(requestShortener: RequestShortener): string; + /** + * @param {LibIdentOptions} options options + * @returns {string | null} an identifier for library inclusion + */ + libIdent(options: LibIdentOptions): string | null; + /** + * @param {NeedBuildContext} context context info + * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild + * @returns {void} + */ + needBuild( + context: NeedBuildContext, + callback: ( + arg0: (WebpackError | null) | undefined, + arg1: boolean | undefined, + ) => void, + ): void; + /** + * @param {WebpackOptions} options webpack options + * @param {Compilation} compilation the compilation + * @param {ResolverWithOptions} resolver the resolver + * @param {InputFileSystem} fs the file system + * @param {function(WebpackError): void} callback callback function + * @returns {void} + */ + build( + options: WebpackOptions, + compilation: Compilation, + resolver: ResolverWithOptions, + fs: InputFileSystem, + callback: (err?: WebpackError) => void, + ): void; + /** + * @param {CodeGenerationContext} context context for code generation + * @returns {CodeGenerationResult} result + */ + codeGeneration({ moduleGraph, chunkGraph, runtimeTemplate }: any): { + sources: Map; + runtimeRequirements: Set< + '__webpack_exports__' | '__webpack_require__.d' | '__webpack_require__.o' + >; + }; + /** + * @param {string=} type the source type for which the size should be estimated + * @returns {number} the estimated size of the module (must be non-zero) + */ + size(type?: string): number; + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context: ObjectSerializerContext): void; +} +export default ContainerEntryModule; diff --git a/packages/enhanced/src/lib/container/ContainerExposedDependency.d.ts b/packages/enhanced/src/lib/container/ContainerExposedDependency.d.ts new file mode 100644 index 00000000000..7828986d74e --- /dev/null +++ b/packages/enhanced/src/lib/container/ContainerExposedDependency.d.ts @@ -0,0 +1,29 @@ +declare const dependencies: typeof import('webpack').dependencies; +import type { + ObjectDeserializerContext, + ObjectSerializerContext, +} from 'webpack/lib/dependencies/ModuleDependency'; +declare class ContainerExposedDependency extends dependencies.ModuleDependency { + exposedName: string; + request: string; + /** + * @param {string} exposedName public name + * @param {string} request request to module + */ + constructor(exposedName: string, request: string); + get type(): string; + get category(): string; + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier(): string | null; + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context: ObjectSerializerContext): void; + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context: ObjectDeserializerContext): void; +} +export default ContainerExposedDependency; diff --git a/packages/enhanced/src/lib/container/options.d.ts b/packages/enhanced/src/lib/container/options.d.ts new file mode 100644 index 00000000000..af571d4a17b --- /dev/null +++ b/packages/enhanced/src/lib/container/options.d.ts @@ -0,0 +1,26 @@ +export type ContainerOptionsFormat = + | (string | Record)[] + | Record; +/** + * @template T + * @template R + * @param {ContainerOptionsFormat} options options passed by the user + * @param {function(string | string[], string) : R} normalizeSimple normalize a simple item + * @param {function(T, string) : R} normalizeOptions normalize a complex item + * @returns {[string, R][]} parsed options + */ +export declare function parseOptions( + options: ContainerOptionsFormat, + normalizeSimple: (item: string | string[], name: string) => R, + normalizeOptions: (item: T, name: string) => R, +): [string, R][]; +/** + * @template T + * @param {string} scope scope name + * @param {ContainerOptionsFormat} options options passed by the user + * @returns {Record} options to spread or pass + */ +export declare function scope( + scope: string, + options: ContainerOptionsFormat, +): Record; diff --git a/packages/enhanced/src/lib/container/runtime/utils.d.ts b/packages/enhanced/src/lib/container/runtime/utils.d.ts new file mode 100644 index 00000000000..5943ec2272d --- /dev/null +++ b/packages/enhanced/src/lib/container/runtime/utils.d.ts @@ -0,0 +1,31 @@ +import type webpack from 'webpack'; +import type RuntimeGlobals from 'webpack/lib/RuntimeGlobals'; +import type { moduleFederationPlugin } from '@module-federation/sdk'; +import type { init } from '@module-federation/runtime-tools'; +type Remotes = Parameters[0]['remotes']; +export interface NormalizedRuntimeInitOptionsWithOutShared { + name: string; + remotes: Array< + Remotes[0] & { + externalType: moduleFederationPlugin.ExternalsType; + } + >; +} +type EntryStaticNormalized = Awaited< + ReturnType any>> +>; +interface ModifyEntryOptions { + compiler: webpack.Compiler; + prependEntry?: (entry: EntryStaticNormalized) => void; + staticEntry?: EntryStaticNormalized; +} +export declare function getFederationGlobalScope( + runtimeGlobals: typeof RuntimeGlobals, +): string; +export declare function normalizeRuntimeInitOptionsWithOutShared( + options: moduleFederationPlugin.ModuleFederationPluginOptions, +): NormalizedRuntimeInitOptionsWithOutShared; +export declare function modifyEntry(options: ModifyEntryOptions): void; +export declare function createHash(contents: string): string; +export declare const normalizeToPosixPath: (p: string) => string; +export {}; diff --git a/packages/enhanced/tsconfig.json b/packages/enhanced/tsconfig.json index 2c02fb951f5..8f70fcf7b6d 100644 --- a/packages/enhanced/tsconfig.json +++ b/packages/enhanced/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/enhanced/tsconfig.spec.json b/packages/enhanced/tsconfig.spec.json index b55e848de9d..5081ea87c51 100644 --- a/packages/enhanced/tsconfig.spec.json +++ b/packages/enhanced/tsconfig.spec.json @@ -5,10 +5,10 @@ "module": "commonjs", "types": ["@rstest/core/globals", "node"], "noEmit": true, - "baseUrl": ".", "paths": { "webpack": ["../../webpack/types.d.ts"], - "webpack/*": ["../../webpack/lib/*.d.ts", "../../webpack/*"] + "webpack/*": ["../../webpack/lib/*.d.ts", "../../webpack/*"], + "*": ["./*"] } }, "include": [ diff --git a/packages/error-codes/jest.config.js b/packages/error-codes/jest.config.js index 271f638474c..c9a0927767b 100644 --- a/packages/error-codes/jest.config.js +++ b/packages/error-codes/jest.config.js @@ -13,7 +13,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/error-codes/tsconfig.json b/packages/error-codes/tsconfig.json index d4b1d8152e6..dc0403bddf1 100644 --- a/packages/error-codes/tsconfig.json +++ b/packages/error-codes/tsconfig.json @@ -7,7 +7,6 @@ "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/esbuild/package.json b/packages/esbuild/package.json index 24c4c70c376..9d42de4054e 100644 --- a/packages/esbuild/package.json +++ b/packages/esbuild/package.json @@ -64,7 +64,7 @@ }, "devDependencies": { "@rslib/core": "^0.23.2", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "scripts": { "build": "rslib build", diff --git a/packages/managers/jest.config.js b/packages/managers/jest.config.js index 2d574a36a71..aa7de73a673 100644 --- a/packages/managers/jest.config.js +++ b/packages/managers/jest.config.js @@ -26,7 +26,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/managers/tsconfig.json b/packages/managers/tsconfig.json index 6c6b5569906..888e594cfbc 100644 --- a/packages/managers/tsconfig.json +++ b/packages/managers/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/manifest/jest.config.js b/packages/manifest/jest.config.js index 1a50a91f194..f5c733ac1a6 100644 --- a/packages/manifest/jest.config.js +++ b/packages/manifest/jest.config.js @@ -13,7 +13,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/manifest/package.json b/packages/manifest/package.json index b6b42e48299..679ef57f4e9 100644 --- a/packages/manifest/package.json +++ b/packages/manifest/package.json @@ -51,7 +51,7 @@ } }, "devDependencies": { - "typescript": "6.0.3", + "typescript": "7.0.2", "webpack": "^5.0.0" }, "scripts": { diff --git a/packages/manifest/tsconfig.json b/packages/manifest/tsconfig.json index 55d8f6e17ab..1ec99053b52 100644 --- a/packages/manifest/tsconfig.json +++ b/packages/manifest/tsconfig.json @@ -7,7 +7,6 @@ "noImplicitOverride": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/metro-core/tsconfig.json b/packages/metro-core/tsconfig.json index a58257592ff..a00e9cb01f5 100644 --- a/packages/metro-core/tsconfig.json +++ b/packages/metro-core/tsconfig.json @@ -5,7 +5,7 @@ "rootDir": "src", "jsx": "react-jsx", "paths": { - "metro/private/*": ["metro/src/*"] + "metro/private/*": ["./node_modules/metro/src/*"] } } } diff --git a/packages/metro-plugin-rnc-cli/package.json b/packages/metro-plugin-rnc-cli/package.json index 0f82136b608..48a888e82dc 100644 --- a/packages/metro-plugin-rnc-cli/package.json +++ b/packages/metro-plugin-rnc-cli/package.json @@ -35,7 +35,8 @@ "devDependencies": { "@module-federation/metro": "workspace:*", "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0" + "@typescript-eslint/parser": "8.54.0", + "typescript": "^6.0.3" }, "scripts": { "build": "echo 'No build needed for metro-plugin-rnc-cli - pure JavaScript package'", diff --git a/packages/modernjs-v3/package.json b/packages/modernjs-v3/package.json index 90611ab38de..d9e42a18fbe 100644 --- a/packages/modernjs-v3/package.json +++ b/packages/modernjs-v3/package.json @@ -162,17 +162,16 @@ "@modern-js/server-runtime": "3.5.0", "@modern-js/module-tools": "2.70.5", "@modern-js/runtime": "3.5.0", - "@modern-js/tsconfig": "3.5.0", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "react": "~18.3.1", "react-dom": "~18.3.1", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "peerDependencies": { "react": ">=17", "react-dom": ">=17", - "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0", + "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vue-tsc": "^1.0.24", "react-router-dom": "^4 || ^5 || ^6 || ^7", "react-router": "^7" diff --git a/packages/modernjs-v3/tsconfig.json b/packages/modernjs-v3/tsconfig.json index 03c994a49f0..5c318adb361 100644 --- a/packages/modernjs-v3/tsconfig.json +++ b/packages/modernjs-v3/tsconfig.json @@ -1,14 +1,27 @@ { - "extends": "@modern-js/tsconfig/base", + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Module Federation Modern.js", "compilerOptions": { + "target": "ES2015", + "lib": ["DOM", "ESNext"], + "allowJs": true, + "module": "ESNext", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, "declaration": false, "jsx": "preserve", - "baseUrl": "./", + "experimentalDecorators": true, + "resolveJsonModule": true, + "moduleResolution": "bundler", "rootDir": "./src", - "paths": {}, + "paths": { + "*": ["./*"] + }, "noImplicitAny": false, - "moduleResolution": "node10", "ignoreDeprecations": "6.0" }, - "include": ["src", "types", "global.d.ts"] + "include": ["src", "types", "global.d.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] } diff --git a/packages/modernjs/package.json b/packages/modernjs/package.json index 11b68c01e4e..d4f6ca8c3e6 100644 --- a/packages/modernjs/package.json +++ b/packages/modernjs/package.json @@ -156,21 +156,20 @@ "@rsbuild/plugin-react": "1.4.5", "@rstest/core": "^0.10.6", "@module-federation/manifest": "workspace:*", - "@rslib/core": "0.18.5", + "@rslib/core": "0.23.2", "@rsbuild/core": "1.3.21", "@modern-js/app-tools": "2.70.5", "@modern-js/server-runtime": "2.70.5", "@modern-js/module-tools": "2.70.5", "@modern-js/runtime": "2.70.5", - "@modern-js/tsconfig": "2.70.5", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "peerDependencies": { "react": ">=17", "react-dom": ">=17", - "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0", + "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vue-tsc": "^1.0.24", "react-router-dom": "^4 || ^5 || ^6 || ^7", "react-router": "^7" diff --git a/packages/modernjs/tsconfig.json b/packages/modernjs/tsconfig.json index 03c994a49f0..5c318adb361 100644 --- a/packages/modernjs/tsconfig.json +++ b/packages/modernjs/tsconfig.json @@ -1,14 +1,27 @@ { - "extends": "@modern-js/tsconfig/base", + "$schema": "https://json.schemastore.org/tsconfig", + "display": "Module Federation Modern.js", "compilerOptions": { + "target": "ES2015", + "lib": ["DOM", "ESNext"], + "allowJs": true, + "module": "ESNext", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, "declaration": false, "jsx": "preserve", - "baseUrl": "./", + "experimentalDecorators": true, + "resolveJsonModule": true, + "moduleResolution": "bundler", "rootDir": "./src", - "paths": {}, + "paths": { + "*": ["./*"] + }, "noImplicitAny": false, - "moduleResolution": "node10", "ignoreDeprecations": "6.0" }, - "include": ["src", "types", "global.d.ts"] + "include": ["src", "types", "global.d.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] } diff --git a/packages/nextjs-mf/jest.config.js b/packages/nextjs-mf/jest.config.js index a2da2ba1a3e..16cd7f4d162 100644 --- a/packages/nextjs-mf/jest.config.js +++ b/packages/nextjs-mf/jest.config.js @@ -5,12 +5,7 @@ module.exports = { globals: {}, testEnvironment: 'node', transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], + '^.+\\.[tj]sx?$': ['@swc/jest'], }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/packages/nextjs-mf', diff --git a/packages/nextjs-mf/package.json b/packages/nextjs-mf/package.json index b4e0d89049a..81cddc13f81 100644 --- a/packages/nextjs-mf/package.json +++ b/packages/nextjs-mf/package.json @@ -22,7 +22,7 @@ ], "scripts": { "postinstall": "echo \"Deprecation Notice: We intend to deprecate 'nextjs-mf'. Please see https://github.com/module-federation/core/issues/3153 for more details.\"", - "build": "tsdown --config tsdown.config.mts", + "build": "tsdown --config tsdown.config.mts && tsc -p tsconfig.lib.json && node ../../tools/scripts/copy-dts-to-dmts.mjs dist", "lint": "ESLINT_USE_FLAT_CONFIG=false pnpm exec eslint --ignore-pattern node_modules \"**/*.js\" \"**/*.ts\"", "test": "pnpm exec jest --config jest.config.js --passWithNoTests", "pre-release": "pnpm run test && pnpm run build && rm -f ./dist/package.json" @@ -77,7 +77,7 @@ "@types/react": "^18.3.1", "@types/react-dom": "^18.3.1", "tsdown": "0.20.3", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "peerDependencies": { "webpack": "^5.40.0", diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts index 3ce572676a4..912c352af48 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts @@ -219,6 +219,11 @@ export class NextFederationPlugin { const defaultShared = this._extraOptions.skipSharingNextInternals ? {} : retrieveDefaultShared(isServer); + const manifestOptions = + typeof this._options.manifest === 'object' && + this._options.manifest !== null + ? this._options.manifest + : {}; return { ...this._options, @@ -241,10 +246,10 @@ export class NextFederationPlugin { }, shared: { ...defaultShared, - ...this._options.shared, + ...(this._options.shared as Record), }, manifest: { - ...(this._options.manifest ?? {}), + ...manifestOptions, filePath: isServer ? '' : '/static/chunks', }, // nextjs project needs to add config.watchOptions = ['**/node_modules/**', '**/@mf-types/**'] to prevent loop types update diff --git a/packages/nextjs-mf/src/plugins/container/InvertedContainerRuntimeModule.ts b/packages/nextjs-mf/src/plugins/container/InvertedContainerRuntimeModule.ts index 1a223fe2c0d..89ef0602935 100644 --- a/packages/nextjs-mf/src/plugins/container/InvertedContainerRuntimeModule.ts +++ b/packages/nextjs-mf/src/plugins/container/InvertedContainerRuntimeModule.ts @@ -1,14 +1,25 @@ import { normalizeWebpackPath } from '@module-federation/sdk/normalize-webpack-path'; -import type ContainerEntryModule from '@module-federation/enhanced/src/lib/container/ContainerEntryModule'; const { RuntimeModule, Template, RuntimeGlobals } = require( normalizeWebpackPath('webpack'), -) as typeof import('webpack'); +) as typeof import('webpack') & { + RuntimeGlobals: Record; +}; interface InvertedContainerRuntimeModuleOptions { name?: string; containers: Set; // Adjust the type as necessary } +type ContainerEntryModule = NonNullable< + ReturnType +> & { + _name?: string; +}; + +type CompilationModuleGraph = { + getModule: (dependency: unknown) => unknown; +}; + class InvertedContainerRuntimeModule extends RuntimeModule { private options: InvertedContainerRuntimeModuleOptions; diff --git a/packages/nextjs-mf/tsconfig.json b/packages/nextjs-mf/tsconfig.json index 2c02fb951f5..8f70fcf7b6d 100644 --- a/packages/nextjs-mf/tsconfig.json +++ b/packages/nextjs-mf/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/nextjs-mf/tsconfig.lib.json b/packages/nextjs-mf/tsconfig.lib.json index a76f2ea3a7d..14a9e0dc193 100644 --- a/packages/nextjs-mf/tsconfig.lib.json +++ b/packages/nextjs-mf/tsconfig.lib.json @@ -1,7 +1,17 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "dist" + "outDir": "dist", + "rootDir": ".", + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false, + "strict": false, + "noPropertyAccessFromIndexSignature": false, + "paths": { + "@module-federation/enhanced/src/*": ["../enhanced/src/*"], + "*": ["./*"] + } }, "include": ["src/**/*.ts", "utils/**/*.ts", "*.ts"], "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] diff --git a/packages/nextjs-mf/tsdown.config.mts b/packages/nextjs-mf/tsdown.config.mts index 4a727da89d7..50739c7bb00 100644 --- a/packages/nextjs-mf/tsdown.config.mts +++ b/packages/nextjs-mf/tsdown.config.mts @@ -28,10 +28,7 @@ export default defineConfig([ 'react-dom', 'webpack', ], - dts: { - resolver: 'tsc', - eager: true, - }, + dts: false, copyLicense: true, unbundle: true, define: {}, diff --git a/packages/node/jest.config.js b/packages/node/jest.config.js index 60fad132bd9..158c92d7d24 100644 --- a/packages/node/jest.config.js +++ b/packages/node/jest.config.js @@ -5,12 +5,7 @@ module.exports = { globals: {}, testEnvironment: 'node', transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], + '^.+\\.[tj]sx?$': ['@swc/jest'], }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/packages/node', diff --git a/packages/node/package.json b/packages/node/package.json index 94e2a371cdb..1b1e2fb9ecd 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -124,7 +124,7 @@ } }, "devDependencies": { - "typescript": "6.0.3" + "typescript": "7.0.2" }, "scripts": { "build": "tsdown --config tsdown.config.mts", diff --git a/packages/node/src/__tests__/runtimePlugin.test.ts b/packages/node/src/__tests__/runtimePlugin.test.ts index 267c2486740..15a8477470f 100644 --- a/packages/node/src/__tests__/runtimePlugin.test.ts +++ b/packages/node/src/__tests__/runtimePlugin.test.ts @@ -18,7 +18,6 @@ import type { ModuleFederation, Federation, } from '@module-federation/runtime'; -import * as runtimePluginModule from '../runtimePlugin'; declare global { interface Global { @@ -275,9 +274,9 @@ describe('runtimePlugin', () => { runInThisContext: mockRunInThisContext, }; - require('vm').Script.mockImplementation(() => mockScript); + require('vm').Script.mockImplementationOnce(() => mockScript); - require('fs').readFile.mockImplementation( + require('fs').readFile.mockImplementationOnce( ( path: string, encoding: string, @@ -303,7 +302,7 @@ describe('runtimePlugin', () => { it('should handle readFile errors', () => { require('fs').existsSync.mockReturnValue(true); const readError = new Error('Read error'); - require('fs').readFile.mockImplementation( + require('fs').readFile.mockImplementationOnce( ( path: string, encoding: string, @@ -321,7 +320,7 @@ describe('runtimePlugin', () => { it('should handle script evaluation errors', () => { require('fs').existsSync.mockReturnValue(true); - require('fs').readFile.mockImplementation( + require('fs').readFile.mockImplementationOnce( ( path: string, encoding: string, @@ -333,7 +332,7 @@ describe('runtimePlugin', () => { // Mock Script to throw an error when constructed const evalError = new Error('Evaluation failed'); - require('vm').Script.mockImplementation(() => { + require('vm').Script.mockImplementationOnce(() => { throw evalError; }); @@ -427,13 +426,9 @@ describe('runtimePlugin', () => { }); it('should attach remote chunk context when execution fails', async () => { - const syntaxError = new SyntaxError('Unexpected token :'); (global.fetch as jest.Mock).mockResolvedValue({ text: jest.fn().mockResolvedValue('const broken = { foo: };'), }); - require('vm').Script.mockImplementationOnce(() => { - throw syntaxError; - }); const url = Object.assign(new URL('http://example.com/chunk.js'), { mfMetadata: { @@ -542,13 +537,14 @@ describe('runtimePlugin', () => { return new originalURL(args[0], args[1]); }) as any; - // Mock a complex remote entry URL with a path + // Use a complex remote entry URL with a path const mockEntryUrl = 'http://example.com/static/js/remoteEntry.js'; - jest - .spyOn(runtimePluginModule, 'returnFromCache') - .mockReturnValue(mockEntryUrl); + const originalEntry = mockModule.remoteInfo.entry; + mockModule.remoteInfo.entry = mockEntryUrl; // Set a rootDir for testing combined paths + const originalRootOutputDir = (global as any).__webpack_require__ + .federation.rootOutputDir; (global as any).__webpack_require__.federation.rootOutputDir = 'dist'; const result = resolveUrl('test-remote', 'chunk123.js'); @@ -560,6 +556,9 @@ describe('runtimePlugin', () => { // Restore the original URL constructor global.URL = originalURL; + mockModule.remoteInfo.entry = originalEntry; + (global as any).__webpack_require__.federation.rootOutputDir = + originalRootOutputDir; }); it('should return null when URL cannot be resolved', () => { @@ -569,13 +568,8 @@ describe('runtimePlugin', () => { throw new Error('Invalid URL'); }) as any; - // Mock returnFromCache and returnFromGlobalInstances to return null - const spyReturnFromCache = jest - .spyOn(runtimePluginModule, 'returnFromCache') - .mockReturnValue(null); - const spyReturnFromGlobalInstances = jest - .spyOn(runtimePluginModule, 'returnFromGlobalInstances') - .mockReturnValue(null); + const originalInstances = (global as any).__FEDERATION__.__INSTANCES__; + (global as any).__FEDERATION__.__INSTANCES__ = []; const result = resolveUrl('non-existent-remote', 'chunk.js'); @@ -583,8 +577,7 @@ describe('runtimePlugin', () => { // Clean up mocks global.URL = originalURL; - spyReturnFromCache.mockRestore(); - spyReturnFromGlobalInstances.mockRestore(); + (global as any).__FEDERATION__.__INSTANCES__ = originalInstances; }); it('should attach fallback resolution metadata to resolved urls', () => { @@ -624,7 +617,6 @@ describe('runtimePlugin', () => { }); it('should load a chunk from the filesystem', () => { - // Create a spy that will resolve successfully const mockCallback = jest.fn(); const mockChunk = { modules: { 'test-module': {} }, @@ -632,63 +624,76 @@ describe('runtimePlugin', () => { runtime: jest.fn(), }; - // Create a manual spy for loadFromFs that calls the callback with a successful result - jest - .spyOn(runtimePluginModule, 'loadFromFs') - .mockImplementation((path, callback) => callback(null, mockChunk)); + require('fs').existsSync.mockReturnValueOnce(true); + require('fs').readFile.mockImplementationOnce( + ( + path: string, + encoding: string, + callback: (error: Error | null, content?: string) => void, + ) => callback(null, '// mock chunk'), + ); + require('vm').Script.mockImplementationOnce(() => ({ + runInThisContext: jest.fn().mockReturnValue((exports: any) => { + Object.assign(exports, mockChunk); + }), + })); loadChunk('filesystem', 'test-chunk', '/dist', mockCallback, {}); - expect(runtimePluginModule.loadFromFs).toHaveBeenCalledWith( - expect.stringContaining('test-chunk'), - expect.any(Function), - ); - + expect(require('fs').readFile).toHaveBeenCalled(); expect(mockCallback).toHaveBeenCalledWith(null, mockChunk); }); - it('should fetch a chunk from a URL', () => { - const mockCallback = jest.fn(); + it('should fetch a chunk from a URL', async () => { const mockChunk = { modules: { 'test-module': {} }, ids: ['test-chunk'], - runtime: jest.fn(), + runtime: null, + }; + const originalPublicPath = (global as any).__webpack_require__.p; + (global as any).__webpack_require__.p = 'http://example.com/'; + (global.fetch as jest.Mock).mockResolvedValueOnce({ + text: jest + .fn() + .mockResolvedValue( + "exports.modules = {'test-module': {}}; exports.ids = ['test-chunk']; exports.runtime = null;", + ), + }); + const args = { + origin: { + options: { name: 'test-host' }, + loaderHook: { + lifecycle: { + fetch: { emit: jest.fn().mockResolvedValue(null) }, + }, + }, + }, }; - const mockFetchAndRun = jest - .spyOn(runtimePluginModule, 'fetchAndRun') - .mockImplementation((url, chunkId, callback, args) => - callback(null, mockChunk), + const result = await new Promise((resolve, reject) => { + loadChunk( + 'url', + 'test-chunk', + '/dist', + (error, chunk) => { + if (error) reject(error); + else resolve(chunk); + }, + args, ); + }); - // Create a proper URL object - const testUrl = new URL('http://example.com/chunk.js'); - const resolveUrlSpy = jest - .spyOn(runtimePluginModule, 'resolveUrl') - .mockReturnValue(testUrl); - - loadChunk('url', 'test-chunk', '/dist', mockCallback, {}); - - // Fix the parameter order to match the implementation: (remoteName, chunkName) - expect(resolveUrlSpy).toHaveBeenCalledWith('/dist', 'test-chunk'); - expect(mockFetchAndRun).toHaveBeenCalledWith( - testUrl, - 'test-chunk', - mockCallback, - {}, - ); - expect(mockCallback).toHaveBeenCalledWith(null, mockChunk); - - // Restore mocks - mockFetchAndRun.mockRestore(); - resolveUrlSpy.mockRestore(); + expect(result).toEqual(mockChunk); + (global as any).__webpack_require__.p = originalPublicPath; }); it('should handle unknown strategies', () => { const mockCallback = jest.fn(); - // Mock resolveUrl to return a URL to ensure we test the strategy branch - jest.spyOn(runtimePluginModule, 'resolveUrl').mockReturnValue(null); + const originalPublicPath = (global as any).__webpack_require__.p; + const originalInstances = (global as any).__FEDERATION__.__INSTANCES__; + (global as any).__webpack_require__.p = 'invalid'; + (global as any).__FEDERATION__.__INSTANCES__ = []; // The strategy 'unknown' isn't in the implementation, so it will default to the URL path // which requires resolveUrl to work, which we've mocked to return null @@ -700,6 +705,8 @@ describe('runtimePlugin', () => { ids: [], runtime: null, }); + (global as any).__webpack_require__.p = originalPublicPath; + (global as any).__FEDERATION__.__INSTANCES__ = originalInstances; }); }); @@ -820,25 +827,8 @@ describe('runtimePlugin', () => { }); it('should return a handler for chunk loading and reuse existing promises', () => { - // Setup mock for loadChunk - const mockChunk = { - modules: { 'test-module': {} }, - ids: ['test-chunk'], - runtime: jest.fn(), - }; - - jest - .spyOn(runtimePluginModule, 'loadChunk') - .mockImplementation((strategy, chunkId, root, callback, args) => { - callback(null, mockChunk); - }); - - jest - .spyOn(runtimePluginModule, 'installChunk') - .mockImplementation((chunk, installedChunks) => { - // Mock implementation that doesn't rely on iterating chunk.ids - installedChunks['test-chunk'] = 0; - }); + require('fs').existsSync.mockReturnValue(true); + require('fs').readFile.mockImplementationOnce(() => undefined); // Create a test environment const installedChunks: Record = {}; diff --git a/packages/node/tsconfig.json b/packages/node/tsconfig.json index af22a77b9e8..6a9426ae9d1 100644 --- a/packages/node/tsconfig.json +++ b/packages/node/tsconfig.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig.base.json", "compilerOptions": { "target": "ES2021", - "moduleResolution": "node10", "resolveJsonModule": true, "skipLibCheck": true, "skipDefaultLibCheck": true, diff --git a/packages/playground/package.json b/packages/playground/package.json index 22bf43445dd..136cba4ed31 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -12,14 +12,14 @@ "author": "2heal1 ", "exports": { ".": { - "types": "./dist/cjs/index.d.ts", + "types": "./dist/types/index.d.ts", "import": "./dist/esm/index.mjs", "require": "./dist/cjs/index.js" } }, "main": "./dist/cjs/index.js", "module": "./dist/esm/index.mjs", - "types": "./dist/cjs/index.d.ts", + "types": "./dist/types/index.d.ts", "files": [ "dist" ], @@ -30,7 +30,7 @@ "prebuild": "pnpm run sync:bridge-runtime", "dev": "rslib mf-dev", "start": "rsbuild dev", - "build": "rslib build", + "build": "tsc -p tsconfig.build.json && node scripts/write-dts-entry.mjs && rslib build", "pre-release": "pnpm run build" }, "dependencies": { @@ -38,7 +38,8 @@ "@module-federation/runtime": "workspace:*", "@monaco-editor/react": "4.7.0", "monaco-editor": "0.52.2", - "typescript": "6.0.3" + "typescript": "7.0.2", + "typescript-compiler": "npm:typescript@6.0.3" }, "devDependencies": { "@module-federation/rsbuild-plugin": "workspace:*", diff --git a/packages/playground/rslib.config.ts b/packages/playground/rslib.config.ts index 376eeca74bc..52d2eb95526 100644 --- a/packages/playground/rslib.config.ts +++ b/packages/playground/rslib.config.ts @@ -33,9 +33,7 @@ function isTypescriptDynamicRequireWarning(warning: unknown) { } const shared = { - dts: { - bundle: true, - }, + dts: false, source: { entry: { index: './src/component.ts', diff --git a/packages/playground/scripts/write-dts-entry.mjs b/packages/playground/scripts/write-dts-entry.mjs new file mode 100644 index 00000000000..bebd926ec61 --- /dev/null +++ b/packages/playground/scripts/write-dts-entry.mjs @@ -0,0 +1,7 @@ +import { mkdir, writeFile } from 'node:fs/promises'; + +await mkdir('dist/types', { recursive: true }); +await writeFile( + 'dist/types/index.d.ts', + "export * from './component';\nexport { default } from './component';\n", +); diff --git a/packages/playground/src/consumerCompiler.ts b/packages/playground/src/consumerCompiler.ts index e5b8ed407d7..5a9edd14a8f 100644 --- a/packages/playground/src/consumerCompiler.ts +++ b/packages/playground/src/consumerCompiler.ts @@ -1,4 +1,4 @@ -import ts from 'typescript'; +import * as ts from 'typescript-compiler'; import { BRIDGE_RUNTIME_FILES } from './generated/bridgeRuntimeFiles'; export type CompilePlaygroundParams = { diff --git a/packages/playground/tsconfig.build.json b/packages/playground/tsconfig.build.json new file mode 100644 index 00000000000..64769b34980 --- /dev/null +++ b/packages/playground/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "noEmit": false, + "outDir": "./dist/types", + "rootDir": "./src" + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/rsbuild-plugin/package.json b/packages/rsbuild-plugin/package.json index f6d66c64945..413b97d8879 100644 --- a/packages/rsbuild-plugin/package.json +++ b/packages/rsbuild-plugin/package.json @@ -57,7 +57,7 @@ "@rslib/core": "^0.23.2", "@rsbuild/core": "2.1.4", "@rstest/core": "^0.10.6", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "peerDependencies": { "@rsbuild/core": "^1.3.21 || ^2.0.0-0" diff --git a/packages/rsbuild-plugin/tsconfig.json b/packages/rsbuild-plugin/tsconfig.json index 4b06adc60d9..977deb076a6 100644 --- a/packages/rsbuild-plugin/tsconfig.json +++ b/packages/rsbuild-plugin/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { - "baseUrl": ".", "rootDir": "./", "outDir": "dist", "sourceMap": false, @@ -20,7 +19,8 @@ "declaration": true, "paths": { "@/*": ["./*"], - "@src/*": ["./src/*"] + "@src/*": ["./src/*"], + "*": ["./*"] } }, "include": ["src", "../../global.d.ts", "__tests__/**/*"], diff --git a/packages/rspack/jest.config.js b/packages/rspack/jest.config.js index a0e6674e3c6..907c9a12199 100644 --- a/packages/rspack/jest.config.js +++ b/packages/rspack/jest.config.js @@ -13,7 +13,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/rspack/package.json b/packages/rspack/package.json index 0a5606f1ce1..b2eac5ed11c 100644 --- a/packages/rspack/package.json +++ b/packages/rspack/package.json @@ -34,7 +34,7 @@ }, "devDependencies": { "@rspack/core": "^1.0.2", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "exports": { ".": { @@ -82,7 +82,7 @@ } }, "peerDependencies": { - "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0", + "typescript": "^4.9.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", "vue-tsc": ">=1.0.24", "@rspack/core": "^0.7.0 || ^1.0.0 || ^2.0.0-0" }, diff --git a/packages/rspack/src/index.ts b/packages/rspack/src/index.ts index d9b772f79a8..abc5efc8f20 100644 --- a/packages/rspack/src/index.ts +++ b/packages/rspack/src/index.ts @@ -1,4 +1,6 @@ export { ModuleFederationPlugin, PLUGIN_NAME } from './ModuleFederationPlugin'; import { container } from '@rspack/core'; -export const ContainerPlugin = container.ContainerPlugin; -export const ContainerReferencePlugin = container.ContainerReferencePlugin; +export const ContainerPlugin: typeof container.ContainerPlugin = + container.ContainerPlugin; +export const ContainerReferencePlugin: typeof container.ContainerReferencePlugin = + container.ContainerReferencePlugin; diff --git a/packages/rspack/tsconfig.json b/packages/rspack/tsconfig.json index 9d75d638cba..5549659621d 100644 --- a/packages/rspack/tsconfig.json +++ b/packages/rspack/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/rspress-plugin/package.json b/packages/rspress-plugin/package.json index 4c0dc7e4772..c7cca0d80fa 100644 --- a/packages/rspress-plugin/package.json +++ b/packages/rspress-plugin/package.json @@ -41,7 +41,7 @@ "@types/html-to-text": "^9.0.4", "@types/lodash-es": "^4.17.12", "@types/react": "^18.3.11", - "typescript": "6.0.3" + "typescript": "7.0.2" }, "dependencies": { "cheerio": "1.0.0-rc.12", diff --git a/packages/runtime-plugins/inject-external-runtime-core-plugin/tsconfig.json b/packages/runtime-plugins/inject-external-runtime-core-plugin/tsconfig.json index 8541f8de0a9..f27bedf7fc3 100644 --- a/packages/runtime-plugins/inject-external-runtime-core-plugin/tsconfig.json +++ b/packages/runtime-plugins/inject-external-runtime-core-plugin/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/sdk/jest.config.cjs b/packages/sdk/jest.config.cjs index 2d574a36a71..aa7de73a673 100644 --- a/packages/sdk/jest.config.cjs +++ b/packages/sdk/jest.config.cjs @@ -26,7 +26,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/sdk/tsconfig.json b/packages/sdk/tsconfig.json index 19eb5ac6ce6..b3d58da6f5f 100644 --- a/packages/sdk/tsconfig.json +++ b/packages/sdk/tsconfig.json @@ -8,7 +8,6 @@ "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/storybook-addon/jest.config.cjs b/packages/storybook-addon/jest.config.cjs new file mode 100644 index 00000000000..bb694f71b4d --- /dev/null +++ b/packages/storybook-addon/jest.config.cjs @@ -0,0 +1,34 @@ +/* eslint-disable */ +module.exports = { + displayName: 'storybook-addon', + preset: '../../jest.preset.js', + transform: { + '^.+\\.[tj]sx?$': [ + '@swc/jest', + { + jsc: { + parser: { + syntax: 'typescript', + tsx: true, + }, + transform: { + react: { + runtime: 'automatic', + }, + }, + target: 'es2022', + }, + module: { + type: 'commonjs', + }, + }, + ], + }, + moduleNameMapper: { + '^(\\.{1,2}/.*)\\.js$': '$1', + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], + coverageDirectory: '../../coverage/packages/storybook-addon', + // https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest + testEnvironment: 'jest-fixed-jsdom', +}; diff --git a/packages/storybook-addon/jest.config.ts b/packages/storybook-addon/jest.config.ts deleted file mode 100644 index 113a0a86c3e..00000000000 --- a/packages/storybook-addon/jest.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'storybook-addon', - preset: '../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '/tsconfig.spec.json', - }, - }, - transform: { - '^.+\\.[tj]s$': 'ts-jest', - }, - moduleNameMapper: { - '^(\\.{1,2}/.*)\\.js$': '$1', - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/packages/storybook-addon', - // https://mswjs.io/docs/migrations/1.x-to-2.x#requestresponsetextencoder-is-not-defined-jest - testEnvironment: 'jest-fixed-jsdom', -}; diff --git a/packages/storybook-addon/package.json b/packages/storybook-addon/package.json index 3f327b73c5b..26d0261c756 100644 --- a/packages/storybook-addon/package.json +++ b/packages/storybook-addon/package.json @@ -59,7 +59,7 @@ "@storybook/core": "^8.4.6", "@storybook/node-logger": "7.6.20", "jest-fixed-jsdom": "^0.0.9", - "typescript": "6.0.3", + "typescript": "7.0.2", "webpack": "5.104.1", "webpack-virtual-modules": "0.6.2" }, @@ -110,8 +110,8 @@ "scripts": { "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && pnpm -C . exec tsdown --config tsdown.config.ts && cp *.md dist", "lint": "ESLINT_USE_FLAT_CONFIG=false pnpm exec eslint --ignore-pattern node_modules \"**/*.ts\"", - "test": "pnpm exec jest --config jest.config.ts --passWithNoTests", - "test:ci": "pnpm exec jest --config jest.config.ts --passWithNoTests --ci --coverage", + "test": "pnpm exec jest --config jest.config.cjs --passWithNoTests", + "test:ci": "pnpm exec jest --config jest.config.cjs --passWithNoTests --ci --coverage", "pre-release": "pnpm run test && pnpm run build" } } diff --git a/packages/storybook-addon/src/utils/with-module-federation-enhanced-rsbuild.spec.ts b/packages/storybook-addon/src/utils/with-module-federation-enhanced-rsbuild.spec.ts index d4cac41b96b..abe5088f2a1 100644 --- a/packages/storybook-addon/src/utils/with-module-federation-enhanced-rsbuild.spec.ts +++ b/packages/storybook-addon/src/utils/with-module-federation-enhanced-rsbuild.spec.ts @@ -1,6 +1,6 @@ import { moduleFederationPlugin } from '@module-federation/sdk'; -class MockModuleFederationPlugin {} +function MockModuleFederationPlugin() {} jest.mock('@module-federation/enhanced/rspack', () => ({ ModuleFederationPlugin: MockModuleFederationPlugin, diff --git a/packages/third-party-dts-extractor/package.json b/packages/third-party-dts-extractor/package.json index 31efd00e979..33b41ffc463 100644 --- a/packages/third-party-dts-extractor/package.json +++ b/packages/third-party-dts-extractor/package.json @@ -40,10 +40,11 @@ "@types/node": "^20.19.5", "@types/react": "^18.3.11", "react": "^18", + "typescript": "7.0.2", "tsup": "7.3.0" }, "scripts": { - "build": "tsup --config tsup.config.ts --outDir dist && cp package.json dist && cp *.md dist", + "build": "tsup --config tsup.config.ts --outDir dist && tsc -p tsconfig.lib.json && cp package.json dist && cp *.md dist", "lint": "ESLINT_USE_FLAT_CONFIG=false pnpm exec eslint --ignore-pattern node_modules \"**/*.ts\"", "test": "pnpm exec rstest --passWithNoTests", "pre-release": "pnpm run test && pnpm run build" diff --git a/packages/third-party-dts-extractor/tsconfig.json b/packages/third-party-dts-extractor/tsconfig.json index 71976837bfd..b89ffbd9a21 100644 --- a/packages/third-party-dts-extractor/tsconfig.json +++ b/packages/third-party-dts-extractor/tsconfig.json @@ -3,7 +3,6 @@ "target": "es2017", "module": "esnext", "lib": ["esnext"], - "moduleResolution": "node10", "esModuleInterop": true, "resolveJsonModule": true, "types": ["node"], diff --git a/packages/third-party-dts-extractor/tsconfig.lib.json b/packages/third-party-dts-extractor/tsconfig.lib.json index cfe95b654b6..e3220e93d8e 100644 --- a/packages/third-party-dts-extractor/tsconfig.lib.json +++ b/packages/third-party-dts-extractor/tsconfig.lib.json @@ -1,12 +1,14 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "../../dist/out-tsc", + "outDir": "./dist", + "rootDir": "./src", "declaration": true, + "emitDeclarationOnly": true, "skipLibCheck": true, - "types": [] + "types": ["node"] }, - "include": ["**/*.ts"], + "include": ["src/**/*.ts"], "exclude": [ "rstest.config.mts", "**/*.spec.ts", diff --git a/packages/third-party-dts-extractor/tsup.config.ts b/packages/third-party-dts-extractor/tsup.config.ts index c2c3e311c12..14fa411aede 100644 --- a/packages/third-party-dts-extractor/tsup.config.ts +++ b/packages/third-party-dts-extractor/tsup.config.ts @@ -3,7 +3,7 @@ import { defineConfig } from 'tsup'; const shared = { entry: [join(__dirname, 'src', 'index.ts')], - dts: true, + dts: false, splitting: true, outDir: join('packages', 'third-party-dts-extractor', 'dist'), external: [join(__dirname, 'package.json')], diff --git a/packages/treeshake-frontend/tsconfig.adapter.json b/packages/treeshake-frontend/tsconfig.adapter.json index 7d42623395e..80be68d9754 100644 --- a/packages/treeshake-frontend/tsconfig.adapter.json +++ b/packages/treeshake-frontend/tsconfig.adapter.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "ES2020", "module": "CommonJS", - "moduleResolution": "node10", "lib": ["ES2020", "DOM"], "declaration": true, "outDir": "dist/adapter", diff --git a/packages/treeshake-server/package.json b/packages/treeshake-server/package.json index dc052c82c00..06f9da9ce36 100644 --- a/packages/treeshake-server/package.json +++ b/packages/treeshake-server/package.json @@ -51,7 +51,7 @@ "@vercel/nft": "^1.1.1", "pino-pretty": "^13.1.2", "ts-node": "^10.9.2", - "typescript": "^6.0.3" + "typescript": "7.0.2" }, "engines": { "node": ">=20.19.5", diff --git a/packages/treeshake-server/tsconfig.json b/packages/treeshake-server/tsconfig.json index 6c16b69740d..934a6884ec2 100644 --- a/packages/treeshake-server/tsconfig.json +++ b/packages/treeshake-server/tsconfig.json @@ -2,16 +2,15 @@ "compilerOptions": { "target": "ES2020", "module": "CommonJS", - "moduleResolution": "node10", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "resolveJsonModule": true, "types": ["node"], - "baseUrl": "./", "paths": { - "@/*": ["src/*"] + "@/*": ["./src/*"], + "*": ["./*"] }, "ignoreDeprecations": "6.0" }, diff --git a/packages/utilities/jest.config.ts b/packages/utilities/jest.config.ts index 097eb994c71..e45cc0ddc0e 100644 --- a/packages/utilities/jest.config.ts +++ b/packages/utilities/jest.config.ts @@ -4,12 +4,7 @@ export default { preset: '../../jest.preset.js', globals: {}, transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], + '^.+\\.[tj]sx?$': ['@swc/jest'], }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/packages/utils', diff --git a/packages/webpack-bundler-runtime/jest.config.cjs b/packages/webpack-bundler-runtime/jest.config.cjs index 3a1ad5072cb..3e0e45996af 100644 --- a/packages/webpack-bundler-runtime/jest.config.cjs +++ b/packages/webpack-bundler-runtime/jest.config.cjs @@ -26,7 +26,6 @@ module.exports = { __BROWSER__: false, __VERSION__: '"unknown"', }, - preset: 'ts-jest', transformIgnorePatterns: [ // Change MODULE_NAME_HERE to your module that isn't being compiled '/node_modules/', diff --git a/packages/webpack-bundler-runtime/tsconfig.json b/packages/webpack-bundler-runtime/tsconfig.json index d4b1d8152e6..dc0403bddf1 100644 --- a/packages/webpack-bundler-runtime/tsconfig.json +++ b/packages/webpack-bundler-runtime/tsconfig.json @@ -7,7 +7,6 @@ "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, "noFallthroughCasesInSwitch": true, - "moduleResolution": "node10", "resolveJsonModule": true, "esModuleInterop": true, "skipLibCheck": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 614ab185849..5f686e02965 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -629,8 +629,8 @@ importers: specifier: ^1.1.0 version: 1.2.2 typescript: - specifier: ^4.8.2 - version: 4.9.5 + specifier: 7.0.2 + version: 7.0.2 apps/manifest-demo/3009-webpack-provider: dependencies: @@ -1090,8 +1090,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1107,13 +1107,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1135,9 +1135,15 @@ importers: rimraf: specifier: ~3.0.2 version: 3.0.2 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modern-component-data-fetch/provider: dependencies: @@ -1145,8 +1151,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1162,13 +1168,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1190,9 +1196,15 @@ importers: rimraf: specifier: ~3.0.2 version: 3.0.2 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modern-component-data-fetch/provider-csr: devDependencies: @@ -1236,8 +1248,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1253,13 +1265,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1281,9 +1293,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modernjs-ssr/dynamic-remote: dependencies: @@ -1322,8 +1340,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1339,13 +1357,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1367,9 +1385,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modernjs-ssr/host: dependencies: @@ -1377,8 +1401,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1394,13 +1418,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1422,9 +1446,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modernjs-ssr/nested-remote: dependencies: @@ -1432,8 +1462,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1449,13 +1479,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1477,9 +1507,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modernjs-ssr/remote: dependencies: @@ -1487,8 +1523,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1504,13 +1540,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1532,9 +1568,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/modernjs-ssr/remote-new-version: dependencies: @@ -1542,8 +1584,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1559,13 +1601,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -1587,9 +1629,15 @@ importers: rimraf: specifier: ~6.0.1 version: 6.0.1 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/next-app-router/next-app-router-4000: dependencies: @@ -1635,10 +1683,10 @@ importers: devDependencies: '@tailwindcss/forms': specifier: 0.5.7 - version: 0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5))) + version: 0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))) '@tailwindcss/typography': specifier: 0.5.12 - version: 0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5))) + version: 0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))) '@types/ms': specifier: 0.7.34 version: 0.7.34 @@ -1662,7 +1710,7 @@ importers: version: 9.26.0(jiti@2.6.1) eslint-config-next: specifier: 16.0.10 - version: 16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + version: 16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) lint-staged: specifier: 15.2.2 version: 15.2.2 @@ -1677,10 +1725,10 @@ importers: version: 0.5.14(prettier@3.2.5) tailwindcss: specifier: 3.4.3 - version: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)) + version: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 7.0.2 + version: 7.0.2 apps/next-app-router/next-app-router-4001: dependencies: @@ -1726,10 +1774,10 @@ importers: devDependencies: '@tailwindcss/forms': specifier: 0.5.7 - version: 0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5))) + version: 0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))) '@tailwindcss/typography': specifier: 0.5.12 - version: 0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5))) + version: 0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))) '@types/ms': specifier: 0.7.34 version: 0.7.34 @@ -1753,7 +1801,7 @@ importers: version: 9.26.0(jiti@2.6.1) eslint-config-next: specifier: 16.0.10 - version: 16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + version: 16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) lint-staged: specifier: 15.2.2 version: 15.2.2 @@ -1768,10 +1816,10 @@ importers: version: 0.5.14(prettier@3.2.5) tailwindcss: specifier: 3.4.3 - version: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)) + version: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) typescript: - specifier: 5.4.5 - version: 5.4.5 + specifier: 7.0.2 + version: 7.0.2 apps/node-dynamic-remote: dependencies: @@ -1832,7 +1880,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) apps/react-ts-host: dependencies: @@ -1867,6 +1915,9 @@ importers: react-refresh: specifier: 0.14.2 version: 0.14.2 + typescript: + specifier: 7.0.2 + version: 7.0.2 apps/react-ts-nested-remote: dependencies: @@ -1892,6 +1943,9 @@ importers: react-refresh: specifier: 0.14.2 version: 0.14.2 + typescript: + specifier: 7.0.2 + version: 7.0.2 apps/react-ts-remote: dependencies: @@ -1917,6 +1971,9 @@ importers: react-refresh: specifier: 0.14.2 version: 0.14.2 + typescript: + specifier: 7.0.2 + version: 7.0.2 apps/reactRemoteUI: dependencies: @@ -2058,10 +2115,10 @@ importers: version: 18.3.7(@types/react@18.3.28) tailwindcss: specifier: ^3.4.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-host-vue3-2100: dependencies: @@ -2073,10 +2130,10 @@ importers: version: link:../../../packages/enhanced vue: specifier: ^3.4.19 - version: 3.5.30(typescript@5.9.3) + version: 3.5.30(typescript@7.0.2) vue-router: specifier: ^4.4.5 - version: 4.4.5(vue@3.5.30(typescript@5.9.3)) + version: 4.4.5(vue@3.5.30(typescript@7.0.2)) devDependencies: '@module-federation/rsbuild-plugin': specifier: workspace:* @@ -2086,13 +2143,13 @@ importers: version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) '@rsbuild/plugin-vue': specifier: ^2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.9.3)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) tailwindcss: specifier: ^3.4.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) typescript: - specifier: ^5.4.2 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-remote1-2001: dependencies: @@ -2140,8 +2197,8 @@ importers: specifier: ^5.3.3 version: 5.3.3 typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-remote2-2002: dependencies: @@ -2180,8 +2237,8 @@ importers: specifier: ^18.3.0 version: 18.3.7(@types/react@18.3.28) typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-remote3-2003: dependencies: @@ -2193,29 +2250,29 @@ importers: version: link:../../../packages/rsbuild-plugin vue: specifier: ^3.4.19 - version: 3.5.30(typescript@5.9.3) + version: 3.5.30(typescript@7.0.2) vue-router: specifier: ^4.4.5 - version: 4.4.5(vue@3.5.30(typescript@5.9.3)) + version: 4.4.5(vue@3.5.30(typescript@7.0.2)) devDependencies: '@rsbuild/core': specifier: 2.1.4 version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) '@rsbuild/plugin-vue': specifier: ^2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.9.3)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) '@vue/tsconfig': specifier: ^0.5.1 version: 0.5.1 tailwindcss: specifier: ^3.4.3 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) typescript: - specifier: ^5.4.2 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 vue-tsc: specifier: ^2.0.26 - version: 2.2.12(typescript@5.9.3) + version: 2.2.12(typescript@7.0.2) apps/router-demo/router-remote4-2004: dependencies: @@ -2254,8 +2311,8 @@ importers: specifier: ^18.3.0 version: 18.3.7(@types/react@18.3.28) typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-remote5-2005: dependencies: @@ -2294,8 +2351,8 @@ importers: specifier: ^19.0.0 version: 19.2.3(@types/react@19.2.14) typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/router-demo/router-remote6-2006: dependencies: @@ -2337,8 +2394,8 @@ importers: specifier: ^18.3.0 version: 18.3.7(@types/react@18.3.28) typescript: - specifier: ^5.4.5 - version: 5.9.3 + specifier: 7.0.2 + version: 7.0.2 apps/rslib-module: devDependencies: @@ -2356,7 +2413,7 @@ importers: version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@types/react': specifier: ^18.3.11 version: 18.3.28 @@ -2374,10 +2431,10 @@ importers: version: 8.6.17(prettier@3.8.1) storybook-addon-rslib: specifier: ^1.0.1 - version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3))(typescript@6.0.3) + version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2) storybook-react-rsbuild: specifier: ^1.0.1 - version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) + version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) apps/runtime-demo/3005-runtime-host: dependencies: @@ -2518,8 +2575,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/enhanced': specifier: workspace:* version: link:../../../../packages/enhanced @@ -2535,10 +2592,10 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/plugin-server': specifier: 2.68.0 version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2570,14 +2627,17 @@ importers: specifier: ~3.0.2 version: 3.0.2 ts-node: - specifier: ~10.8.1 - version: 10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: specifier: ~3.14.1 version: 3.14.2 typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/shared-tree-shaking/no-server/provider: dependencies: @@ -2585,8 +2645,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/enhanced': specifier: workspace:* version: link:../../../../packages/enhanced @@ -2602,13 +2662,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2636,9 +2696,15 @@ importers: serve: specifier: 14.2.5 version: 14.2.5 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/shared-tree-shaking/with-server/host: dependencies: @@ -2646,8 +2712,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../../packages/modernjs-v3 @@ -2663,13 +2729,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2704,14 +2770,17 @@ importers: specifier: 14.2.5 version: 14.2.5 ts-node: - specifier: ~10.8.1 - version: 10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: specifier: ~3.14.1 version: 3.14.2 typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/shared-tree-shaking/with-server/provider: dependencies: @@ -2719,8 +2788,8 @@ importers: specifier: 7.28.2 version: 7.28.2 '@modern-js/runtime': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../../packages/modernjs-v3 @@ -2736,13 +2805,13 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': - specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + specifier: 3.5.0 + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@5.0.4) + version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2767,9 +2836,15 @@ importers: rimraf: specifier: ~3.0.2 version: 3.0.2 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ~5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 apps/website-new: dependencies: @@ -2802,7 +2877,7 @@ importers: version: 7.15.1(react-dom@19.1.1(react@19.1.1))(react@19.1.1) tailwindcss: specifier: ^3.2.7 - version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)) + version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) xgplayer: specifier: ^3.0.16 version: 3.0.23(core-js@3.49.0) @@ -2883,10 +2958,10 @@ importers: version: 4.7.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)) '@vitejs/plugin-vue': specifier: ^5.0.4 - version: 5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) '@vitejs/plugin-vue-jsx': specifier: ^4.0.0 - version: 4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) hono: specifier: 4.12.26 version: 4.12.26 @@ -2906,14 +2981,11 @@ importers: specifier: 6.30.3 version: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 vite: specifier: ^5.4.21 version: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vite-plugin-dts: - specifier: ^4.3.0 - version: 4.5.4(@types/node@26.1.0)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)) packages/bridge/bridge-react-webpack-plugin: dependencies: @@ -2928,14 +3000,11 @@ importers: version: 7.6.3 devDependencies: typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 vite: specifier: ^5.4.21 version: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vite-plugin-dts: - specifier: ^4.3.0 - version: 4.5.4(@types/node@26.1.0)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)) packages/bridge/bridge-shared: devDependencies: @@ -2947,22 +3016,19 @@ importers: version: 18.3.28 '@vitejs/plugin-vue': specifier: ^5.0.4 - version: 5.2.4(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 5.2.4(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) '@vitejs/plugin-vue-jsx': specifier: ^4.0.0 - version: 4.2.0(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 4.2.0(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 vite: specifier: ^5.4.21 version: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vite-plugin-dts: - specifier: ^4.3.0 - version: 4.5.4(@types/node@20.19.5)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)) vue-tsc: specifier: ^2.0.6 - version: 2.2.12(typescript@6.0.3) + version: 2.2.12(typescript@7.0.2) packages/bridge/vue3-bridge: dependencies: @@ -2987,28 +3053,25 @@ importers: version: 18.3.28 '@vitejs/plugin-vue': specifier: ^5.0.4 - version: 5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) '@vitejs/plugin-vue-jsx': specifier: ^4.0.0 - version: 4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3)) + version: 4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 vite: specifier: ^5.4.21 version: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vite-plugin-dts: - specifier: ^4.5.4 - version: 4.5.4(@types/node@26.1.0)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)) vue: specifier: ^3.5.30 - version: 3.5.30(typescript@6.0.3) + version: 3.5.30(typescript@7.0.2) vue-router: specifier: 4.4.5 - version: 4.4.5(vue@3.5.30(typescript@6.0.3)) + version: 4.4.5(vue@3.5.30(typescript@7.0.2)) vue-tsc: specifier: ^2.2.12 - version: 2.2.12(typescript@6.0.3) + version: 2.2.12(typescript@7.0.2) packages/chrome-devtools: dependencies: @@ -3051,19 +3114,19 @@ importers: devDependencies: '@modern-js-app/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@6.0.3) + version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 2.70.8 - version: 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.41(@swc/helpers@0.5.19))(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) + version: 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.41(@swc/helpers@0.5.19))(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) '@modern-js/eslint-config': specifier: 2.59.0 - version: 2.59.0(typescript@6.0.3) + version: 2.59.0(typescript@7.0.2) '@modern-js/module-tools': specifier: 2.70.8 - version: 2.70.8(@types/node@20.19.5)(typescript@6.0.3) + version: 2.70.8(@types/node@20.19.5)(typescript@7.0.2) '@modern-js/storybook': specifier: 2.70.8 - version: 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) + version: 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) '@modern-js/tsconfig': specifier: 2.70.8 version: 2.70.8 @@ -3104,8 +3167,8 @@ importers: specifier: ~6.0.1 version: 6.0.1 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 vitest: specifier: 1.2.2 version: 1.2.2(@edge-runtime/vm@3.2.0)(@types/node@20.19.5)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) @@ -3129,8 +3192,8 @@ importers: specifier: ^20.19.5 version: 20.19.5 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/core: dependencies: @@ -3161,7 +3224,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@types/glob': specifier: 7.2.0 version: 7.2.0 @@ -3226,6 +3289,9 @@ importers: typescript: specifier: 6.0.3 version: 6.0.3 + typescript-7: + specifier: npm:typescript@7.0.2 + version: typescript@7.0.2 vue: specifier: ^3.5.13 version: 3.5.30(typescript@6.0.3) @@ -3282,7 +3348,7 @@ importers: version: 2.0.1 vue-tsc: specifier: '>=1.0.24' - version: 2.2.12(typescript@6.0.3) + version: 2.2.12(typescript@7.0.2) webpack: specifier: ^5.0.0 version: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) @@ -3303,8 +3369,8 @@ importers: specifier: ^5.37.0 version: 5.46.1 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/error-codes: {} @@ -3346,10 +3412,10 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/managers: dependencies: @@ -3377,8 +3443,8 @@ importers: version: link:../sdk devDependencies: typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 webpack: specifier: ^5.0.0 version: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) @@ -3458,6 +3524,9 @@ importers: '@typescript-eslint/parser': specifier: 8.54.0 version: 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + typescript: + specifier: ^6.0.3 + version: 6.0.3 packages/metro-plugin-rnef: devDependencies: @@ -3568,23 +3637,20 @@ importers: version: 6.30.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7) vue-tsc: specifier: ^1.0.24 - version: 1.8.27(typescript@6.0.3) + version: 1.8.27(typescript@7.0.2) devDependencies: '@modern-js/app-tools': specifier: 2.70.5 - version: 2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(@swc/core@1.15.41(@swc/helpers@0.5.17))(encoding@0.1.13)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) + version: 2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(@swc/core@1.15.41(@swc/helpers@0.5.17))(encoding@0.1.13)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) '@modern-js/module-tools': specifier: 2.70.5 - version: 2.70.5(@types/node@26.1.0)(typescript@6.0.3) + version: 2.70.5(@types/node@26.1.0)(typescript@7.0.2) '@modern-js/runtime': specifier: 2.70.5 version: 2.70.5(react-dom@19.2.7(react@19.2.7))(react-server-dom-webpack@19.2.4(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(react@19.2.7) '@modern-js/server-runtime': specifier: 2.70.5 version: 2.70.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@modern-js/tsconfig': - specifier: 2.70.5 - version: 2.70.5 '@module-federation/manifest': specifier: workspace:* version: link:../manifest @@ -3595,8 +3661,8 @@ importers: specifier: 1.4.5 version: 1.4.5(@rsbuild/core@1.3.21)(webpack-hot-middleware@2.26.1) '@rslib/core': - specifier: 0.18.5 - version: 0.18.5(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(typescript@6.0.3) + specifier: 0.23.2 + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@rstest/core': specifier: ^0.10.6 version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) @@ -3607,8 +3673,8 @@ importers: specifier: ^18.3.0 version: 18.3.7(@types/react@18.3.28) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/modernjs-v3: dependencies: @@ -3656,23 +3722,20 @@ importers: version: 6.30.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) vue-tsc: specifier: ^1.0.24 - version: 1.8.27(typescript@6.0.3) + version: 1.8.27(typescript@7.0.2) devDependencies: '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) '@modern-js/module-tools': specifier: 2.70.5 - version: 2.70.5(@types/node@26.1.0)(typescript@6.0.3) + version: 2.70.5(@types/node@26.1.0)(typescript@7.0.2) '@modern-js/runtime': specifier: 3.5.0 version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@modern-js/server-runtime': specifier: 3.5.0 version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/tsconfig': - specifier: 3.5.0 - version: 3.5.0 '@module-federation/manifest': specifier: workspace:* version: link:../manifest @@ -3684,7 +3747,7 @@ importers: version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: 0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@rspack/core': specifier: 2.0.6 version: 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) @@ -3704,8 +3767,8 @@ importers: specifier: ~18.3.1 version: 18.3.1(react@18.3.1) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/native-federation-tests: dependencies: @@ -3825,10 +3888,10 @@ importers: version: 18.3.7(@types/react@18.3.28) tsdown: specifier: 0.20.3 - version: 0.20.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(publint@0.3.18)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + version: 0.20.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(publint@0.3.18)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@6.0.3)) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/node: dependencies: @@ -3855,8 +3918,8 @@ importers: version: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) devDependencies: typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/observability-plugin: dependencies: @@ -3883,8 +3946,11 @@ importers: specifier: 0.52.2 version: 0.52.2 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 + typescript-compiler: + specifier: npm:typescript@6.0.3 + version: typescript@6.0.3 devDependencies: '@module-federation/rsbuild-plugin': specifier: workspace:* @@ -3897,7 +3963,7 @@ importers: version: 1.4.5(@rsbuild/core@1.7.3)(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: ^0.12.4 - version: 0.12.4(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(typescript@6.0.3) + version: 0.12.4(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(typescript@7.0.2) '@types/node': specifier: ^20.19.5 version: 20.19.5 @@ -3941,13 +4007,13 @@ importers: version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@rstest/core': specifier: ^0.10.6 version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/rspack: dependencies: @@ -3974,14 +4040,14 @@ importers: version: link:../sdk vue-tsc: specifier: '>=1.0.24' - version: 2.2.12(typescript@6.0.3) + version: 2.2.12(typescript@7.0.2) devDependencies: '@rspack/core': specifier: ^1.0.2 version: 1.3.9(@swc/helpers@0.5.23) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/rspress-plugin: dependencies: @@ -4012,7 +4078,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) '@rspress/core': specifier: 2.0.14 version: 2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@18.3.28)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) @@ -4026,8 +4092,8 @@ importers: specifier: ^18.3.11 version: 18.3.28 typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/runtime: dependencies: @@ -4084,10 +4150,10 @@ importers: version: link:../sdk '@nx/react': specifier: '>= 16.0.0' - version: 22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(esbuild@0.25.5)(eslint@9.39.3(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@6.0.3))(webpack-cli@5.1.4) + version: 22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(esbuild@0.25.5)(eslint@9.39.3(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4) '@nx/webpack': specifier: '>= 16.0.0' - version: 22.5.4(@babel/traverse@7.29.7)(@rspack/core@1.6.8(@swc/helpers@0.5.23))(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vue-template-compiler@2.7.16)(webpack-cli@5.1.4) + version: 22.5.4(@babel/traverse@7.29.7)(@rspack/core@1.6.8(@swc/helpers@0.5.23))(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vue-template-compiler@2.7.16)(webpack-cli@5.1.4) storybook: specifier: '>= 8.2.0' version: 8.6.17(prettier@3.8.1) @@ -4097,10 +4163,10 @@ importers: version: link:../utilities '@nx/module-federation': specifier: '>= 16.0.0' - version: 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack-cli@5.1.4) + version: 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4) '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@0.21.6)(core-js@3.49.0) '@storybook/core': specifier: ^8.4.6 version: 8.6.14(prettier@3.8.1)(storybook@8.6.17(prettier@3.8.1)) @@ -4111,8 +4177,8 @@ importers: specifier: ^0.0.9 version: 0.0.9(jest-environment-jsdom@29.7.0) typescript: - specifier: 6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 webpack: specifier: 5.104.1 version: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) @@ -4143,7 +4209,10 @@ importers: version: 18.3.1 tsup: specifier: 7.3.0 - version: 7.3.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3))(typescript@6.0.3) + version: 7.3.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(typescript@7.0.2) + typescript: + specifier: 7.0.2 + version: 7.0.2 packages/treeshake-frontend: dependencies: @@ -4421,10 +4490,10 @@ importers: version: 13.1.3 ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3) + version: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) typescript: - specifier: ^6.0.3 - version: 6.0.3 + specifier: 7.0.2 + version: 7.0.2 packages/typescript: dependencies: @@ -7965,19 +8034,6 @@ packages: tsconfig-paths: optional: true - '@modern-js/app-tools@3.0.1': - resolution: {integrity: sha512-xgib0+2kkm9Kx7iVl8SuAa8izSYWWyVrArZ1t53NKfqWQm2cQZf5nf9+MAVSsRoG9Hleob9nUK8/pM4rAAPSyA==} - engines: {node: '>=20'} - hasBin: true - peerDependencies: - ts-node: ^10.9.2 - tsconfig-paths: ^4.2.0 - peerDependenciesMeta: - ts-node: - optional: true - tsconfig-paths: - optional: true - '@modern-js/app-tools@3.5.0': resolution: {integrity: sha512-Ng7+8zUwa5+QUEYtJUVg0tLPlqq/CFyfTgFy6OgQ8LWhcu1bLPY0SB/C2HEkUTYl6eaIpilZ0fUiYThsTX2yDg==} engines: {node: '>=20'} @@ -8021,9 +8077,6 @@ packages: '@modern-js/babel-preset@2.70.8': resolution: {integrity: sha512-duxCARvviTlKSGbc2FuO/M+lDa16tLXblO51AYHVgzsdWwf+/Qwpou73OCRCrb2NcHLJ4RonWIbcqVscGEoV2w==} - '@modern-js/builder@3.0.1': - resolution: {integrity: sha512-5hSa5zi4tmD2rQ8tqaj03ROBf1eRgZGH1oKNG+4flwerMgp8qlVkXfmJmxG7PO2JuphhObA8/GFNEPVD0ey9uw==} - '@modern-js/builder@3.5.0': resolution: {integrity: sha512-jEs1V11oGYINY8Z1CQjb2AxB410rDbTHRbsA+ou9EPss0Zh6mzB1quWVHh2kmkb3yPL4BSALIoKZG1tw8p1zHA==} @@ -8042,12 +8095,6 @@ packages: '@modern-js/flight-server-transform-plugin@2.70.8': resolution: {integrity: sha512-f5XC6kaWB0BU2Lt/CptYiFDXeQGl9LEJy97QO0eabdRS2ibwpkE0Hd3gpzMAzqGI/llOeV3S1wafxGJYOqVdrQ==} - '@modern-js/flight-server-transform-plugin@3.0.1': - resolution: {integrity: sha512-KPGekiKpMm6mMjR3xEULH3wGWfA72wIpBJuHPCDW/I3umU2dghOpPxkGL3LyMcHCTuCKds3VJGsJGbAWf8fwWg==} - - '@modern-js/i18n-utils@3.0.1': - resolution: {integrity: sha512-hmdFk6Zi3Pe+gtnjvuRbXa960brmZtaQCDWvSw7Kndfadrhqd6AOFMzHYRPeKDbB/4sllytswWXvhnexJg0gJg==} - '@modern-js/i18n-utils@3.5.0': resolution: {integrity: sha512-fPvJ8NZ7YxrEGqpkaEYgnHH5vEUotUQhnZWvQrnIpX8ZC9t65xR5BOArpqs/qgSotx+X9kLxsF2TnZg20l12xw==} @@ -8095,12 +8142,6 @@ packages: peerDependencies: react: '>=17.0.0' - '@modern-js/plugin-data-loader@3.0.1': - resolution: {integrity: sha512-WGqsuVWOm6xbG+zM6KNTz1OvmluhfurtqHkoH+QLEmn5kUwMkzuXuqHyWM2ZKjngjgpB/bPhEp98DUEFvep8eA==} - engines: {node: '>=20'} - peerDependencies: - react: '>=17.0.2' - '@modern-js/plugin-data-loader@3.5.0': resolution: {integrity: sha512-RUnBERamzt0IBLYMOhLCdnIkLD3+zzPbxFrTtGllgcww8XSx5FwNGvcMuMh1xXNx46wwIzyZUoiyDOJ+yIDTpA==} engines: {node: '>=20'} @@ -8149,10 +8190,6 @@ packages: resolution: {integrity: sha512-EgYyjIe4MRAIs7CNd8qCtQrpTC9WbrSrai9Fu9IiGniItshVQmp+d07joPiIoAob9Xd8UhGPt7KBW3pUcGLpEg==} engines: {node: '>=16.2.0'} - '@modern-js/prod-server@3.0.1': - resolution: {integrity: sha512-bKPi2LD3b2usU0cwIBLODyiONykq+f76LLv3+Sk4PI+K7PlMO5RjlJT4YmHzsWKXhUNRigqNZFoBV9V7rELmhw==} - engines: {node: '>=20'} - '@modern-js/prod-server@3.5.0': resolution: {integrity: sha512-g/3/dMtckJHfXjNuFMKEhtlTL1cYXX7kwaSWcbCmbMJ6S+984X2iJ2X7TAUo1s/Yd+TOSuMp8FBCPkEMesQETg==} engines: {node: '>=20'} @@ -8171,13 +8208,6 @@ packages: react-dom: '>=17.0.0' react-server-dom-webpack: ^19.2.4 - '@modern-js/render@3.0.1': - resolution: {integrity: sha512-0PETtP5NuqFWuEc5IMSz6fYF7OMCwbIi5hG0SSToqQdVQUVJIxxi+Of7cCbiY4RqKGN9u/Fijz88DSDF8Lp4kw==} - peerDependencies: - react: '>=17.0.2' - react-dom: '>=17.0.2' - react-server-dom-webpack: ^19.2.3 - '@modern-js/render@3.5.0': resolution: {integrity: sha512-qqVN+NVsLSGx+RrKu8lhr9oT5hw3l1rBT6L7f0VWWdrA52JTX72TI34ySvrNOCe1KjqZvtID6i9gAlSNAb0Wfg==} peerDependencies: @@ -8260,13 +8290,6 @@ packages: react: '>=17' react-dom: '>=17' - '@modern-js/runtime@3.0.1': - resolution: {integrity: sha512-/6Hj1x2ynK9e/abmLgle7GbPHZgJ4+eMfRPp469Nnj9dnqul4IE8Q/z/qVlSR4G9v9J+YUyCXxSpAh6UgaMP9w==} - engines: {node: '>=20'} - peerDependencies: - react: '>=17.0.2' - react-dom: '>=17.0.2' - '@modern-js/runtime@3.5.0': resolution: {integrity: sha512-Yb7LqJWmTLz8Mgok5kQsQF10RExAQctYzgDzfxWXeWMjydScYe6RvNyJqKyK7b+Eofu9Wjz9P6h4mxZb+RVVdA==} engines: {node: '>=20'} @@ -8308,9 +8331,6 @@ packages: '@modern-js/server-utils@2.70.8': resolution: {integrity: sha512-RGfz0ZIONg/3+QmQv22an3UwvC/YnHLufAiKerur75DZpIrUQQogLz1LksA2ihMtmwqRHVHiY32dKhHTs4jJ5g==} - '@modern-js/server-utils@3.0.1': - resolution: {integrity: sha512-Z+rrXC7kzDfplX80WpZpJ6vfaz2S/h567ynM91KW7sjCRPDz1gawvZLUnCz/ZkpFYnpf1w50gcwyUj5TQx9i9Q==} - '@modern-js/server-utils@3.5.0': resolution: {integrity: sha512-HIJEXi4c6vMvEKZ6tXcwVv5YXlQX2jpNJ7wnYHAbFYRXXJ7qp6HwlnhFtxVVNCntSt0hpVSR2UFSkG61Xtg2Gw==} @@ -8342,20 +8362,6 @@ packages: tsconfig-paths: optional: true - '@modern-js/server@3.0.1': - resolution: {integrity: sha512-uDAWoWCnnuNvkpfoLtds3OL224xzs5I5/9BcKUnwy+xeRqTJaRV/zwgibOBpFpKTv6pOHBbHcC6YbN0np8ONsA==} - peerDependencies: - devcert: ^1.2.2 - ts-node: ^10.9.2 - tsconfig-paths: '>= 3.0.0 || >= 4.0.0' - peerDependenciesMeta: - devcert: - optional: true - ts-node: - optional: true - tsconfig-paths: - optional: true - '@modern-js/server@3.5.0': resolution: {integrity: sha512-ILaZCx9uZkd8+Bj58w84N1cSw+KHnOkMP/agTvAz6Rx/RTW3hhZUfEY3M5bIb9ToSlc27r6pAzTcIAhNwfycKg==} peerDependencies: @@ -11681,14 +11687,6 @@ packages: core-js: optional: true - '@rsbuild/plugin-assets-retry@1.5.1': - resolution: {integrity: sha512-AJR8xkwtGlYJDGDJdZ8PrluWyoDjXY8lpJFqL8X9QTUrBD3IRYamFRFAPim8azmEnF9dlnT74dmgqXsxHXThLQ==} - peerDependencies: - '@rsbuild/core': ^1.0.0 || ^2.0.0-0 - peerDependenciesMeta: - '@rsbuild/core': - optional: true - '@rsbuild/plugin-assets-retry@1.5.2': resolution: {integrity: sha512-d+nZeoaokk/nlP0UV2/ijbmrvLFlH1SXTUd3kDilw0IqvANrlBMnwTcaxkX6tf0Dr0b4gApp9xiZLP5zQsgb5w==} peerDependencies: @@ -11805,11 +11803,6 @@ packages: '@rsbuild/core': optional: true - '@rsbuild/plugin-react@1.4.4': - resolution: {integrity: sha512-tWOjyV4ZpUgwKT7sXHtGs24EYeyfY/THpTraLgikUUk0yLDeNHlDT5XPHOfLIbLIB3L8763AfgASFyhiqFw76g==} - peerDependencies: - '@rsbuild/core': ^1.0.0 || ^2.0.0-0 - '@rsbuild/plugin-react@1.4.5': resolution: {integrity: sha512-eS2sXCedgGA/7bLu8yVtn48eE/GyPbXx4Q7OcutB01IQ1D2y8WSMBys4nwfrecy19utvw4NPn4gYDy52316+vg==} peerDependencies: @@ -12002,19 +11995,6 @@ packages: typescript: optional: true - '@rslib/core@0.18.5': - resolution: {integrity: sha512-eofh36cvXJIq+h8sI2EniSD+2hr2V8eR+am3u9c8TIljv2KepQaHh1IH3OAIMRz/UOmXufJ97oHhH35fTK9vyA==} - engines: {node: '>=18.12.0'} - hasBin: true - peerDependencies: - '@microsoft/api-extractor': ^7 - typescript: ^5 - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - typescript: - optional: true - '@rslib/core@0.23.2': resolution: {integrity: sha512-KxSp+/y0BJ1O4oKwxX4ydBY7/ZVeJCUpWAmQniCIct8mTxIQFPGO/ibKbKq2IxZYqRuRpM8g+Dtyq0VbEQf9HQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -13450,12 +13430,6 @@ packages: chokidar: optional: true - '@swc/core-darwin-arm64@1.15.10': - resolution: {integrity: sha512-U72pGqmJYbjrLhMndIemZ7u9Q9owcJczGxwtfJlz/WwMaGYAV/g4nkGiUVk/+QSX8sFCAjanovcU1IUsP2YulA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - '@swc/core-darwin-arm64@1.15.41': resolution: {integrity: sha512-kREh6J5paQFvP3i7f/4FbqRNOJREutVFVOkder4GVyCBQ39YmER55cW/y1NNjwrchzFqgYswFn0mMDCqbqKzrw==} engines: {node: '>=10'} @@ -13474,12 +13448,6 @@ packages: cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.15.10': - resolution: {integrity: sha512-NZpDXtwHH083L40xdyj1sY31MIwLgOxKfZEAGCI8xHXdHa+GWvEiVdGiu4qhkJctoHFzAEc7ZX3GN5phuJcPuQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - '@swc/core-darwin-x64@1.15.41': resolution: {integrity: sha512-N8B56ESFazZAWZyIkecADSPCwlLEinW7QLMEeotCpv4J7VXwfH+OLkmRL8o96UZ+1355fwHxDTS6/wK7yucvkA==} engines: {node: '>=10'} @@ -13498,12 +13466,6 @@ packages: cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.15.10': - resolution: {integrity: sha512-ioieF5iuRziUF1HkH1gg1r93e055dAdeBAPGAk40VjqpL5/igPJ/WxFHGvc6WMLhUubSJI4S0AiZAAhEAp1jDg==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - '@swc/core-linux-arm-gnueabihf@1.15.41': resolution: {integrity: sha512-6XrId2fyle0mS5xxON8rU84mPd2Cq1kDJRj+4BnQKTd7u+2kSA6Ww+JkOP0iTNqOqt9OXhPOEAjBHAuonWcdCg==} engines: {node: '>=10'} @@ -13522,12 +13484,6 @@ packages: cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.15.10': - resolution: {integrity: sha512-tD6BClOrxSsNus9cJL7Gxdv7z7Y2hlyvZd9l0NQz+YXzmTWqnfzLpg16ovEI7gknH2AgDBB5ywOsqu8hUgSeEQ==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - '@swc/core-linux-arm64-gnu@1.15.41': resolution: {integrity: sha512-ynLIarxlkVnqHn1D0fKOVht6mNU5ks6lrH+MY3kkS+XFaGGgDxFZVjWKJlkYTKm3RCvBTfA8Ng5fLufXheMRKQ==} engines: {node: '>=10'} @@ -13546,12 +13502,6 @@ packages: cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.15.10': - resolution: {integrity: sha512-4uAHO3nbfbrTcmO/9YcVweTQdx5fN3l7ewwl5AEK4yoC4wXmoBTEPHAVdKNe4r9+xrTgd4BgyPsy0409OjjlMw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - '@swc/core-linux-arm64-musl@1.15.41': resolution: {integrity: sha512-dXu/5vd4gh8symyhRF+4G7gOPkjmb4pONhh7sl+6GSiW0LOKZlfu5kXmyFbTz9smOT7jgr002qY9b1nujjXt2A==} engines: {node: '>=10'} @@ -13582,12 +13532,6 @@ packages: cpu: [s390x] os: [linux] - '@swc/core-linux-x64-gnu@1.15.10': - resolution: {integrity: sha512-W0h9ONNw1pVIA0cN7wtboOSTl4Jk3tHq+w2cMPQudu9/+3xoCxpFb9ZdehwCAk29IsvdWzGzY6P7dDVTyFwoqg==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - '@swc/core-linux-x64-gnu@1.15.41': resolution: {integrity: sha512-VxkuQK59c0tHm6uJZCUrS3cyA2JhGGfdU6e41SZz0x/JS+4Sm7C1mIc97In14vkZJopEt7yXA2TouCqZDSygEA==} engines: {node: '>=10'} @@ -13606,12 +13550,6 @@ packages: cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.15.10': - resolution: {integrity: sha512-XQNZlLZB62S8nAbw7pqoqwy91Ldy2RpaMRqdRN3T+tAg6Xg6FywXRKCsLh6IQOadr4p1+lGnqM/Wn35z5a/0Vw==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - '@swc/core-linux-x64-musl@1.15.41': resolution: {integrity: sha512-/0qXIu1ZxggLuovLb22vFfKHq2AA4n6Whw5UwmVCHk4pkw7KWnPIQpMCEqUMPsNkFJig7PPp/TSYFu8ZEb2rtQ==} engines: {node: '>=10'} @@ -13630,12 +13568,6 @@ packages: cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.15.10': - resolution: {integrity: sha512-qnAGrRv5Nj/DATxAmCnJQRXXQqnJwR0trxLndhoHoxGci9MuguNIjWahS0gw8YZFjgTinbTxOwzatkoySihnmw==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - '@swc/core-win32-arm64-msvc@1.15.41': resolution: {integrity: sha512-Y481sMNZM6rECh9VO4+y26N1lWEDAyxnBZskUf37fl90uHE946VHfmiVQWT0uMFOhyJJFovGTRuF4W82dwewUg==} engines: {node: '>=10'} @@ -13654,12 +13586,6 @@ packages: cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.15.10': - resolution: {integrity: sha512-i4X/q8QSvzVlaRtv1xfnfl+hVKpCfiJ+9th484rh937fiEZKxZGf51C+uO0lfKDP1FfnT6C1yBYwHy7FLBVXFw==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - '@swc/core-win32-ia32-msvc@1.15.41': resolution: {integrity: sha512-BAchBD5qeUzy3hiPSLJtaaoSm4blCLyYffOF1bGE4ETcV+OisqjUAwDQMJj++4bTpvMCDzwC+Bj3PmQyBCtscw==} engines: {node: '>=10'} @@ -13678,12 +13604,6 @@ packages: cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.15.10': - resolution: {integrity: sha512-HvY8XUFuoTXn6lSccDLYFlXv1SU/PzYi4PyUqGT++WfTnbw/68N/7BdUZqglGRwiSqr0qhYt/EhmBpULj0J9rA==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - '@swc/core-win32-x64-msvc@1.15.41': resolution: {integrity: sha512-WOkA+fJ/ViVBQDsSV9JC52NACTe5PhlurA6viASDZGb7HR3KS01ZG7RZ+Bg6SVQFIoq3gSbTsskQVe6EbHFAYw==} engines: {node: '>=10'} @@ -13702,15 +13622,6 @@ packages: cpu: [x64] os: [win32] - '@swc/core@1.15.10': - resolution: {integrity: sha512-udNofxftduMUEv7nqahl2nvodCiCDQ4Ge0ebzsEm6P8s0RC2tBM0Hqx0nNF5J/6t9uagFJyWIDjXy3IIWMHDJw==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - '@swc/core@1.15.41': resolution: {integrity: sha512-03nQq/082QRJJiOvp3FGbgxTGyyxMxohPTjhk/W9bD2J0tk4ukITI7goOhOO2WbaHn/lsPmo/zf8+DIXhwpgYQ==} engines: {node: '>=10'} @@ -14758,6 +14669,126 @@ packages: resolution: {integrity: sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} deprecated: Potential CWE-502 - Update to 1.3.1 or higher @@ -15008,27 +15039,18 @@ packages: '@volar/language-core@2.4.15': resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} - '@volar/language-core@2.4.28': - resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - '@volar/source-map@1.11.1': resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} '@volar/source-map@2.4.15': resolution: {integrity: sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==} - '@volar/source-map@2.4.28': - resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - '@volar/typescript@1.11.1': resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} '@volar/typescript@2.4.15': resolution: {integrity: sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==} - '@volar/typescript@2.4.28': - resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - '@vscode/sudo-prompt@9.3.2': resolution: {integrity: sha512-gcXoCN00METUNFeQOFJ+C9xUI0DKB+0EGMVg7wbVYRHBw2Eq3fKisDZOkRdOz3kqXRKOENMfShPOmypw1/8nOw==} @@ -15090,14 +15112,6 @@ packages: typescript: optional: true - '@vue/language-core@2.2.0': - resolution: {integrity: sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@vue/language-core@2.2.12': resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==} peerDependencies: @@ -15472,9 +15486,6 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - alien-signals@0.4.14: - resolution: {integrity: sha512-itUAVzhczTmP2U5yX67xVpsbbOiquusbWVyA9N+sy6+r6YVbFkahXvNCeEPWEOMhwDYwbVbGHFkVL03N9I5g+Q==} - alien-signals@1.0.13: resolution: {integrity: sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==} @@ -15847,13 +15858,6 @@ packages: peerDependencies: postcss: ^8.1.0 - autoprefixer@10.4.24: - resolution: {integrity: sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - autoprefixer@10.4.27: resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} engines: {node: ^10 || ^12 || >=14} @@ -16856,9 +16860,6 @@ packages: compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - compare-versions@6.1.1: - resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - component-emitter@1.3.1: resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} @@ -16897,9 +16898,6 @@ packages: confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - confbox@0.2.4: - resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - connect-history-api-fallback@2.0.0: resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} engines: {node: '>=0.8'} @@ -21025,9 +21023,6 @@ packages: resolution: {integrity: sha512-MeuwbCoN1daWS32/Ni5qkzmrOtQO2qrnfdxDHjrm6s4b59yG4nexAJ0pTEFyzjLp0pBVO80CZp0vW8Ze30Ebow==} engines: {node: '>= 18'} - kolorist@1.8.0: - resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -21178,10 +21173,6 @@ packages: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} - local-pkg@1.1.2: - resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} - engines: {node: '>=14'} - locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -22933,9 +22924,6 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.3.0: - resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -25146,22 +25134,6 @@ packages: typescript: optional: true - rsbuild-plugin-dts@0.18.5: - resolution: {integrity: sha512-J17XXR5lNNHxXOG/Zi4kpIpCsQDxh3InPdicHkqfWNX65ly11nVC+zB/5CSkQFYAgJbw/y4SDSsuzOfkNt9DwQ==} - engines: {node: '>=18.12.0'} - peerDependencies: - '@microsoft/api-extractor': ^7 - '@rsbuild/core': 1.x - '@typescript/native-preview': 7.x - typescript: ^5 - peerDependenciesMeta: - '@microsoft/api-extractor': - optional: true - '@typescript/native-preview': - optional: true - typescript: - optional: true - rsbuild-plugin-dts@0.23.2: resolution: {integrity: sha512-Ve8WOSPyTBjxH40O/6fChJtflL7yqcUtt5zbF0eHDM4hIt35jqLocRlSdCxFJdQm0blTjl6+hkmPa/vNI06ArA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -25229,14 +25201,6 @@ packages: '@rspack/core': optional: true - rspack-manifest-plugin@5.2.1: - resolution: {integrity: sha512-H3qyCumiEiWy9zhcPIYPr3J3SWyvypVJJY5wxjG5L8gYny6dfNHfk0gyICg1tGO+g4uQzvVHER875ek/I/J8UA==} - peerDependencies: - '@rspack/core': ^1.0.0 || ^2.0.0-0 - peerDependenciesMeta: - '@rspack/core': - optional: true - rspack-manifest-plugin@5.2.2: resolution: {integrity: sha512-vynki1FQjdRaPYHKuiu5vxa/CT6v6pa601Q1nXWOHgdJ1HGID7/bShwuD1c6K4GWboJYl590iD0i6hoUi4AAhA==} peerDependencies: @@ -26869,20 +26833,6 @@ packages: ts-morph@12.0.0: resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} - ts-node@10.8.2: - resolution: {integrity: sha512-LYdGnoGddf1D6v8REPtIH+5iq/gTDuZqv2/UJUU7tKjuEU8xVZorBM+buCGNjj+pGEud+sOoM4CX3/YzINpENA==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - ts-node@10.9.1: resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true @@ -27137,11 +27087,6 @@ packages: engines: {node: '>=12.20'} hasBin: true - typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -27157,6 +27102,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + typical@4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} @@ -27569,15 +27519,6 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite-plugin-dts@4.5.4: - resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==} - peerDependencies: - typescript: '*' - vite: '*' - peerDependenciesMeta: - vite: - optional: true - vite-tsconfig-paths@4.2.3: resolution: {integrity: sha512-xVsA2xe6QSlzBujtWF8q2NYexh7PAUYfzJ4C8Axpe/7d2pcERYxuxGgph9F4f0iQO36g5tyGq6eBUYIssdUrVw==} peerDependencies: @@ -28843,14 +28784,14 @@ snapshots: '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.28.6(supports-color@5.5.0)': dependencies: - '@babel/traverse': 7.29.0(supports-color@5.5.0) + '@babel/traverse': 7.29.7(supports-color@5.5.0) '@babel/types': 7.29.7 transitivePeerDependencies: - supports-color @@ -29028,7 +28969,7 @@ snapshots: dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29036,7 +28977,7 @@ snapshots: dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29082,7 +29023,7 @@ snapshots: dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29090,7 +29031,7 @@ snapshots: dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29440,7 +29381,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29449,7 +29390,7 @@ snapshots: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.7) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29539,7 +29480,7 @@ snapshots: '@babel/helper-globals': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29551,7 +29492,7 @@ snapshots: '@babel/helper-globals': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.7) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29571,7 +29512,7 @@ snapshots: dependencies: '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29579,7 +29520,7 @@ snapshots: dependencies: '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29696,7 +29637,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29705,7 +29646,7 @@ snapshots: '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29795,7 +29736,7 @@ snapshots: '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29805,7 +29746,7 @@ snapshots: '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29874,7 +29815,7 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -29885,7 +29826,7 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.7) '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.7) - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 transitivePeerDependencies: - supports-color @@ -30530,18 +30471,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@7.29.0(supports-color@5.5.0)': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.2 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -32437,7 +32366,7 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.31 babel-plugin-istanbul: 6.1.1 @@ -32925,6 +32854,7 @@ snapshots: '@rushstack/node-core-library': 5.20.3(@types/node@20.19.5) transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/api-extractor-model@7.33.4(@types/node@22.19.15)': dependencies: @@ -32942,6 +32872,7 @@ snapshots: '@rushstack/node-core-library': 5.20.3(@types/node@26.1.0) transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/api-extractor@7.57.7(@types/node@20.19.5)': dependencies: @@ -32955,12 +32886,13 @@ snapshots: diff: 8.0.3 lodash: 4.17.23 minimatch: 10.2.3 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 source-map: 0.6.1 typescript: 5.8.2 transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/api-extractor@7.57.7(@types/node@22.19.15)': dependencies: @@ -32974,7 +32906,7 @@ snapshots: diff: 8.0.3 lodash: 4.17.23 minimatch: 10.2.3 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 source-map: 0.6.1 typescript: 5.8.2 @@ -32994,12 +32926,13 @@ snapshots: diff: 8.0.3 lodash: 4.17.23 minimatch: 10.2.3 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 source-map: 0.6.1 typescript: 5.8.2 transitivePeerDependencies: - '@types/node' + optional: true '@microsoft/tsdoc-config@0.18.1': dependencies: @@ -33007,8 +32940,10 @@ snapshots: ajv: 8.18.0 jju: 1.4.0 resolve: 1.22.11 + optional: true - '@microsoft/tsdoc@0.16.0': {} + '@microsoft/tsdoc@0.16.0': + optional: true '@modelcontextprotocol/sdk@1.27.1(zod@3.25.76)': dependencies: @@ -33032,53 +32967,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@modern-js-app/eslint-config@2.59.0(typescript@5.0.4)': - dependencies: - '@babel/core': 7.29.0 - '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) - '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1))(eslint@8.57.1) - '@modern-js/babel-preset': 2.59.0(@rsbuild/core@1.0.1-rc.4) - '@rsbuild/core': 1.0.1-rc.4 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.0.4) - eslint: 8.57.1 - eslint-config-prettier: 8.10.2(eslint@8.57.1) - eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) - eslint-plugin-filenames: 1.3.2(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) - eslint-plugin-node: 11.1.0(eslint@8.57.1) - eslint-plugin-prettier: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) - eslint-plugin-promise: 6.6.0(eslint@8.57.1) - eslint-plugin-react: 7.37.2(eslint@8.57.1) - eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) - prettier: 2.8.8 - typescript: 5.0.4 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - '@modern-js-app/eslint-config@2.59.0(typescript@6.0.3)': + '@modern-js-app/eslint-config@2.59.0(typescript@7.0.2)': dependencies: '@babel/core': 7.29.0 '@babel/eslint-parser': 7.28.6(@babel/core@7.29.7)(eslint@8.57.1) '@babel/eslint-plugin': 7.27.1(@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1))(eslint@8.57.1) '@modern-js/babel-preset': 2.59.0(@rsbuild/core@1.0.1-rc.4) '@rsbuild/core': 1.0.1-rc.4 - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 eslint-config-prettier: 8.10.2(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-filenames: 1.3.2(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1) eslint-plugin-node: 11.1.0(eslint@8.57.1) eslint-plugin-prettier: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) eslint-plugin-promise: 6.6.0(eslint@8.57.1) eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) prettier: 2.8.8 - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -33130,7 +33039,7 @@ snapshots: '@swc/helpers': 0.5.1 redux: 4.2.1 - '@modern-js/app-tools@2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(@swc/core@1.15.41(@swc/helpers@0.5.17))(encoding@0.1.13)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': + '@modern-js/app-tools@2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(@swc/core@1.15.41(@swc/helpers@0.5.17))(encoding@0.1.13)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/parser': 7.29.2 '@babel/traverse': 7.29.0 @@ -33143,11 +33052,11 @@ snapshots: '@modern-js/plugin-v2': 2.70.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@modern-js/prod-server': 2.70.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@modern-js/rsbuild-plugin-esbuild': 2.70.5(@swc/core@1.15.41(@swc/helpers@0.5.17))(webpack-cli@5.1.4) - '@modern-js/server': 2.70.5(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0) + '@modern-js/server': 2.70.5(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0) '@modern-js/server-core': 2.70.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@modern-js/server-utils': 2.70.5(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3) '@modern-js/types': 2.70.5 - '@modern-js/uni-builder': 2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) + '@modern-js/uni-builder': 2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) '@modern-js/utils': 2.70.5 '@rsbuild/core': 1.7.3 '@rsbuild/plugin-node-polyfill': 1.4.3(@rsbuild/core@1.7.3) @@ -33161,7 +33070,7 @@ snapshots: pkg-types: 1.3.1 std-env: 3.10.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@parcel/css' @@ -33192,7 +33101,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/app-tools@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.41(@swc/helpers@0.5.19))(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': + '@modern-js/app-tools@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.41(@swc/helpers@0.5.19))(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rollup@4.59.0)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/parser': 7.29.2 '@babel/traverse': 7.29.0 @@ -33205,11 +33114,11 @@ snapshots: '@modern-js/plugin-v2': 2.70.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@modern-js/prod-server': 2.70.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@modern-js/rsbuild-plugin-esbuild': 2.70.8(@swc/core@1.15.41(@swc/helpers@0.5.19))(webpack-cli@5.1.4) - '@modern-js/server': 2.70.8(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3))(tsconfig-paths@4.2.0) + '@modern-js/server': 2.70.8(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0) '@modern-js/server-core': 2.70.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@modern-js/server-utils': 2.70.8(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3) '@modern-js/types': 2.70.8 - '@modern-js/uni-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) + '@modern-js/uni-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) '@modern-js/utils': 2.70.8 '@rsbuild/core': 1.7.3 '@rsbuild/plugin-node-polyfill': 1.4.4(@rsbuild/core@1.7.3) @@ -33223,7 +33132,7 @@ snapshots: pkg-types: 1.3.1 std-env: 3.10.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@parcel/css' @@ -33254,90 +33163,40 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/app-tools@3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': - dependencies: - '@babel/parser': 7.29.7 - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - '@modern-js/builder': 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@modern-js/i18n-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@3.14.2) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@swc/helpers': 0.5.17 - es-module-lexer: 1.7.0 - esbuild: 0.25.5 - esbuild-register: 3.6.0(esbuild@0.25.5) - flatted: 3.4.2 - mlly: 1.8.2 - ndepe: 0.1.13(encoding@0.1.13)(rollup@4.59.0) - pkg-types: 1.3.1 - std-env: 3.10.0 - optionalDependencies: - ts-node: 10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) - tsconfig-paths: 3.14.2 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - '@parcel/css' - - '@rspack/core' - - '@swc/css' - - bufferutil - - clean-css - - core-js - - csso - - debug - - devcert - - encoding - - lightningcss - - react - - react-dom - - rollup - - supports-color - - tslib - - typescript - - utf-8-validate - - webpack - - webpack-hot-middleware - - '@modern-js/app-tools@3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@modern-js/i18n-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 es-module-lexer: 1.7.0 - esbuild: 0.25.5 - esbuild-register: 3.6.0(esbuild@0.25.5) flatted: 3.4.2 + import-meta-resolve: 4.2.0 mlly: 1.8.2 ndepe: 0.1.13(encoding@0.1.13)(rollup@4.59.0) pkg-types: 1.3.1 std-env: 3.10.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@parcel/css' - '@rspack/core' - '@swc/css' + - '@typescript/native-preview' - bufferutil - clean-css - core-js @@ -33345,50 +33204,52 @@ snapshots: - debug - devcert - encoding + - esbuild - lightningcss - react - react-dom + - react-server-dom-rspack - rollup - supports-color - tslib - typescript - utf-8-validate - webpack - - webpack-hot-middleware - '@modern-js/app-tools@3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@modern-js/i18n-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 es-module-lexer: 1.7.0 - esbuild: 0.25.5 - esbuild-register: 3.6.0(esbuild@0.25.5) flatted: 3.4.2 + import-meta-resolve: 4.2.0 mlly: 1.8.2 ndepe: 0.1.13(encoding@0.1.13)(rollup@4.59.0) pkg-types: 1.3.1 std-env: 3.10.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) - tsconfig-paths: 4.2.0 + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) + tsconfig-paths: 3.14.2 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@parcel/css' - '@rspack/core' - '@swc/css' + - '@typescript/native-preview' - bufferutil - clean-css - core-js @@ -33396,28 +33257,29 @@ snapshots: - debug - devcert - encoding + - esbuild - lightningcss - react - react-dom + - react-server-dom-rspack - rollup - supports-color - tslib - typescript - utf-8-validate - webpack - - webpack-hot-middleware - '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0) '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 @@ -33433,7 +33295,7 @@ snapshots: pkg-types: 1.3.1 std-env: 3.10.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@module-federation/runtime-tools' @@ -33592,122 +33454,72 @@ snapshots: - '@rsbuild/core' - supports-color - '@modern-js/builder@3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: - '@modern-js/flight-server-transform-plugin': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-assets-retry': 1.5.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-check-syntax': 1.6.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-css-minimizer': 1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@rsbuild/plugin-less': 1.6.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-react': 1.4.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-rem': 1.0.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@5.0.4)(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-type-check': 1.3.3(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@5.0.4) - '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@swc/core': 1.15.10(@swc/helpers@0.5.17) - '@swc/helpers': 0.5.17 - autoprefixer: 10.4.24(postcss@8.5.10) - browserslist: 4.28.1 - core-js: 3.49.0 - cssnano: 6.1.2(postcss@8.5.10) - html-minifier-terser: 7.2.0 - lodash: 4.18.1 - postcss: 8.5.10 - postcss-custom-properties: 13.3.12(postcss@8.5.10) - postcss-flexbugs-fixes: 5.0.2(postcss@8.5.10) - postcss-font-variant: 5.0.0(postcss@8.5.10) - postcss-initial: 4.0.1(postcss@8.5.10) - postcss-media-minmax: 5.0.0(postcss@8.5.10) - postcss-nesting: 12.1.5(postcss@8.5.10) - postcss-page-break: 3.0.4(postcss@8.5.10) - rspack-manifest-plugin: 5.2.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) - ts-deepmerge: 7.0.3 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - '@parcel/css' - - '@rspack/core' - - '@swc/css' - - clean-css - - csso - - esbuild - - lightningcss - - react - - react-dom - - supports-color - - tslib - - typescript - - webpack - - webpack-hot-middleware - - '@modern-js/builder@3.0.1(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.25.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@5.0.4)(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': - dependencies: - '@modern-js/flight-server-transform-plugin': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-assets-retry': 1.5.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-check-syntax': 1.6.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-css-minimizer': 1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@rsbuild/plugin-less': 1.6.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-react': 1.4.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-rem': 1.0.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@5.0.4)(webpack-hot-middleware@2.26.1) - '@rsbuild/plugin-type-check': 1.3.3(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@5.0.4) - '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@swc/core': 1.15.10(@swc/helpers@0.5.17) + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@7.0.2) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) + '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 - autoprefixer: 10.4.24(postcss@8.5.10) - browserslist: 4.28.1 + autoprefixer: 10.4.27(postcss@8.5.15) + browserslist: 4.28.2 core-js: 3.49.0 - cssnano: 6.1.2(postcss@8.5.10) + cssnano: 6.1.2(postcss@8.5.15) html-minifier-terser: 7.2.0 lodash: 4.18.1 - postcss: 8.5.10 - postcss-custom-properties: 13.3.12(postcss@8.5.10) - postcss-flexbugs-fixes: 5.0.2(postcss@8.5.10) - postcss-font-variant: 5.0.0(postcss@8.5.10) - postcss-initial: 4.0.1(postcss@8.5.10) - postcss-media-minmax: 5.0.0(postcss@8.5.10) - postcss-nesting: 12.1.5(postcss@8.5.10) - postcss-page-break: 3.0.4(postcss@8.5.10) - rspack-manifest-plugin: 5.2.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + postcss: 8.5.15 + postcss-custom-properties: 13.3.12(postcss@8.5.15) + postcss-flexbugs-fixes: 5.0.2(postcss@8.5.15) + postcss-font-variant: 5.0.0(postcss@8.5.15) + postcss-initial: 4.0.1(postcss@8.5.15) + postcss-media-minmax: 5.0.0(postcss@8.5.15) + postcss-nesting: 12.1.5(postcss@8.5.15) + postcss-page-break: 3.0.4(postcss@8.5.15) + rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + rspack-manifest-plugin: 5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) ts-deepmerge: 7.0.3 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@parcel/css' - '@rspack/core' - '@swc/css' + - '@typescript/native-preview' - clean-css - csso - esbuild - lightningcss - react - react-dom + - react-server-dom-rspack - supports-color - tslib - typescript - webpack - - webpack-hot-middleware - '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) - '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) - '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@6.0.3) - '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3) + '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(typescript@7.0.2) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 @@ -33725,8 +33537,8 @@ snapshots: postcss-media-minmax: 5.0.0(postcss@8.5.15) postcss-nesting: 12.1.5(postcss@8.5.15) postcss-page-break: 3.0.4(postcss@8.5.15) - rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - rspack-manifest-plugin: 5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + rspack-manifest-plugin: 5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) ts-deepmerge: 7.0.3 transitivePeerDependencies: - '@module-federation/runtime-tools' @@ -33760,18 +33572,9 @@ snapshots: '@modern-js/utils': 2.70.8 '@swc/helpers': 0.5.17 - '@modern-js/eslint-config@2.59.0(typescript@5.0.4)': - dependencies: - '@modern-js-app/eslint-config': 2.59.0(typescript@5.0.4) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - typescript - - '@modern-js/eslint-config@2.59.0(typescript@6.0.3)': + '@modern-js/eslint-config@2.59.0(typescript@7.0.2)': dependencies: - '@modern-js-app/eslint-config': 2.59.0(typescript@6.0.3) + '@modern-js-app/eslint-config': 2.59.0(typescript@7.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -33782,16 +33585,6 @@ snapshots: '@modern-js/flight-server-transform-plugin@2.70.8': {} - '@modern-js/flight-server-transform-plugin@3.0.1': {} - - '@modern-js/i18n-utils@3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - transitivePeerDependencies: - - react - - react-dom - '@modern-js/i18n-utils@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -33800,7 +33593,7 @@ snapshots: - react - react-dom - '@modern-js/module-tools@2.70.5(@types/node@26.1.0)(typescript@6.0.3)': + '@modern-js/module-tools@2.70.5(@types/node@26.1.0)(typescript@7.0.2)': dependencies: '@ampproject/remapping': 2.3.0 '@ast-grep/napi': 0.35.0 @@ -33829,13 +33622,13 @@ snapshots: terser: 5.46.1 tsconfig-paths-webpack-plugin: 4.1.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@types/node' - debug - supports-color - '@modern-js/module-tools@2.70.8(@types/node@20.19.5)(typescript@6.0.3)': + '@modern-js/module-tools@2.70.8(@types/node@20.19.5)(typescript@7.0.2)': dependencies: '@ampproject/remapping': 2.3.0 '@ast-grep/napi': 0.35.0 @@ -33864,7 +33657,7 @@ snapshots: terser: 5.46.1 tsconfig-paths-webpack-plugin: 4.1.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@types/node' - debug @@ -33936,16 +33729,6 @@ snapshots: - react-dom - supports-color - '@modern-js/plugin-data-loader@3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - path-to-regexp: 6.3.0 - react: 18.3.1 - transitivePeerDependencies: - - react-dom - '@modern-js/plugin-data-loader@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34080,18 +33863,6 @@ snapshots: - react - react-dom - '@modern-js/prod-server@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - core-js - - react - - react-dom - '@modern-js/prod-server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34122,32 +33893,23 @@ snapshots: react-dom: 19.2.4(react@19.2.4) react-server-dom-webpack: 19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) - '@modern-js/render@3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1)': - dependencies: - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-server-dom-webpack: 19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - - '@modern-js/render@3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1)': + '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-webpack: 19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/rsbuild-plugin-esbuild@2.70.5(@swc/core@1.15.41(@swc/helpers@0.5.17))(webpack-cli@5.1.4)': dependencies: @@ -34296,45 +34058,17 @@ snapshots: - react-server-dom-webpack - supports-color - '@modern-js/runtime@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1)': - dependencies: - '@loadable/component': 5.16.7(react@18.3.1) - '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - '@swc/plugin-loadable-components': 11.15.0 - '@types/loadable__component': 5.13.10 - '@types/react-helmet': 6.1.11 - cookie: 0.7.2 - entities: 7.0.1 - es-module-lexer: 1.7.0 - esbuild: 0.25.5 - invariant: 2.2.4 - isbot: 3.8.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-helmet: 6.1.0(react@18.3.1) - react-is: 18.3.1 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - core-js - - react-server-dom-webpack - - '@modern-js/runtime@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1)': + '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@loadable/component': 5.16.7(react@18.3.1) '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin-data-loader': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.0.1(react-dom@18.3.1(react@18.3.1))(react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))))(react@18.3.1) - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 '@swc/plugin-loadable-components': 11.15.0 '@types/loadable__component': 5.13.10 @@ -34342,7 +34076,6 @@ snapshots: cookie: 0.7.2 entities: 7.0.1 es-module-lexer: 1.7.0 - esbuild: 0.25.5 invariant: 2.2.4 isbot: 3.8.0 react: 18.3.1 @@ -34352,15 +34085,15 @@ snapshots: transitivePeerDependencies: - '@module-federation/runtime-tools' - core-js - - react-server-dom-webpack + - react-server-dom-rspack - '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@loadable/component': 5.16.7(react@18.3.1) '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34544,14 +34277,6 @@ snapshots: - '@rsbuild/core' - supports-color - '@modern-js/server-utils@3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@swc/helpers': 0.5.17 - transitivePeerDependencies: - - react - - react-dom - '@modern-js/server-utils@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34560,7 +34285,7 @@ snapshots: - react - react-dom - '@modern-js/server@2.70.5(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)': + '@modern-js/server@2.70.5(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: '@babel/core': 7.29.7 '@babel/register': 7.28.6(@babel/core@7.29.7) @@ -34577,7 +34302,7 @@ snapshots: path-to-regexp: 6.3.0 ws: 8.21.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@babel/traverse' @@ -34589,7 +34314,7 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@2.70.8(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3))(tsconfig-paths@4.2.0)': + '@modern-js/server@2.70.8(@babel/traverse@7.29.0)(@rsbuild/core@1.7.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: '@babel/core': 7.29.0 '@babel/register': 7.28.6(@babel/core@7.29.0) @@ -34606,7 +34331,7 @@ snapshots: path-to-regexp: 6.3.0 ws: 8.21.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@babel/traverse' @@ -34618,13 +34343,13 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@3.14.2)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 axios: 1.16.1(debug@4.4.3) connect-history-api-fallback: 2.0.0 @@ -34633,8 +34358,8 @@ snapshots: path-to-regexp: 6.3.0 ws: 8.21.0 optionalDependencies: - ts-node: 10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) - tsconfig-paths: 3.14.2 + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2) + tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@module-federation/runtime-tools' - bufferutil @@ -34645,13 +34370,13 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))(tsconfig-paths@4.2.0)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)': dependencies: - '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/types': 3.0.1 - '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/types': 3.5.0 + '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 axios: 1.16.1(debug@4.4.3) connect-history-api-fallback: 2.0.0 @@ -34660,8 +34385,8 @@ snapshots: path-to-regexp: 6.3.0 ws: 8.21.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) - tsconfig-paths: 4.2.0 + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) + tsconfig-paths: 3.14.2 transitivePeerDependencies: - '@module-federation/runtime-tools' - bufferutil @@ -34672,7 +34397,7 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3))(tsconfig-paths@4.2.0)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34687,7 +34412,7 @@ snapshots: path-to-regexp: 6.3.0 ws: 8.21.0 optionalDependencies: - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) tsconfig-paths: 4.2.0 transitivePeerDependencies: - '@module-federation/runtime-tools' @@ -34699,12 +34424,12 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/storybook-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': + '@modern-js/storybook-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': dependencies: '@modern-js/core': 2.70.8 '@modern-js/plugin-state': 2.70.8(@modern-js/runtime@2.70.8(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@modern-js/runtime': 2.70.8(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4) - '@modern-js/uni-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.18.20)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) + '@modern-js/uni-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.18.20)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1) '@modern-js/utils': 2.70.8 '@rsbuild/core': 1.7.3 '@storybook/components': 7.6.24(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -34715,7 +34440,7 @@ snapshots: '@storybook/mdx2-csf': 1.1.0 '@storybook/preview': 7.6.24 '@storybook/preview-api': 7.6.24 - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) '@storybook/router': 7.6.24 '@storybook/theming': 7.6.24(react-dom@19.2.4(react@19.2.4))(react@19.2.4) ast-types: 0.14.2 @@ -34753,11 +34478,11 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/storybook@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': + '@modern-js/storybook@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': dependencies: - '@modern-js/storybook-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) + '@modern-js/storybook-builder': 2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(esbuild@0.18.20)(react-dom@19.2.4(react@19.2.4))(react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(react@19.2.4)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) '@modern-js/utils': 2.70.8 - '@storybook/react': 7.6.24(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.3) + '@storybook/react': 7.6.24(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2) storybook: 7.6.24(encoding@0.1.13) transitivePeerDependencies: - '@parcel/css' @@ -34855,7 +34580,7 @@ snapshots: '@modern-js/types@3.5.0': {} - '@modern-js/uni-builder@2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': + '@modern-js/uni-builder@2.70.5(@rspack/core@1.7.9(@swc/helpers@0.5.17))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/core': 7.29.7 '@babel/preset-react': 7.28.5(@babel/core@7.29.7) @@ -34876,9 +34601,9 @@ snapshots: '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@1.7.3) '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/plugin-styled-components': 1.6.0(@rsbuild/core@1.7.3) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@6.0.3)(webpack-hot-middleware@2.26.1) + '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@7.0.2)(webpack-hot-middleware@2.26.1) '@rsbuild/plugin-toml': 1.1.2(@rsbuild/core@1.7.3) - '@rsbuild/plugin-type-check': 1.3.3(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3) + '@rsbuild/plugin-type-check': 1.3.3(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@1.7.3) '@rsbuild/plugin-yaml': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/webpack': 1.6.1(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.17))(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) @@ -34911,7 +34636,7 @@ snapshots: rspack-manifest-plugin: 5.0.3(@rspack/core@1.7.9(@swc/helpers@0.5.17)) terser-webpack-plugin: 5.3.14(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)) ts-deepmerge: 7.0.2 - ts-loader: 9.4.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)) + ts-loader: 9.4.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)) webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.9(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)) transitivePeerDependencies: @@ -34935,7 +34660,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/uni-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.18.20)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': + '@modern-js/uni-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.18.20)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/core': 7.29.0 '@babel/preset-react': 7.28.5(@babel/core@7.29.0) @@ -34956,9 +34681,9 @@ snapshots: '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@1.7.3) '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/plugin-styled-components': 1.6.0(@rsbuild/core@1.7.3) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@6.0.3)(webpack-hot-middleware@2.26.1) + '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@7.0.2)(webpack-hot-middleware@2.26.1) '@rsbuild/plugin-toml': 1.1.2(@rsbuild/core@1.7.3) - '@rsbuild/plugin-type-check': 1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@6.0.3) + '@rsbuild/plugin-type-check': 1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@7.0.2) '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@1.7.3) '@rsbuild/plugin-yaml': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/webpack': 1.6.1(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.18.20)(webpack-cli@5.1.4) @@ -34991,7 +34716,7 @@ snapshots: rspack-manifest-plugin: 5.0.3(@rspack/core@1.7.9(@swc/helpers@0.5.19)) terser-webpack-plugin: 5.3.14(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.18.20)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) ts-deepmerge: 7.0.2 - ts-loader: 9.4.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) + ts-loader: 9.4.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.18.20)(webpack-cli@5.1.4) webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.9(@swc/helpers@0.5.19))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) transitivePeerDependencies: @@ -35015,7 +34740,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/uni-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@6.0.3)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': + '@modern-js/uni-builder@2.70.8(@rspack/core@1.7.9(@swc/helpers@0.5.19))(esbuild@0.25.5)(styled-components@6.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(tslib@2.8.1)(type-fest@2.19.0)(typescript@7.0.2)(webpack-cli@5.1.4)(webpack-dev-server@5.2.3(webpack-cli@5.1.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/core': 7.29.0 '@babel/preset-react': 7.28.5(@babel/core@7.29.0) @@ -35036,9 +34761,9 @@ snapshots: '@rsbuild/plugin-sass': 1.5.0(@rsbuild/core@1.7.3) '@rsbuild/plugin-source-build': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/plugin-styled-components': 1.6.0(@rsbuild/core@1.7.3) - '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@6.0.3)(webpack-hot-middleware@2.26.1) + '@rsbuild/plugin-svgr': 1.3.0(@rsbuild/core@1.7.3)(typescript@7.0.2)(webpack-hot-middleware@2.26.1) '@rsbuild/plugin-toml': 1.1.2(@rsbuild/core@1.7.3) - '@rsbuild/plugin-type-check': 1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@6.0.3) + '@rsbuild/plugin-type-check': 1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@7.0.2) '@rsbuild/plugin-typed-css-modules': 1.2.1(@rsbuild/core@1.7.3) '@rsbuild/plugin-yaml': 1.0.4(@rsbuild/core@1.7.3) '@rsbuild/webpack': 1.6.1(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) @@ -35071,7 +34796,7 @@ snapshots: rspack-manifest-plugin: 5.0.3(@rspack/core@1.7.9(@swc/helpers@0.5.19)) terser-webpack-plugin: 5.3.14(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) ts-deepmerge: 7.0.2 - ts-loader: 9.4.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) + ts-loader: 9.4.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) webpack: 5.104.1(@swc/core@1.15.8(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) webpack-subresource-integrity: 5.1.0(html-webpack-plugin@5.6.6(@rspack/core@1.7.9(@swc/helpers@0.5.19))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) transitivePeerDependencies: @@ -35098,7 +34823,7 @@ snapshots: '@modern-js/utils@2.68.0': dependencies: '@swc/helpers': 0.5.17 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 lodash: 4.18.1 rslog: 1.2.3 @@ -35112,14 +34837,14 @@ snapshots: '@modern-js/utils@2.70.8': dependencies: '@swc/helpers': 0.5.17 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 lodash: 4.18.1 rslog: 1.2.3 '@modern-js/utils@3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@swc/helpers': 0.5.17 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 import-meta-resolve: 4.2.0 lodash: 4.18.1 lodash-es: 4.18.1 @@ -35159,9 +34884,9 @@ snapshots: transitivePeerDependencies: - node-fetch - '@module-federation/cli@0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/cli@0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: - '@module-federation/dts-plugin': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/sdk': 0.21.6 chalk: 3.0.0 commander: 11.1.0 @@ -35174,9 +34899,9 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/cli@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/cli@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: - '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/sdk': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) chalk: 3.0.0 commander: 11.1.0 @@ -35209,7 +34934,7 @@ snapshots: transitivePeerDependencies: - node-fetch - '@module-federation/dts-plugin@0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/dts-plugin@0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: '@module-federation/error-codes': 0.21.6 '@module-federation/managers': 0.21.6 @@ -35226,17 +34951,17 @@ snapshots: log4js: 6.9.1 node-schedule: 2.1.1 rambda: 9.2.1 - typescript: 6.0.3 + typescript: 7.0.2 ws: 8.18.0 optionalDependencies: - vue-tsc: 2.2.12(typescript@6.0.3) + vue-tsc: 2.2.12(typescript@7.0.2) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - '@module-federation/dts-plugin@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/dts-plugin@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: '@module-federation/error-codes': 2.2.2 '@module-federation/managers': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) @@ -35252,10 +34977,10 @@ snapshots: log4js: 6.9.1 node-schedule: 2.1.1 rambda: 9.2.1 - typescript: 6.0.3 + typescript: 7.0.2 ws: 8.18.0 optionalDependencies: - vue-tsc: 2.2.12(typescript@6.0.3) + vue-tsc: 2.2.12(typescript@7.0.2) transitivePeerDependencies: - bufferutil - debug @@ -35263,25 +34988,25 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': + '@module-federation/enhanced@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.21.6 - '@module-federation/cli': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/cli': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/data-prefetch': 0.21.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@module-federation/dts-plugin': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/error-codes': 0.21.6 '@module-federation/inject-external-runtime-core-plugin': 0.21.6(@module-federation/runtime-tools@0.21.6) '@module-federation/managers': 0.21.6 - '@module-federation/manifest': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) - '@module-federation/rspack': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/manifest': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) + '@module-federation/rspack': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/runtime-tools': 0.21.6 '@module-federation/sdk': 0.21.6 btoa: 1.2.1 schema-utils: 4.3.0 upath: 2.0.1 optionalDependencies: - typescript: 6.0.3 - vue-tsc: 2.2.12(typescript@6.0.3) + typescript: 7.0.2 + vue-tsc: 2.2.12(typescript@7.0.2) webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) transitivePeerDependencies: - '@rspack/core' @@ -35292,17 +35017,17 @@ snapshots: - supports-color - utf-8-validate - '@module-federation/enhanced@2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': + '@module-federation/enhanced@2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: '@module-federation/bridge-react-webpack-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) - '@module-federation/cli': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/cli': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/data-prefetch': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/error-codes': 2.2.2 '@module-federation/inject-external-runtime-core-plugin': 2.2.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13))) '@module-federation/managers': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) - '@module-federation/manifest': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) - '@module-federation/rspack': 2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/manifest': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) + '@module-federation/rspack': 2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/runtime-tools': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/sdk': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/webpack-bundler-runtime': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) @@ -35311,8 +35036,8 @@ snapshots: tapable: 2.3.0 upath: 2.0.1 optionalDependencies: - typescript: 6.0.3 - vue-tsc: 2.2.12(typescript@6.0.3) + typescript: 7.0.2 + vue-tsc: 2.2.12(typescript@7.0.2) webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) transitivePeerDependencies: - '@rspack/core' @@ -35363,9 +35088,9 @@ snapshots: transitivePeerDependencies: - node-fetch - '@module-federation/manifest@0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/manifest@0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: - '@module-federation/dts-plugin': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/managers': 0.21.6 '@module-federation/sdk': 0.21.6 chalk: 3.0.0 @@ -35378,9 +35103,9 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/manifest@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/manifest@2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: - '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/managers': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/sdk': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) chalk: 3.0.0 @@ -35394,9 +35119,9 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/node@2.7.36(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': + '@module-federation/node@2.7.36(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: - '@module-federation/enhanced': 2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) + '@module-federation/enhanced': 2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) '@module-federation/runtime': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/sdk': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) btoa: 1.2.1 @@ -35416,40 +35141,40 @@ snapshots: - utf-8-validate - vue-tsc - '@module-federation/rspack@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/rspack@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.21.6 - '@module-federation/dts-plugin': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/inject-external-runtime-core-plugin': 0.21.6(@module-federation/runtime-tools@0.21.6) '@module-federation/managers': 0.21.6 - '@module-federation/manifest': 0.21.6(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/manifest': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/runtime-tools': 0.21.6 '@module-federation/sdk': 0.21.6 '@rspack/core': 1.6.8(@swc/helpers@0.5.23) btoa: 1.2.1 optionalDependencies: - typescript: 6.0.3 - vue-tsc: 2.2.12(typescript@6.0.3) + typescript: 7.0.2 + vue-tsc: 2.2.12(typescript@7.0.2) transitivePeerDependencies: - bufferutil - debug - supports-color - utf-8-validate - '@module-federation/rspack@2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))': + '@module-federation/rspack@2.2.2(@rspack/core@1.6.8(@swc/helpers@0.5.23))(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: '@module-federation/bridge-react-webpack-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) - '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/dts-plugin': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/inject-external-runtime-core-plugin': 2.2.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13))) '@module-federation/managers': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) - '@module-federation/manifest': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3)) + '@module-federation/manifest': 2.2.2(node-fetch@2.7.0(encoding@0.1.13))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) '@module-federation/runtime-tools': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@module-federation/sdk': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@rspack/core': 1.6.8(@swc/helpers@0.5.23) btoa: 1.2.1 optionalDependencies: - typescript: 6.0.3 - vue-tsc: 2.2.12(typescript@6.0.3) + typescript: 7.0.2 + vue-tsc: 2.2.12(typescript@7.0.2) transitivePeerDependencies: - bufferutil - debug @@ -36035,10 +35760,10 @@ snapshots: - nx - supports-color - '@nx/module-federation@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack-cli@5.1.4)': + '@nx/module-federation@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4)': dependencies: - '@module-federation/enhanced': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) - '@module-federation/node': 2.7.36(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) + '@module-federation/enhanced': 0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) + '@module-federation/node': 2.7.36(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) '@module-federation/sdk': 0.21.6 '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) @@ -36098,16 +35823,16 @@ snapshots: '@nx/nx-win32-x64-msvc@22.5.4': optional: true - '@nx/react@22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(esbuild@0.25.5)(eslint@9.39.3(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@6.0.3))(webpack-cli@5.1.4)': + '@nx/react@22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(@types/babel__core@7.20.5)(@zkochan/js-yaml@0.0.7)(esbuild@0.25.5)(eslint@9.39.3(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4)': dependencies: '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/eslint': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@zkochan/js-yaml@0.0.7)(eslint@9.39.3(jiti@2.6.1))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) - '@nx/module-federation': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)(vue-tsc@2.2.12(typescript@6.0.3))(webpack-cli@5.1.4) - '@nx/rollup': 22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3) + '@nx/module-federation': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4) + '@nx/rollup': 22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2) '@nx/web': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) - '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.3) - '@svgr/webpack': 8.1.0(typescript@6.0.3) + '@phenomnomnominal/tsquery': 6.1.4(typescript@7.0.2) + '@svgr/webpack': 8.1.0(typescript@7.0.2) express: 4.22.1 http-proxy-middleware: 3.0.5 minimatch: 10.2.4 @@ -36115,7 +35840,7 @@ snapshots: semver: 7.6.3 tslib: 2.8.1 optionalDependencies: - '@nx/vite': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)) + '@nx/vite': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)) transitivePeerDependencies: - '@babel/core' - '@babel/traverse' @@ -36141,7 +35866,7 @@ snapshots: - vue-tsc - webpack-cli - '@nx/rollup@22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)': + '@nx/rollup@22.5.4(@babel/core@7.29.7)(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/babel__core@7.20.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)': dependencies: '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) @@ -36150,7 +35875,7 @@ snapshots: '@rollup/plugin-image': 3.0.3(rollup@4.59.0) '@rollup/plugin-json': 6.1.0(rollup@4.59.0) '@rollup/plugin-node-resolve': 15.3.1(rollup@4.59.0) - '@rollup/plugin-typescript': 12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@6.0.3) + '@rollup/plugin-typescript': 12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@7.0.2) autoprefixer: 10.4.20(postcss@8.5.10) concat-with-sourcemaps: 1.1.0 picocolors: 1.1.1 @@ -36158,7 +35883,7 @@ snapshots: postcss: 8.5.10 postcss-modules: 6.0.1(postcss@8.5.10) rollup: 4.59.0 - rollup-plugin-typescript2: 0.36.0(rollup@4.59.0)(typescript@6.0.3) + rollup-plugin-typescript2: 0.36.0(rollup@4.59.0)(typescript@7.0.2) tslib: 2.8.1 transitivePeerDependencies: - '@babel/core' @@ -36172,12 +35897,12 @@ snapshots: - typescript - verdaccio - '@nx/vite@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))': + '@nx/vite@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))': dependencies: '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) - '@nx/vitest': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)) - '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.3) + '@nx/vitest': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)) + '@phenomnomnominal/tsquery': 6.1.4(typescript@7.0.2) ajv: 8.18.0 enquirer: 2.3.6 picomatch: 4.0.2 @@ -36197,11 +35922,11 @@ snapshots: - verdaccio optional: true - '@nx/vitest@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))': + '@nx/vitest@22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vite@7.3.5(@types/node@26.1.0)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0)(yaml@2.9.0))(vitest@1.6.1(@edge-runtime/vm@3.2.0)(@types/node@26.1.0)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.98.0)(sass@1.98.0)(terser@5.48.0))': dependencies: '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) - '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.3) + '@phenomnomnominal/tsquery': 6.1.4(typescript@7.0.2) semver: 7.6.3 tslib: 2.8.1 optionalDependencies: @@ -36235,12 +35960,12 @@ snapshots: - supports-color - verdaccio - '@nx/webpack@22.5.4(@babel/traverse@7.29.7)(@rspack/core@1.6.8(@swc/helpers@0.5.23))(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@6.0.3)(vue-template-compiler@2.7.16)(webpack-cli@5.1.4)': + '@nx/webpack@22.5.4(@babel/traverse@7.29.7)(@rspack/core@1.6.8(@swc/helpers@0.5.23))(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(html-webpack-plugin@5.6.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(typescript@7.0.2)(vue-template-compiler@2.7.16)(webpack-cli@5.1.4)': dependencies: '@babel/core': 7.29.0 '@nx/devkit': 22.5.4(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) '@nx/js': 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))) - '@phenomnomnominal/tsquery': 6.1.4(typescript@6.0.3) + '@phenomnomnominal/tsquery': 6.1.4(typescript@7.0.2) ajv: 8.18.0 autoprefixer: 10.4.20(postcss@8.4.49) babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) @@ -36248,7 +35973,7 @@ snapshots: copy-webpack-plugin: 10.2.4(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) css-loader: 6.11.0(@rspack/core@1.6.8(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) css-minimizer-webpack-plugin: 5.0.1(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) - fork-ts-checker-webpack-plugin: 7.2.13(typescript@6.0.3)(vue-template-compiler@2.7.16)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) + fork-ts-checker-webpack-plugin: 7.2.13(typescript@7.0.2)(vue-template-compiler@2.7.16)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) less: 4.6.4 less-loader: 11.1.4(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) license-webpack-plugin: 4.0.2(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) @@ -36266,7 +35991,7 @@ snapshots: source-map-loader: 5.0.0(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) style-loader: 3.3.4(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) terser-webpack-plugin: 5.4.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) - ts-loader: 9.5.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) + ts-loader: 9.5.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)) tsconfig-paths-webpack-plugin: 4.2.0 tslib: 2.8.1 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) @@ -36520,11 +36245,11 @@ snapshots: tslib: 2.8.1 tsyringe: 4.10.0 - '@phenomnomnominal/tsquery@6.1.4(typescript@6.0.3)': + '@phenomnomnominal/tsquery@6.1.4(typescript@7.0.2)': dependencies: '@types/esquery': 1.5.4 esquery: 1.7.0 - typescript: 6.0.3 + typescript: 7.0.2 '@pinojs/redact@0.4.0': {} @@ -38566,7 +38291,7 @@ snapshots: '@react-native/babel-plugin-codegen@0.80.0(@babel/core@7.29.0)': dependencies: - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 '@react-native/codegen': 0.80.0(@babel/core@7.29.0) transitivePeerDependencies: - '@babel/core' @@ -39159,11 +38884,11 @@ snapshots: optionalDependencies: rollup: 4.59.0 - '@rollup/plugin-typescript@12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@6.0.3)': + '@rollup/plugin-typescript@12.3.0(rollup@4.59.0)(tslib@2.8.1)(typescript@7.0.2)': dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) resolve: 1.22.8 - typescript: 6.0.3 + typescript: 7.0.2 optionalDependencies: rollup: 4.59.0 tslib: 2.8.1 @@ -39346,9 +39071,9 @@ snapshots: transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(core-js@3.49.0)': + '@rsbuild/core@2.1.4(@module-federation/runtime-tools@0.21.6)(core-js@3.49.0)': dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@0.21.6)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.49.0 @@ -39373,10 +39098,6 @@ snapshots: transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/plugin-assets-retry@1.5.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-assets-retry@1.5.2(@rsbuild/core@1.7.3)': optionalDependencies: '@rsbuild/core': 1.7.3 @@ -39466,16 +39187,6 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-check-syntax@1.6.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - dependencies: - acorn: 8.17.0 - browserslist-to-es-version: 1.4.1 - htmlparser2: 10.0.0 - picocolors: 1.1.1 - source-map: 0.7.6 - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-check-syntax@2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': dependencies: acorn: 8.17.0 @@ -39531,27 +39242,12 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-css-minimizer@1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': - dependencies: - css-minimizer-webpack-plugin: 7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - reduce-configs: 1.1.2 - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - transitivePeerDependencies: - - '@parcel/css' - - '@swc/css' - - clean-css - - csso - - esbuild - - lightningcss - - webpack - - '@rsbuild/plugin-css-minimizer@1.1.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: - css-minimizer-webpack-plugin: 7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + css-minimizer-webpack-plugin: 8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: - '@parcel/css' - '@swc/css' @@ -39561,9 +39257,9 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: - css-minimizer-webpack-plugin: 8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + css-minimizer-webpack-plugin: 8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) reduce-configs: 1.1.2 optionalDependencies: '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) @@ -39582,17 +39278,23 @@ snapshots: deepmerge: 4.3.1 reduce-configs: 1.1.2 - '@rsbuild/plugin-less@1.6.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) deepmerge: 4.3.1 + less: 4.6.4 + less-loader: 12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) reduce-configs: 1.1.2 + optionalDependencies: + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + transitivePeerDependencies: + - '@rspack/core' + - webpack - '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: deepmerge: 4.3.1 less: 4.6.4 - less-loader: 12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + less-loader: 12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) reduce-configs: 1.1.2 optionalDependencies: '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) @@ -39665,14 +39367,6 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-react@1.4.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1)': - dependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rspack/plugin-react-refresh': 1.6.1(react-refresh@0.18.0)(webpack-hot-middleware@2.26.1) - react-refresh: 0.18.0 - transitivePeerDependencies: - - webpack-hot-middleware - '@rsbuild/plugin-react@1.4.5(@rsbuild/core@1.3.21)(webpack-hot-middleware@2.26.1)': dependencies: '@rsbuild/core': 1.3.21 @@ -39689,14 +39383,6 @@ snapshots: transitivePeerDependencies: - webpack-hot-middleware - '@rsbuild/plugin-react@1.4.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1)': - dependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rspack/plugin-react-refresh': 1.6.1(react-refresh@0.18.0)(webpack-hot-middleware@2.26.1) - react-refresh: 0.18.0 - transitivePeerDependencies: - - webpack-hot-middleware - '@rsbuild/plugin-react@1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1)': dependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) @@ -39714,6 +39400,15 @@ snapshots: transitivePeerDependencies: - '@rspack/core' + '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + dependencies: + '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + transitivePeerDependencies: + - '@rspack/core' + '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': dependencies: '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) @@ -39732,6 +39427,15 @@ snapshots: transitivePeerDependencies: - '@rspack/core' + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + dependencies: + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + react-refresh: 0.18.0 + optionalDependencies: + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + transitivePeerDependencies: + - '@rspack/core' + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@0.7.5(@swc/helpers@0.5.23))': dependencies: '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@0.7.5(@swc/helpers@0.5.23))(react-refresh@0.18.0) @@ -39762,17 +39466,10 @@ snapshots: '@rsbuild/plugin-rem@1.0.5(@rsbuild/core@1.7.3)': dependencies: deepmerge: 4.3.1 - terser: 5.46.1 + terser: 5.48.0 optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-rem@1.0.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - dependencies: - deepmerge: 4.3.1 - terser: 5.46.1 - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-rem@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': dependencies: deepmerge: 4.3.1 @@ -39789,15 +39486,6 @@ snapshots: reduce-configs: 1.1.2 sass-embedded: 1.100.0 - '@rsbuild/plugin-sass@1.5.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - dependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - deepmerge: 4.3.1 - loader-utils: 2.0.4 - postcss: 8.5.10 - reduce-configs: 1.1.2 - sass-embedded: 1.100.0 - '@rsbuild/plugin-sass@1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': dependencies: deepmerge: 4.3.1 @@ -39822,18 +39510,10 @@ snapshots: dependencies: fast-glob: 3.3.3 json5: 2.2.3 - yaml: 2.8.2 + yaml: 2.9.0 optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-source-build@1.0.4(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - dependencies: - fast-glob: 3.3.3 - json5: 2.2.3 - yaml: 2.8.2 - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-source-build@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': dependencies: fast-glob: 3.3.3 @@ -39849,13 +39529,13 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-svgr@1.3.0(@rsbuild/core@1.7.3)(typescript@6.0.3)(webpack-hot-middleware@2.26.1)': + '@rsbuild/plugin-svgr@1.3.0(@rsbuild/core@1.7.3)(typescript@7.0.2)(webpack-hot-middleware@2.26.1)': dependencies: '@rsbuild/core': 1.7.3 '@rsbuild/plugin-react': 1.4.5(@rsbuild/core@1.7.3)(webpack-hot-middleware@2.26.1) - '@svgr/core': 8.1.0(typescript@6.0.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@6.0.3) + '@svgr/core': 8.1.0(typescript@7.0.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2))(typescript@7.0.2) deepmerge: 4.3.1 loader-utils: 3.3.1 transitivePeerDependencies: @@ -39863,26 +39543,27 @@ snapshots: - typescript - webpack-hot-middleware - '@rsbuild/plugin-svgr@1.3.0(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@5.0.4)(webpack-hot-middleware@2.26.1)': + '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@7.0.2)': dependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-react': 1.4.5(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) - '@svgr/core': 8.1.0(typescript@5.0.4) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@5.0.4) + '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + '@svgr/core': 8.1.0(typescript@7.0.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2))(typescript@7.0.2) deepmerge: 4.3.1 loader-utils: 3.3.1 + optionalDependencies: + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: + - '@rspack/core' - supports-color - typescript - - webpack-hot-middleware - '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@6.0.3)': + '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(typescript@7.0.2)': dependencies: - '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) - '@svgr/core': 8.1.0(typescript@6.0.3) + '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + '@svgr/core': 8.1.0(typescript@7.0.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@6.0.3) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@7.0.2) deepmerge: 4.3.1 loader-utils: 3.3.1 optionalDependencies: @@ -39898,12 +39579,12 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-type-check@1.3.3(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3)': + '@rsbuild/plugin-type-check@1.3.3(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3) + ts-checker-rspack-plugin: 1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: '@rsbuild/core': 1.7.3 transitivePeerDependencies: @@ -39911,53 +39592,53 @@ snapshots: - tslib - typescript - '@rsbuild/plugin-type-check@1.3.3(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@5.0.4)': + '@rsbuild/plugin-type-check@1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.3.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@5.0.4) + ts-checker-rspack-plugin: 1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 1.7.3 transitivePeerDependencies: - '@rspack/core' - tslib - typescript - '@rsbuild/plugin-type-check@1.3.4(@rsbuild/core@1.7.3)(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@6.0.3)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@6.0.3) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 1.7.3 + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib - typescript - '@rsbuild/plugin-type-check@1.3.4(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@6.0.3)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.3.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@6.0.3) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib - typescript - '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib @@ -39967,10 +39648,6 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-typed-css-modules@1.2.1(@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': - optionalDependencies: - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-typed-css-modules@1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': optionalDependencies: '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) @@ -39986,9 +39663,9 @@ snapshots: - '@babel/core' - supports-color - '@rsbuild/plugin-vue@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.9.3))': + '@rsbuild/plugin-vue@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2))': dependencies: - rspack-vue-loader: 17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.9.3)) + rspack-vue-loader: 17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) optionalDependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) transitivePeerDependencies: @@ -40062,28 +39739,18 @@ snapshots: - uglify-js - webpack-cli - '@rslib/core@0.12.4(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(typescript@6.0.3)': + '@rslib/core@0.12.4(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(typescript@7.0.2)': dependencies: '@rsbuild/core': 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) - rsbuild-plugin-dts: 0.12.4(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@6.0.3) + rsbuild-plugin-dts: 0.12.4(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@7.0.2) tinyglobby: 0.2.15 optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' - '@rslib/core@0.18.5(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(typescript@6.0.3)': - dependencies: - '@rsbuild/core': 1.7.3 - rsbuild-plugin-dts: 0.18.5(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@1.7.3)(typescript@6.0.3) - optionalDependencies: - '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) - typescript: 6.0.3 - transitivePeerDependencies: - - '@typescript/native-preview' - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(typescript@6.0.3)': dependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1) @@ -40120,13 +39787,13 @@ snapshots: - '@typescript/native-preview' - core-js - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3)': + '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2)': dependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3) + rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@7.0.2) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@typescript/native-preview' @@ -40740,7 +40407,7 @@ snapshots: dependencies: '@module-federation/runtime-tools': 0.1.6 '@rspack/binding': 0.7.5 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 tapable: 2.2.1 webpack-sources: 3.2.3 optionalDependencies: @@ -40751,7 +40418,7 @@ snapshots: '@module-federation/runtime-tools': 0.5.1 '@rspack/binding': 1.0.14 '@rspack/lite-tapable': 1.0.1 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 optionalDependencies: '@swc/helpers': 0.5.17 @@ -40760,7 +40427,7 @@ snapshots: '@module-federation/runtime-tools': 0.13.1 '@rspack/binding': 1.3.11 '@rspack/lite-tapable': 1.0.1 - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 optionalDependencies: '@swc/helpers': 0.5.17 @@ -40865,11 +40532,11 @@ snapshots: '@module-federation/runtime-tools': 2.7.0 '@swc/helpers': 0.5.23 - '@rspack/core@2.1.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(@swc/helpers@0.5.23)': + '@rspack/core@2.1.2(@module-federation/runtime-tools@0.21.6)(@swc/helpers@0.5.23)': dependencies: '@rspack/binding': 2.1.2 optionalDependencies: - '@module-federation/runtime-tools': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) + '@module-federation/runtime-tools': 0.21.6 '@swc/helpers': 0.5.23 '@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)': @@ -41108,10 +40775,11 @@ snapshots: fs-extra: 11.3.0 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 optionalDependencies: '@types/node': 20.19.5 + optional: true '@rushstack/node-core-library@5.20.3(@types/node@22.19.15)': dependencies: @@ -41121,7 +40789,7 @@ snapshots: fs-extra: 11.3.0 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 optionalDependencies: '@types/node': 22.19.15 @@ -41135,14 +40803,16 @@ snapshots: fs-extra: 11.3.0 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.8 + resolve: 1.22.11 semver: 7.5.4 optionalDependencies: '@types/node': 26.1.0 + optional: true '@rushstack/problem-matcher@0.2.1(@types/node@20.19.5)': optionalDependencies: '@types/node': 20.19.5 + optional: true '@rushstack/problem-matcher@0.2.1(@types/node@22.19.15)': optionalDependencies: @@ -41152,11 +40822,13 @@ snapshots: '@rushstack/problem-matcher@0.2.1(@types/node@26.1.0)': optionalDependencies: '@types/node': 26.1.0 + optional: true '@rushstack/rig-package@0.7.2': dependencies: resolve: 1.22.11 strip-json-comments: 3.1.1 + optional: true '@rushstack/terminal@0.22.3(@types/node@20.19.5)': dependencies: @@ -41165,6 +40837,7 @@ snapshots: supports-color: 8.1.1 optionalDependencies: '@types/node': 20.19.5 + optional: true '@rushstack/terminal@0.22.3(@types/node@22.19.15)': dependencies: @@ -41182,6 +40855,7 @@ snapshots: supports-color: 8.1.1 optionalDependencies: '@types/node': 26.1.0 + optional: true '@rushstack/ts-command-line@5.3.3(@types/node@20.19.5)': dependencies: @@ -41191,6 +40865,7 @@ snapshots: string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' + optional: true '@rushstack/ts-command-line@5.3.3(@types/node@22.19.15)': dependencies: @@ -41210,6 +40885,7 @@ snapshots: string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' + optional: true '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -41818,21 +41494,21 @@ snapshots: '@storybook/preview@7.6.24': {} - '@storybook/react-docgen-typescript-plugin@1.0.1(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4))': + '@storybook/react-docgen-typescript-plugin@1.0.1(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 micromatch: 4.0.8 - react-docgen-typescript: 2.4.0(typescript@6.0.3) + react-docgen-typescript: 2.4.0(typescript@7.0.2) tslib: 2.8.1 - typescript: 6.0.3 + typescript: 7.0.2 webpack: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@6.0.3)(webpack@5.104.1)': dependencies: debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 @@ -41842,21 +41518,21 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@6.0.3) tslib: 2.8.1 typescript: 6.0.3 - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4) + webpack: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@6.0.3)(webpack@5.104.1)': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': dependencies: debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 micromatch: 4.0.8 - react-docgen-typescript: 2.4.0(typescript@6.0.3) + react-docgen-typescript: 2.4.0(typescript@7.0.2) tslib: 2.8.1 - typescript: 6.0.3 - webpack: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) + typescript: 7.0.2 + webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color @@ -41883,7 +41559,7 @@ snapshots: react-dom: 19.2.7(react@19.2.7) storybook: 8.6.17(prettier@3.8.1) - '@storybook/react@7.6.24(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@6.0.3)': + '@storybook/react@7.6.24(encoding@0.1.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2)': dependencies: '@storybook/client-logger': 7.6.24 '@storybook/core-client': 7.6.24 @@ -41909,12 +41585,12 @@ snapshots: type-fest: 2.19.0 util-deprecate: 1.0.2 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - encoding - supports-color - '@storybook/react@8.6.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.17(prettier@3.8.1))(typescript@6.0.3)': + '@storybook/react@8.6.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.17(prettier@3.8.1))(typescript@7.0.2)': dependencies: '@storybook/components': 8.6.18(storybook@8.6.17(prettier@3.8.1)) '@storybook/global': 5.0.0 @@ -41926,7 +41602,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) storybook: 8.6.17(prettier@3.8.1) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 '@storybook/react@9.0.9(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@8.6.17(prettier@3.8.1))(typescript@6.0.3)': dependencies: @@ -41986,67 +41662,67 @@ snapshots: '@types/express': 4.17.21 file-system-cache: 2.3.0 - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.0)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 - '@svgr/babel-preset@8.1.0(@babel/core@7.29.0)': + '@svgr/babel-preset@8.1.0(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.0) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.0) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.29.7) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.29.7) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.29.7) - '@svgr/core@8.1.0(typescript@5.0.4)': + '@svgr/core@8.1.0(typescript@6.0.3)': dependencies: - '@babel/core': 7.29.0 - '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.0.4) + cosmiconfig: 8.3.6(typescript@6.0.3) snake-case: 3.0.4 transitivePeerDependencies: - supports-color - typescript - '@svgr/core@8.1.0(typescript@6.0.3)': + '@svgr/core@8.1.0(typescript@7.0.2)': dependencies: - '@babel/core': 7.29.0 - '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@6.0.3) + cosmiconfig: 8.3.6(typescript@7.0.2) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -42059,27 +41735,46 @@ snapshots: '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))': dependencies: - '@babel/core': 7.29.0 - '@svgr/babel-preset': 8.1.0(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) '@svgr/core': 8.1.0(typescript@6.0.3) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@5.0.4)': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@7.0.2))': + dependencies: + '@babel/core': 7.29.7 + '@svgr/babel-preset': 8.1.0(@babel/core@7.29.7) + '@svgr/core': 8.1.0(typescript@7.0.2) + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@6.0.3)': dependencies: '@svgr/core': 8.1.0(typescript@6.0.3) - cosmiconfig: 8.3.6(typescript@5.0.4) + cosmiconfig: 8.3.6(typescript@6.0.3) deepmerge: 4.3.1 svgo: 3.3.3 transitivePeerDependencies: - typescript - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@6.0.3)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@7.0.2)': dependencies: '@svgr/core': 8.1.0(typescript@6.0.3) - cosmiconfig: 8.3.6(typescript@6.0.3) + cosmiconfig: 8.3.6(typescript@7.0.2) + deepmerge: 4.3.1 + svgo: 3.3.3 + transitivePeerDependencies: + - typescript + + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@7.0.2))(typescript@7.0.2)': + dependencies: + '@svgr/core': 8.1.0(typescript@7.0.2) + cosmiconfig: 8.3.6(typescript@7.0.2) deepmerge: 4.3.1 svgo: 3.3.3 transitivePeerDependencies: @@ -42099,6 +41794,20 @@ snapshots: - supports-color - typescript + '@svgr/webpack@8.1.0(typescript@7.0.2)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.2(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@svgr/core': 8.1.0(typescript@7.0.2) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@7.0.2) + transitivePeerDependencies: + - supports-color + - typescript + '@swc-node/core@1.14.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)': dependencies: '@swc/core': 1.7.26(@swc/helpers@0.5.13) @@ -42144,9 +41853,6 @@ snapshots: - react-native-b4a - supports-color - '@swc/core-darwin-arm64@1.15.10': - optional: true - '@swc/core-darwin-arm64@1.15.41': optional: true @@ -42156,9 +41862,6 @@ snapshots: '@swc/core-darwin-arm64@1.7.26': optional: true - '@swc/core-darwin-x64@1.15.10': - optional: true - '@swc/core-darwin-x64@1.15.41': optional: true @@ -42168,9 +41871,6 @@ snapshots: '@swc/core-darwin-x64@1.7.26': optional: true - '@swc/core-linux-arm-gnueabihf@1.15.10': - optional: true - '@swc/core-linux-arm-gnueabihf@1.15.41': optional: true @@ -42180,9 +41880,6 @@ snapshots: '@swc/core-linux-arm-gnueabihf@1.7.26': optional: true - '@swc/core-linux-arm64-gnu@1.15.10': - optional: true - '@swc/core-linux-arm64-gnu@1.15.41': optional: true @@ -42192,9 +41889,6 @@ snapshots: '@swc/core-linux-arm64-gnu@1.7.26': optional: true - '@swc/core-linux-arm64-musl@1.15.10': - optional: true - '@swc/core-linux-arm64-musl@1.15.41': optional: true @@ -42210,9 +41904,6 @@ snapshots: '@swc/core-linux-s390x-gnu@1.15.41': optional: true - '@swc/core-linux-x64-gnu@1.15.10': - optional: true - '@swc/core-linux-x64-gnu@1.15.41': optional: true @@ -42222,9 +41913,6 @@ snapshots: '@swc/core-linux-x64-gnu@1.7.26': optional: true - '@swc/core-linux-x64-musl@1.15.10': - optional: true - '@swc/core-linux-x64-musl@1.15.41': optional: true @@ -42234,9 +41922,6 @@ snapshots: '@swc/core-linux-x64-musl@1.7.26': optional: true - '@swc/core-win32-arm64-msvc@1.15.10': - optional: true - '@swc/core-win32-arm64-msvc@1.15.41': optional: true @@ -42246,9 +41931,6 @@ snapshots: '@swc/core-win32-arm64-msvc@1.7.26': optional: true - '@swc/core-win32-ia32-msvc@1.15.10': - optional: true - '@swc/core-win32-ia32-msvc@1.15.41': optional: true @@ -42258,9 +41940,6 @@ snapshots: '@swc/core-win32-ia32-msvc@1.7.26': optional: true - '@swc/core-win32-x64-msvc@1.15.10': - optional: true - '@swc/core-win32-x64-msvc@1.15.41': optional: true @@ -42270,23 +41949,6 @@ snapshots: '@swc/core-win32-x64-msvc@1.7.26': optional: true - '@swc/core@1.15.10(@swc/helpers@0.5.17)': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.27 - optionalDependencies: - '@swc/core-darwin-arm64': 1.15.10 - '@swc/core-darwin-x64': 1.15.10 - '@swc/core-linux-arm-gnueabihf': 1.15.10 - '@swc/core-linux-arm64-gnu': 1.15.10 - '@swc/core-linux-arm64-musl': 1.15.10 - '@swc/core-linux-x64-gnu': 1.15.10 - '@swc/core-linux-x64-musl': 1.15.10 - '@swc/core-win32-arm64-msvc': 1.15.10 - '@swc/core-win32-ia32-msvc': 1.15.10 - '@swc/core-win32-x64-msvc': 1.15.10 - '@swc/helpers': 0.5.17 - '@swc/core@1.15.41(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 @@ -42349,7 +42011,7 @@ snapshots: '@swc/core@1.15.8(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.25 + '@swc/types': 0.1.27 optionalDependencies: '@swc/core-darwin-arm64': 1.15.8 '@swc/core-darwin-x64': 1.15.8 @@ -42442,23 +42104,23 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/forms@0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)))': + '@tailwindcss/forms@0.5.7(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))': dependencies: mini-svg-data-uri: 1.4.4 - tailwindcss: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)) + tailwindcss: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) '@tailwindcss/forms@0.5.9(tailwindcss@3.4.13(ts-node@10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3)))': dependencies: mini-svg-data-uri: 1.4.4 tailwindcss: 3.4.13(ts-node@10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3)) - '@tailwindcss/typography@0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)))': + '@tailwindcss/typography@0.5.12(tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))': dependencies: lodash.castarray: 4.4.0 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 - tailwindcss: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)) + tailwindcss: 3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) '@tanstack/react-virtual@3.14.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: @@ -42471,7 +42133,7 @@ snapshots: '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.7 - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.28.2 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -42578,14 +42240,15 @@ snapshots: dependencies: '@types/node': 20.19.5 - '@types/argparse@1.0.38': {} + '@types/argparse@1.0.38': + optional: true '@types/aria-query@5.0.4': {} '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 @@ -43167,41 +42830,22 @@ snapshots: '@types/node': 20.19.5 optional: true - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@7.0.2) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@7.0.2) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@7.0.2) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare-lite: 1.4.0 semver: 7.6.3 - tsutils: 3.21.0(typescript@5.0.4) + tsutils: 3.21.0(typescript@7.0.2) optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1)(typescript@6.0.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3) - debug: 4.4.3(supports-color@8.1.1) - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare-lite: 1.4.0 - semver: 7.6.3 - tsutils: 3.21.0(typescript@6.0.3) - optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43255,19 +42899,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2))(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/parser': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) '@typescript-eslint/scope-manager': 8.57.1 - '@typescript-eslint/type-utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/type-utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) + '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) '@typescript-eslint/visitor-keys': 8.57.1 eslint: 9.26.0(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.4.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43287,40 +42931,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@7.0.2) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 optionalDependencies: - typescript: 5.0.4 + typescript: 7.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3)': - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3) - debug: 4.4.3(supports-color@8.1.1) - eslint: 8.57.1 - optionalDependencies: - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.4.5)': + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 6.21.0 '@typescript-eslint/types': 6.21.0 - '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 optionalDependencies: - typescript: 5.4.5 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -43361,15 +42993,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2)': dependencies: '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@7.0.2) '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3(supports-color@8.1.1) eslint: 9.26.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43403,21 +43035,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.1(typescript@5.4.5)': + '@typescript-eslint/project-service@8.57.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.4.5) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) '@typescript-eslint/types': 8.57.1 debug: 4.4.3(supports-color@8.1.1) - typescript: 5.4.5 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.57.1(typescript@6.0.3)': + '@typescript-eslint/project-service@8.57.1(typescript@7.0.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@7.0.2) '@typescript-eslint/types': 8.57.1 debug: 4.4.3(supports-color@8.1.1) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43459,35 +43091,23 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/tsconfig-utils@8.57.1(typescript@5.4.5)': - dependencies: - typescript: 5.4.5 - '@typescript-eslint/tsconfig-utils@8.57.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/tsconfig-utils@8.57.1(typescript@7.0.2)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) - debug: 4.4.3(supports-color@8.1.1) - eslint: 8.57.1 - tsutils: 3.21.0(typescript@5.0.4) - optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color + typescript: 7.0.2 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@6.0.3)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@7.0.2) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@7.0.2) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - tsutils: 3.21.0(typescript@6.0.3) + tsutils: 3.21.0(typescript@7.0.2) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43527,15 +43147,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/type-utils@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2)': dependencies: '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.4.5) - '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@7.0.2) + '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) debug: 4.4.3(supports-color@8.1.1) eslint: 9.26.0(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.4.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43577,7 +43197,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@5.62.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@7.0.2)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 @@ -43585,13 +43205,13 @@ snapshots: globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 - tsutils: 3.21.0(typescript@6.0.3) + tsutils: 3.21.0(typescript@7.0.2) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.21.0(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 @@ -43600,9 +43220,9 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.4.5) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.4.5 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -43651,33 +43271,33 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.57.1(typescript@5.4.5)': + '@typescript-eslint/typescript-estree@8.57.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.57.1(typescript@5.4.5) - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@5.4.5) + '@typescript-eslint/project-service': 8.57.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) '@typescript-eslint/types': 8.57.1 '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.4.5) - typescript: 5.4.5 + ts-api-utils: 2.4.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.57.1(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.57.1(typescript@7.0.2)': dependencies: - '@typescript-eslint/project-service': 8.57.1(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) + '@typescript-eslint/project-service': 8.57.1(typescript@7.0.2) + '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@7.0.2) '@typescript-eslint/types': 8.57.1 '@typescript-eslint/visitor-keys': 8.57.1 debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.4 semver: 7.7.4 tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@6.0.3) - typescript: 6.0.3 + ts-api-utils: 2.4.0(typescript@7.0.2) + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43696,14 +43316,14 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@6.0.3)': + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@7.0.2) eslint: 8.57.1 eslint-scope: 5.1.1 semver: 7.6.3 @@ -43744,14 +43364,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5)': + '@typescript-eslint/utils@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.26.0(jiti@2.6.1)) '@typescript-eslint/scope-manager': 8.57.1 '@typescript-eslint/types': 8.57.1 - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@7.0.2) eslint: 9.26.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43796,6 +43416,66 @@ snapshots: '@typescript-eslint/types': 8.57.1 eslint-visitor-keys: 5.0.1 + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + '@ungap/structured-clone@1.3.0': {} '@unhead/react@2.1.15(react@19.2.7)': @@ -44064,37 +43744,37 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@rolldown/pluginutils': 1.0.0-rc.9 '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) vite: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3))': + '@vitejs/plugin-vue-jsx@4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@rolldown/pluginutils': 1.0.0-rc.9 '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2))': dependencies: vite: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) - '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@6.0.3))': + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2))': dependencies: vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) '@vitest/expect@1.2.2': dependencies: @@ -44220,18 +43900,12 @@ snapshots: dependencies: '@volar/source-map': 2.4.15 - '@volar/language-core@2.4.28': - dependencies: - '@volar/source-map': 2.4.28 - '@volar/source-map@1.11.1': dependencies: muggle-string: 0.3.1 '@volar/source-map@2.4.15': {} - '@volar/source-map@2.4.28': {} - '@volar/typescript@1.11.1': dependencies: '@volar/language-core': 1.11.1 @@ -44243,12 +43917,6 @@ snapshots: path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@volar/typescript@2.4.28': - dependencies: - '@volar/language-core': 2.4.28 - path-browserify: 1.0.1 - vscode-uri: 3.1.0 - '@vscode/sudo-prompt@9.3.2': {} '@vue/babel-helper-vue-transform-on@1.5.0': {} @@ -44260,9 +43928,9 @@ snapshots: '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 '@vue/babel-helper-vue-transform-on': 1.5.0 '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.29.0) '@vue/shared': 3.5.30 @@ -44276,9 +43944,9 @@ snapshots: '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.7) - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 '@vue/babel-helper-vue-transform-on': 1.5.0 '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.29.7) '@vue/shared': 3.5.30 @@ -44351,7 +44019,7 @@ snapshots: '@vue/compiler-sfc@3.5.30': dependencies: - '@babel/parser': 7.29.2 + '@babel/parser': 7.29.7 '@vue/compiler-core': 3.5.30 '@vue/compiler-dom': 3.5.30 '@vue/compiler-ssr': 3.5.30 @@ -44387,20 +44055,21 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@vue/language-core@2.2.0(typescript@6.0.3)': + '@vue/language-core@1.8.27(typescript@7.0.2)': dependencies: - '@volar/language-core': 2.4.28 + '@volar/language-core': 1.11.1 + '@volar/source-map': 1.11.1 '@vue/compiler-dom': 3.5.30 - '@vue/compiler-vue2': 2.7.16 '@vue/shared': 3.5.30 - alien-signals: 0.4.14 + computeds: 0.0.1 minimatch: 9.0.9 - muggle-string: 0.4.1 + muggle-string: 0.3.1 path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 - '@vue/language-core@2.2.12(typescript@5.9.3)': + '@vue/language-core@2.2.12(typescript@6.0.3)': dependencies: '@volar/language-core': 2.4.15 '@vue/compiler-dom': 3.5.30 @@ -44411,9 +44080,9 @@ snapshots: muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 - '@vue/language-core@2.2.12(typescript@6.0.3)': + '@vue/language-core@2.2.12(typescript@7.0.2)': dependencies: '@volar/language-core': 2.4.15 '@vue/compiler-dom': 3.5.30 @@ -44424,7 +44093,7 @@ snapshots: muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 '@vue/reactivity@3.5.30': dependencies: @@ -44442,17 +44111,17 @@ snapshots: '@vue/shared': 3.5.30 csstype: 3.2.3 - '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@5.9.3))': + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@6.0.3))': dependencies: '@vue/compiler-ssr': 3.5.30 '@vue/shared': 3.5.30 - vue: 3.5.30(typescript@5.9.3) + vue: 3.5.30(typescript@6.0.3) - '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@6.0.3))': + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@7.0.2))': dependencies: '@vue/compiler-ssr': 3.5.30 '@vue/shared': 3.5.30 - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) '@vue/shared@3.5.30': {} @@ -44781,7 +44450,7 @@ snapshots: acorn-globals@7.0.1: dependencies: - acorn: 8.16.0 + acorn: 8.17.0 acorn-walk: 8.3.5 acorn-import-attributes@1.9.5(acorn@8.16.0): @@ -44800,10 +44469,6 @@ snapshots: dependencies: acorn: 7.4.1 - acorn-jsx@5.3.2(acorn@8.16.0): - dependencies: - acorn: 8.16.0 - acorn-jsx@5.3.2(acorn@8.17.0): dependencies: acorn: 8.17.0 @@ -44816,7 +44481,7 @@ snapshots: acorn-walk@8.3.5: dependencies: - acorn: 8.16.0 + acorn: 8.17.0 acorn@7.4.1: {} @@ -44865,6 +44530,7 @@ snapshots: ajv-draft-04@1.0.0(ajv@8.18.0): optionalDependencies: ajv: 8.18.0 + optional: true ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: @@ -44897,8 +44563,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - alien-signals@0.4.14: {} - alien-signals@1.0.13: {} anser@1.4.10: {} @@ -45550,15 +45214,6 @@ snapshots: postcss-value-parser: 4.2.0 autoprefixer@10.4.23(postcss@8.5.10): - dependencies: - browserslist: 4.28.4 - caniuse-lite: 1.0.30001780 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.10 - postcss-value-parser: 4.2.0 - - autoprefixer@10.4.24(postcss@8.5.10): dependencies: browserslist: 4.28.4 caniuse-lite: 1.0.30001800 @@ -45723,7 +45378,7 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.29.2 + '@babel/runtime': 7.28.2 cosmiconfig: 7.1.0 resolve: 1.22.11 @@ -46192,7 +45847,7 @@ snapshots: browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001780 + caniuse-lite: 1.0.30001800 electron-to-chromium: 1.5.313 node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.24.4) @@ -46839,8 +46494,6 @@ snapshots: array-ify: 1.0.0 dot-prop: 5.3.0 - compare-versions@6.1.1: {} - component-emitter@1.3.1: {} compressible@2.0.18: @@ -46892,8 +46545,6 @@ snapshots: confbox@0.1.8: {} - confbox@0.2.4: {} - connect-history-api-fallback@2.0.0: {} connect@3.7.0: @@ -47087,23 +46738,23 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cosmiconfig@8.3.6(typescript@5.0.4): + cosmiconfig@8.3.6(typescript@6.0.3): dependencies: import-fresh: 3.3.1 js-yaml: 4.2.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.0.4 + typescript: 6.0.3 - cosmiconfig@8.3.6(typescript@6.0.3): + cosmiconfig@8.3.6(typescript@7.0.2): dependencies: import-fresh: 3.3.1 js-yaml: 4.2.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 cosmiconfig@9.0.1(typescript@5.0.4): dependencies: @@ -47311,31 +46962,19 @@ snapshots: optionalDependencies: esbuild: 0.25.5 - css-minimizer-webpack-plugin@7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - cssnano: 7.1.3(postcss@8.5.10) - jest-worker: 29.7.0 - postcss: 8.5.10 - schema-utils: 4.3.0 - serialize-javascript: 6.0.2 - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) - optionalDependencies: - esbuild: 0.25.5 - - css-minimizer-webpack-plugin@7.0.2(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): + css-minimizer-webpack-plugin@8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: '@jridgewell/trace-mapping': 0.3.31 cssnano: 7.1.3(postcss@8.5.10) - jest-worker: 29.7.0 + jest-worker: 30.4.1 postcss: 8.5.10 schema-utils: 4.3.0 - serialize-javascript: 6.0.2 - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) + serialize-javascript: 7.0.7 + webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4) optionalDependencies: - esbuild: 0.25.5 + esbuild: 0.28.1 - css-minimizer-webpack-plugin@8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)): + css-minimizer-webpack-plugin@8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): dependencies: '@jridgewell/trace-mapping': 0.3.31 cssnano: 7.1.3(postcss@8.5.10) @@ -47343,7 +46982,7 @@ snapshots: postcss: 8.5.10 schema-utils: 4.3.0 serialize-javascript: 7.0.7 - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4) + webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) optionalDependencies: esbuild: 0.28.1 @@ -48048,7 +47687,8 @@ snapshots: diff@4.0.4: {} - diff@8.0.3: {} + diff@8.0.3: + optional: true diffie-hellman@5.0.3: dependencies: @@ -48806,7 +48446,7 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-next@16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5): + eslint-config-next@16.0.10(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2): dependencies: '@next/eslint-plugin-next': 16.0.10 eslint: 9.26.0(jiti@2.6.1) @@ -48817,9 +48457,9 @@ snapshots: eslint-plugin-react: 7.37.2(eslint@9.26.0(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.26.0(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + typescript-eslint: 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) optionalDependencies: - typescript: 5.4.5 + typescript: 7.0.2 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-webpack @@ -48857,21 +48497,11 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): dependencies: debug: 3.2.7(supports-color@8.1.1) optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.0.4) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7(supports-color@8.1.1) - optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -48930,7 +48560,7 @@ snapshots: lodash: 4.18.1 string-natural-compare: 3.0.1 - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -48941,7 +48571,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@7.0.2))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -48953,36 +48583,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.0.4) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7(supports-color@8.1.1) - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@6.0.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.5 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@6.0.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@7.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -49422,8 +49023,8 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 4.2.1 espree@9.6.1: @@ -50078,9 +49679,9 @@ snapshots: forever-agent@0.6.1: {} - fork-ts-checker-webpack-plugin@7.2.13(typescript@6.0.3)(vue-template-compiler@2.7.16)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): + fork-ts-checker-webpack-plugin@7.2.13(typescript@7.0.2)(vue-template-compiler@2.7.16)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.29.7 chalk: 4.1.2 chokidar: 3.6.0 cosmiconfig: 7.1.0 @@ -50092,7 +49693,7 @@ snapshots: schema-utils: 3.3.0 semver: 7.6.3 tapable: 2.3.0 - typescript: 6.0.3 + typescript: 7.0.2 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) optionalDependencies: vue-template-compiler: 2.7.16 @@ -50934,7 +50535,7 @@ snapshots: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.46.1 + terser: 5.48.0 html-parse-stringify@3.0.1: dependencies: @@ -51275,7 +50876,8 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-lazy@4.0.0: {} + import-lazy@4.0.0: + optional: true import-local@3.2.0: dependencies: @@ -51744,7 +51346,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -51887,10 +51489,10 @@ snapshots: jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) + babel-jest: 29.7.0(@babel/core@7.29.7) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -51918,10 +51520,10 @@ snapshots: jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) + babel-jest: 29.7.0(@babel/core@7.29.7) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -51949,10 +51551,10 @@ snapshots: jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) + babel-jest: 29.7.0(@babel/core@7.29.7) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -51980,10 +51582,10 @@ snapshots: jest-config@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) + babel-jest: 29.7.0(@babel/core@7.29.7) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -52317,7 +51919,8 @@ snapshots: jiti@2.6.1: {} - jju@1.4.0: {} + jju@1.4.0: + optional: true joi@17.13.3: dependencies: @@ -52395,7 +51998,7 @@ snapshots: jsdom@20.0.3: dependencies: abab: 2.0.6 - acorn: 8.16.0 + acorn: 8.17.0 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 @@ -52567,8 +52170,6 @@ snapshots: type-is: 2.0.1 vary: 1.1.2 - kolorist@1.8.0: {} - language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -52606,6 +52207,13 @@ snapshots: '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4) + less-loader@12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): + dependencies: + less: 4.6.4 + optionalDependencies: + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) + less@4.6.4: dependencies: copy-anything: 3.0.5 @@ -52754,15 +52362,9 @@ snapshots: local-pkg@0.5.1: dependencies: - mlly: 1.8.1 + mlly: 1.8.2 pkg-types: 1.3.1 - local-pkg@1.1.2: - dependencies: - mlly: 1.8.1 - pkg-types: 2.3.0 - quansync: 0.2.11 - locate-path@3.0.0: dependencies: p-locate: 3.0.0 @@ -52818,7 +52420,8 @@ snapshots: lodash@4.17.21: {} - lodash@4.17.23: {} + lodash@4.17.23: + optional: true lodash@4.18.1: {} @@ -53419,7 +53022,7 @@ snapshots: metro-minify-terser@0.82.5: dependencies: flow-enums-runtime: 0.0.6 - terser: 5.46.1 + terser: 5.48.0 metro-minify-terser@0.83.5: dependencies: @@ -53500,7 +53103,7 @@ snapshots: '@babel/core': 7.29.0 '@babel/generator': 7.29.7 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.0 + '@babel/traverse': 7.29.7 flow-enums-runtime: 0.0.6 nullthrows: 1.1.1 transitivePeerDependencies: @@ -54048,6 +53651,7 @@ snapshots: minimatch@10.2.3: dependencies: brace-expansion: 5.0.4 + optional: true minimatch@10.2.4: dependencies: @@ -55239,12 +54843,6 @@ snapshots: mlly: 1.8.2 pathe: 2.0.3 - pkg-types@2.3.0: - dependencies: - confbox: 0.2.4 - exsolve: 1.0.8 - pathe: 2.0.3 - pkg-up@3.1.0: dependencies: find-up: 3.0.0 @@ -55481,13 +55079,13 @@ snapshots: postcss: 8.4.49 ts-node: 10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3) - postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: lilconfig: 3.1.3 yaml: 2.8.2 optionalDependencies: postcss: 8.4.49 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3)): dependencies: @@ -55497,6 +55095,14 @@ snapshots: postcss: 8.4.49 ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3) + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): + dependencies: + lilconfig: 3.1.3 + yaml: 2.8.2 + optionalDependencies: + postcss: 8.4.49 + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2) + postcss-load-config@4.0.2(postcss@8.5.10)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@22.19.15)(typescript@6.0.3)): dependencies: lilconfig: 3.1.3 @@ -55505,13 +55111,13 @@ snapshots: postcss: 8.5.10 ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@22.19.15)(typescript@6.0.3) - postcss-load-config@4.0.2(postcss@8.5.10)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.5.10)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: lilconfig: 3.1.3 yaml: 2.8.2 optionalDependencies: postcss: 8.5.10 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3)): dependencies: @@ -55521,13 +55127,13 @@ snapshots: postcss: 8.5.15 ts-node: 10.9.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(@types/node@20.19.5)(typescript@6.0.3) - postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)): + postcss-load-config@4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: lilconfig: 3.1.3 yaml: 2.8.2 optionalDependencies: postcss: 8.5.15 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) postcss-loader@6.2.1(postcss@8.4.49)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: @@ -56048,7 +55654,7 @@ snapshots: prettier-eslint@16.3.0: dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.4.5) + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.9.3) common-tags: 1.8.2 dlv: 1.1.3 eslint: 8.57.1 @@ -56058,7 +55664,7 @@ snapshots: prettier: 3.8.1 pretty-format: 29.7.0 require-relative: 0.8.7 - typescript: 5.4.5 + typescript: 5.9.3 vue-eslint-parser: 9.4.3(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -57736,6 +57342,10 @@ snapshots: dependencies: typescript: 6.0.3 + react-docgen-typescript@2.4.0(typescript@7.0.2): + dependencies: + typescript: 7.0.2 + react-docgen@6.0.0-alpha.3: dependencies: '@babel/core': 7.29.7 @@ -58275,23 +57885,11 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): - dependencies: - acorn-loose: 8.5.2 - neo-async: 2.6.2 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) - webpack-sources: 3.5.0 - - react-server-dom-webpack@19.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): + react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - acorn-loose: 8.5.2 - neo-async: 2.6.2 + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) - webpack-sources: 3.5.0 react-server-dom-webpack@19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)): dependencies: @@ -58957,6 +58555,24 @@ snapshots: transitivePeerDependencies: - oxc-resolver + rolldown-plugin-dts@0.22.5(rolldown@1.0.0-rc.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@6.0.3)): + dependencies: + '@babel/generator': 8.0.0-rc.2 + '@babel/helper-validator-identifier': 8.0.0-rc.2 + '@babel/parser': 8.0.0-rc.2 + '@babel/types': 8.0.0-rc.2 + ast-kit: 3.0.0-beta.1 + birpc: 4.0.0 + dts-resolver: 2.1.3 + get-tsconfig: 4.13.6 + obug: 2.1.1 + rolldown: 1.0.0-rc.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optionalDependencies: + typescript: 7.0.2 + vue-tsc: 2.2.12(typescript@6.0.3) + transitivePeerDependencies: + - oxc-resolver + rolldown@1.0.0-rc.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1): dependencies: '@oxc-project/types': 0.112.0 @@ -59011,7 +58627,7 @@ snapshots: globby: 10.0.1 is-plain-object: 3.0.1 - rollup-plugin-typescript2@0.36.0(rollup@4.59.0)(typescript@6.0.3): + rollup-plugin-typescript2@0.36.0(rollup@4.59.0)(typescript@7.0.2): dependencies: '@rollup/pluginutils': 4.2.1 find-cache-dir: 3.3.2 @@ -59019,7 +58635,7 @@ snapshots: rollup: 4.59.0 semver: 7.6.3 tslib: 2.8.1 - typescript: 6.0.3 + typescript: 7.0.2 rollup@4.59.0: dependencies: @@ -59069,7 +58685,7 @@ snapshots: transitivePeerDependencies: - supports-color - rsbuild-plugin-dts@0.12.4(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@6.0.3): + rsbuild-plugin-dts@0.12.4(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@7.0.2): dependencies: '@ast-grep/napi': 0.37.0 '@rsbuild/core': 1.5.17(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) @@ -59079,15 +58695,7 @@ snapshots: tsconfig-paths: 4.2.0 optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) - typescript: 6.0.3 - - rsbuild-plugin-dts@0.18.5(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@1.7.3)(typescript@6.0.3): - dependencies: - '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 1.7.3 - optionalDependencies: - '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) - typescript: 6.0.3 + typescript: 7.0.2 rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1))(typescript@6.0.3): dependencies: @@ -59113,13 +58721,13 @@ snapshots: '@microsoft/api-extractor': 7.57.7(@types/node@22.19.15) typescript: 6.0.3 - rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3): + rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@7.0.2): dependencies: '@ast-grep/napi': 0.37.0 '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) - typescript: 6.0.3 + typescript: 7.0.2 rsbuild-plugin-dts@0.9.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@1.4.0-beta.2)(typescript@5.9.3): dependencies: @@ -59152,6 +58760,11 @@ snapshots: '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rsbuild-plugin-rsc@0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + dependencies: + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rslog@1.2.3: {} rslog@1.3.2: {} @@ -59168,25 +58781,25 @@ snapshots: optionalDependencies: '@rspack/core': 1.7.9(@swc/helpers@0.5.19) - rspack-manifest-plugin@5.2.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)): + rspack-manifest-plugin@5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)): dependencies: '@rspack/lite-tapable': 1.1.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) - rspack-manifest-plugin@5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)): + rspack-manifest-plugin@5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)): dependencies: '@rspack/lite-tapable': 1.1.2 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) - rspack-vue-loader@17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.9.3)): + rspack-vue-loader@17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)): dependencies: '@rspack/lite-tapable': 1.1.0 chalk: 4.1.2 optionalDependencies: '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) - vue: 3.5.30(typescript@5.9.3) + vue: 3.5.30(typescript@7.0.2) rstest-fetch-mock@0.1.0(@rstest/core@0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3)): dependencies: @@ -59546,6 +59159,7 @@ snapshots: semver@7.5.4: dependencies: lru-cache: 6.0.0 + optional: true semver@7.6.3: {} @@ -60055,18 +59669,18 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - storybook-addon-rslib@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3))(typescript@6.0.3): + storybook-addon-rslib@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2): dependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rslib/core': 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) - storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3) + '@rslib/core': 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 - storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3): + storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2): dependencies: '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-type-check': 1.3.4(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@6.0.3) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) '@storybook/addon-docs': 8.6.18(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1)) '@storybook/core-webpack': 8.6.18(storybook@8.6.17(prettier@3.8.1)) browser-assert: 1.2.1 @@ -60086,35 +59700,37 @@ snapshots: util: 0.12.5 util-deprecate: 1.0.2 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@rspack/core' - '@types/react' + - '@typescript/native-preview' - tslib - storybook-react-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)): + storybook-react-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@storybook/react': 8.6.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.17(prettier@3.8.1))(typescript@6.0.3) - '@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) + '@storybook/react': 8.6.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.17(prettier@3.8.1))(typescript@7.0.2) + '@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) '@types/node': 18.19.130 find-up: 5.0.0 magic-string: 0.30.21 react: 18.3.1 react-docgen: 7.1.1 - react-docgen-typescript: 2.4.0(typescript@6.0.3) + react-docgen-typescript: 2.4.0(typescript@7.0.2) react-dom: 18.3.1(react@18.3.1) resolve: 1.22.11 storybook: 8.6.17(prettier@3.8.1) - storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@6.0.3) + storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) tsconfig-paths: 4.2.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - '@rspack/core' - '@storybook/test' - '@types/react' + - '@typescript/native-preview' - rollup - supports-color - tslib @@ -60370,7 +59986,7 @@ snapshots: styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react-is@18.3.1)(react@19.2.4): dependencies: '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/traverse': 7.29.0(supports-color@5.5.0) + '@babel/traverse': 7.29.7(supports-color@5.5.0) '@emotion/is-prop-valid': 1.4.0 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 @@ -60388,7 +60004,7 @@ snapshots: styled-components@5.3.11(@babel/core@7.29.0)(react-dom@19.2.7(react@19.2.7))(react-is@18.3.1)(react@19.2.7): dependencies: '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/traverse': 7.29.0(supports-color@5.5.0) + '@babel/traverse': 7.29.7(supports-color@5.5.0) '@emotion/is-prop-valid': 1.4.0 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 @@ -60642,7 +60258,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)): + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -60661,7 +60277,7 @@ snapshots: postcss: 8.4.49 postcss-import: 15.1.0(postcss@8.4.49) postcss-js: 4.1.0(postcss@8.4.49) - postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) postcss-nested: 6.2.0(postcss@8.4.49) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -60696,6 +60312,33 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.49 + postcss-import: 15.1.0(postcss@8.4.49) + postcss-js: 4.1.0(postcss@8.4.49) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) + postcss-nested: 6.2.0(postcss@8.4.49) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.1 + transitivePeerDependencies: + - ts-node + tailwindcss@3.4.16(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@22.19.15)(typescript@6.0.3)): dependencies: '@alloc/quick-lru': 5.2.0 @@ -60723,7 +60366,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)): + tailwindcss@3.4.3(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -60742,7 +60385,7 @@ snapshots: postcss: 8.5.10 postcss-import: 15.1.0(postcss@8.5.10) postcss-js: 4.1.0(postcss@8.5.10) - postcss-load-config: 4.0.2(postcss@8.5.10)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.5.10)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) postcss-nested: 6.2.0(postcss@8.5.10) postcss-selector-parser: 6.1.2 resolve: 1.22.8 @@ -60840,7 +60483,7 @@ snapshots: jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.46.1 + terser: 5.48.0 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.15.8(@swc/helpers@0.5.17) @@ -60852,7 +60495,7 @@ snapshots: jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.46.1 + terser: 5.48.0 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.15.8(@swc/helpers@0.5.17) @@ -60864,7 +60507,7 @@ snapshots: jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 - terser: 5.46.1 + terser: 5.48.0 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.15.8(@swc/helpers@0.5.17) @@ -60914,17 +60557,6 @@ snapshots: '@swc/core': 1.15.41(@swc/helpers@0.5.19) esbuild: 0.25.5 - terser-webpack-plugin@5.4.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.3.0 - terser: 5.46.1 - webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) - optionalDependencies: - '@swc/core': 1.15.41(@swc/helpers@0.5.23) - esbuild: 0.25.5 - terser-webpack-plugin@5.4.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -61193,75 +60825,63 @@ snapshots: dependencies: typescript: 5.0.4 - ts-api-utils@1.4.3(typescript@5.4.5): - dependencies: - typescript: 5.4.5 - - ts-api-utils@2.4.0(typescript@5.4.5): + ts-api-utils@1.4.3(typescript@5.9.3): dependencies: - typescript: 5.4.5 + typescript: 5.9.3 ts-api-utils@2.4.0(typescript@6.0.3): dependencies: typescript: 6.0.3 - ts-checker-rspack-plugin@1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3): + ts-api-utils@2.4.0(typescript@7.0.2): dependencies: - '@rspack/lite-tapable': 1.1.0 - chokidar: 3.6.0 - memfs: 4.56.11(tslib@2.8.1) - picocolors: 1.1.1 - typescript: 6.0.3 - optionalDependencies: - '@rspack/core': 1.7.9(@swc/helpers@0.5.17) - transitivePeerDependencies: - - tslib + typescript: 7.0.2 - ts-checker-rspack-plugin@1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@6.0.3): + ts-checker-rspack-plugin@1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2): dependencies: - '@rspack/lite-tapable': 1.1.0 + '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 memfs: 4.56.11(tslib@2.8.1) picocolors: 1.1.1 - typescript: 6.0.3 + typescript: 7.0.2 optionalDependencies: - '@rspack/core': 1.7.9(@swc/helpers@0.5.19) + '@rspack/core': 1.7.9(@swc/helpers@0.5.17) transitivePeerDependencies: - tslib - ts-checker-rspack-plugin@1.3.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@5.0.4): + ts-checker-rspack-plugin@1.3.0(@rspack/core@1.7.9(@swc/helpers@0.5.19))(tslib@2.8.1)(typescript@7.0.2): dependencies: - '@rspack/lite-tapable': 1.1.0 + '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 memfs: 4.56.11(tslib@2.8.1) picocolors: 1.1.1 - typescript: 5.0.4 + typescript: 7.0.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 1.7.9(@swc/helpers@0.5.19) transitivePeerDependencies: - tslib - ts-checker-rspack-plugin@1.3.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@6.0.3): + ts-checker-rspack-plugin@1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2): dependencies: - '@rspack/lite-tapable': 1.1.0 + '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 - memfs: 4.56.11(tslib@2.8.1) + memfs: 4.58.0(tslib@2.8.1) picocolors: 1.1.1 - typescript: 6.0.3 + typescript: 7.0.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) transitivePeerDependencies: - tslib - ts-checker-rspack-plugin@1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@6.0.3): + ts-checker-rspack-plugin@1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2): dependencies: '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 memfs: 4.58.0(tslib@2.8.1) picocolors: 1.1.1 - typescript: 6.0.3 + typescript: 7.0.2 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) transitivePeerDependencies: - tslib @@ -61292,32 +60912,32 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.29.0) esbuild: 0.28.1 - ts-loader@9.4.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)): + ts-loader@9.4.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.20.1 micromatch: 4.0.8 semver: 7.6.3 - typescript: 6.0.3 + typescript: 7.0.2 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.25.5)(webpack-cli@5.1.4) - ts-loader@9.4.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)): + ts-loader@9.4.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.20.1 micromatch: 4.0.8 semver: 7.6.3 - typescript: 6.0.3 + typescript: 7.0.2 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4) - ts-loader@9.5.4(typescript@6.0.3)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): + ts-loader@9.5.4(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: chalk: 4.1.2 enhanced-resolve: 5.20.1 micromatch: 4.0.8 semver: 7.6.3 source-map: 0.7.6 - typescript: 6.0.3 + typescript: 7.0.2 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) ts-morph@12.0.0: @@ -61325,26 +60945,6 @@ snapshots: '@ts-morph/common': 0.11.1 code-block-writer: 10.1.1 - ts-node@10.8.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.5 - acorn: 8.16.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.0.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.15.41(@swc/helpers@0.5.23) - ts-node@10.9.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@14.18.33)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -61406,7 +61006,7 @@ snapshots: '@swc/core': 1.15.41(@swc/helpers@0.5.17) optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@6.0.3): + ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -61420,14 +61020,14 @@ snapshots: create-require: 1.1.1 diff: 4.0.4 make-error: 1.3.6 - typescript: 6.0.3 + typescript: 7.0.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: '@swc/core': 1.15.41(@swc/helpers@0.5.17) optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@6.0.3): + ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.19))(@types/node@20.19.5)(typescript@7.0.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -61441,7 +61041,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.4 make-error: 1.3.6 - typescript: 6.0.3 + typescript: 7.0.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: @@ -61469,7 +61069,7 @@ snapshots: '@swc/core': 1.15.41(@swc/helpers@0.5.23) optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.4.5): + ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -61483,14 +61083,13 @@ snapshots: create-require: 1.1.1 diff: 4.0.4 make-error: 1.3.6 - typescript: 5.4.5 + typescript: 6.0.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: '@swc/core': 1.15.41(@swc/helpers@0.5.23) - optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3): + ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.12 @@ -61504,7 +61103,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.4 make-error: 1.3.6 - typescript: 6.0.3 + typescript: 7.0.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: @@ -61552,6 +61151,27 @@ snapshots: '@swc/core': 1.15.41(@swc/helpers@0.5.23) optional: true + ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 26.1.0 + acorn: 8.17.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 7.0.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optionalDependencies: + '@swc/core': 1.15.41(@swc/helpers@0.5.23) + optional: true + ts-regex-builder@1.8.2: {} ts-toolbelt@6.15.5: {} @@ -61623,6 +61243,36 @@ snapshots: - synckit - vue-tsc + tsdown@0.20.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)(publint@0.3.18)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@6.0.3)): + dependencies: + ansis: 4.2.0 + cac: 6.7.14 + defu: 6.1.4 + empathic: 2.0.0 + hookable: 6.1.0 + import-without-cache: 0.2.5 + obug: 2.1.1 + picomatch: 4.0.3 + rolldown: 1.0.0-rc.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + rolldown-plugin-dts: 0.22.5(rolldown@1.0.0-rc.3(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1))(typescript@7.0.2)(vue-tsc@2.2.12(typescript@6.0.3)) + semver: 7.7.4 + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + unrun: 0.2.32(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optionalDependencies: + publint: 0.3.18 + typescript: 7.0.2 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + - '@ts-macro/tsc' + - '@typescript/native-preview' + - oxc-resolver + - synckit + - vue-tsc + tslib@1.14.1: {} tslib@2.3.0: {} @@ -61633,7 +61283,7 @@ snapshots: tsscmp@1.0.6: {} - tsup@7.3.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3))(typescript@6.0.3): + tsup@7.3.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(typescript@7.0.2): dependencies: bundle-require: 4.2.1(esbuild@0.19.12) cac: 6.7.14 @@ -61643,7 +61293,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3)) + postcss-load-config: 4.0.2(postcss@8.5.15)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) resolve-from: 5.0.0 rollup: 4.59.0 source-map: 0.8.0-beta.0 @@ -61652,7 +61302,7 @@ snapshots: optionalDependencies: '@swc/core': 1.15.41(@swc/helpers@0.5.23) postcss: 8.5.15 - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color - ts-node @@ -61686,10 +61336,10 @@ snapshots: tslib: 1.14.1 typescript: 5.0.4 - tsutils@3.21.0(typescript@6.0.3): + tsutils@3.21.0(typescript@7.0.2): dependencies: tslib: 1.14.1 - typescript: 6.0.3 + typescript: 7.0.2 tsyringe@4.10.0: dependencies: @@ -61805,14 +61455,14 @@ snapshots: dependencies: csstype: 3.2.3 - typescript-eslint@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5): + typescript-eslint@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5))(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/parser': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) - '@typescript-eslint/typescript-estree': 8.57.1(typescript@5.4.5) - '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 8.57.1(@typescript-eslint/parser@8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2))(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) + '@typescript-eslint/parser': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) + '@typescript-eslint/typescript-estree': 8.57.1(typescript@7.0.2) + '@typescript-eslint/utils': 8.57.1(eslint@9.26.0(jiti@2.6.1))(typescript@7.0.2) eslint: 9.26.0(jiti@2.6.1) - typescript: 5.4.5 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -61831,14 +61481,36 @@ snapshots: typescript@5.0.4: {} - typescript@5.4.5: {} - - typescript@5.8.2: {} + typescript@5.8.2: + optional: true typescript@5.9.3: {} typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + typical@4.0.0: {} typical@5.2.0: {} @@ -62409,44 +62081,6 @@ snapshots: - terser optional: true - vite-plugin-dts@4.5.4(@types/node@20.19.5)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)): - dependencies: - '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - '@volar/typescript': 2.4.28 - '@vue/language-core': 2.2.0(typescript@6.0.3) - compare-versions: 6.1.1 - debug: 4.4.3(supports-color@8.1.1) - kolorist: 1.8.0 - local-pkg: 1.1.2 - magic-string: 0.30.21 - typescript: 6.0.3 - optionalDependencies: - vite: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color - - vite-plugin-dts@4.5.4(@types/node@26.1.0)(rollup@4.59.0)(typescript@6.0.3)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)): - dependencies: - '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) - '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - '@volar/typescript': 2.4.28 - '@vue/language-core': 2.2.0(typescript@6.0.3) - compare-versions: 6.1.1 - debug: 4.4.3(supports-color@8.1.1) - kolorist: 1.8.0 - local-pkg: 1.1.2 - magic-string: 0.30.21 - typescript: 6.0.3 - optionalDependencies: - vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) - transitivePeerDependencies: - - '@types/node' - - rollup - - supports-color - vite-tsconfig-paths@4.2.3(typescript@6.0.3)(vite@7.3.5(@types/node@20.19.5)(jiti@2.6.1)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0)(yaml@2.9.0)): dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -62669,15 +62303,10 @@ snapshots: transitivePeerDependencies: - supports-color - vue-router@4.4.5(vue@3.5.30(typescript@5.9.3)): + vue-router@4.4.5(vue@3.5.30(typescript@7.0.2)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.30(typescript@5.9.3) - - vue-router@4.4.5(vue@3.5.30(typescript@6.0.3)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.30(typescript@6.0.3) + vue: 3.5.30(typescript@7.0.2) vue-template-compiler@2.7.16: dependencies: @@ -62691,11 +62320,12 @@ snapshots: semver: 7.6.3 typescript: 6.0.3 - vue-tsc@2.2.12(typescript@5.9.3): + vue-tsc@1.8.27(typescript@7.0.2): dependencies: - '@volar/typescript': 2.4.15 - '@vue/language-core': 2.2.12(typescript@5.9.3) - typescript: 5.9.3 + '@volar/typescript': 1.11.1 + '@vue/language-core': 1.8.27(typescript@7.0.2) + semver: 7.6.3 + typescript: 7.0.2 vue-tsc@2.2.12(typescript@6.0.3): dependencies: @@ -62703,25 +62333,31 @@ snapshots: '@vue/language-core': 2.2.12(typescript@6.0.3) typescript: 6.0.3 - vue@3.5.30(typescript@5.9.3): + vue-tsc@2.2.12(typescript@7.0.2): + dependencies: + '@volar/typescript': 2.4.15 + '@vue/language-core': 2.2.12(typescript@7.0.2) + typescript: 7.0.2 + + vue@3.5.30(typescript@6.0.3): dependencies: '@vue/compiler-dom': 3.5.30 '@vue/compiler-sfc': 3.5.30 '@vue/runtime-dom': 3.5.30 - '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@5.9.3)) + '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@6.0.3)) '@vue/shared': 3.5.30 optionalDependencies: - typescript: 5.9.3 + typescript: 6.0.3 - vue@3.5.30(typescript@6.0.3): + vue@3.5.30(typescript@7.0.2): dependencies: '@vue/compiler-dom': 3.5.30 '@vue/compiler-sfc': 3.5.30 '@vue/runtime-dom': 3.5.30 - '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@6.0.3)) + '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@7.0.2)) '@vue/shared': 3.5.30 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 w3c-xmlserializer@4.0.0: dependencies: @@ -62780,7 +62416,7 @@ snapshots: webpack-bundle-analyzer@4.10.2: dependencies: '@discoveryjs/json-ext': 0.5.7 - acorn: 8.16.0 + acorn: 8.17.0 acorn-walk: 8.3.5 commander: 7.2.0 debounce: 1.2.1 @@ -63246,40 +62882,6 @@ snapshots: - esbuild - uglify-js - webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)): - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.17.0 - acorn-import-phases: 1.0.4(acorn@8.17.0) - browserslist: 4.28.4 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.20.1 - es-module-lexer: 2.0.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.4.0(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - watchpack: 2.5.1 - webpack-sources: 3.5.0 - optionalDependencies: - webpack-cli: 5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4): dependencies: '@types/eslint-scope': 3.7.7 diff --git a/tools/scripts/copy-dts-to-dmts.mjs b/tools/scripts/copy-dts-to-dmts.mjs new file mode 100644 index 00000000000..be0c8b43c6d --- /dev/null +++ b/tools/scripts/copy-dts-to-dmts.mjs @@ -0,0 +1,25 @@ +import { copyFile, readdir } from 'node:fs/promises'; +import { join } from 'node:path'; + +const targetDir = process.argv[2] || 'dist'; + +async function copyDeclarations(dir) { + const entries = await readdir(dir, { withFileTypes: true }); + + await Promise.all( + entries.map(async (entry) => { + const filePath = join(dir, entry.name); + + if (entry.isDirectory()) { + await copyDeclarations(filePath); + return; + } + + if (entry.isFile() && entry.name.endsWith('.d.ts')) { + await copyFile(filePath, filePath.replace(/\.d\.ts$/, '.d.mts')); + } + }), + ); +} + +await copyDeclarations(targetDir); diff --git a/tsconfig.base.json b/tsconfig.base.json index 579c154e785..b58749e971a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -5,7 +5,6 @@ "sourceMap": true, "esModuleInterop": true, "declaration": false, - "moduleResolution": "node10", "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": false, @@ -15,7 +14,9 @@ "lib": ["es2021", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, - "baseUrl": ".", + "paths": { + "*": ["./*"] + }, "strict": false, "ignoreDeprecations": "6.0" }, From 9331dd84914c134ddac42cb99874ff43b2d2d19a Mon Sep 17 00:00:00 2001 From: Hanric Date: Tue, 14 Jul 2026 14:26:35 +0800 Subject: [PATCH 20/37] ci(node): verify published packages on Node 20 (#4888) --- .github/workflows/build-and-test.yml | 33 +++++ README.md | 18 +++ tools/fixtures/node20-compat/package.json | 12 ++ .../fixtures/node20-compat/rspack.config.cjs | 49 ++++++++ tools/fixtures/node20-compat/smoke-cjs.cjs | 16 +++ tools/fixtures/node20-compat/smoke-esm.mjs | 16 +++ tools/fixtures/node20-compat/src/exposed.ts | 3 + tools/fixtures/node20-compat/src/index.ts | 20 +++ tools/fixtures/node20-compat/tsconfig.json | 12 ++ .../fixtures/node20-compat/webpack.config.cjs | 48 ++++++++ .../prepare-node20-compat-packages.mjs | 56 +++++++++ tools/scripts/verify-node20-compat.mjs | 115 ++++++++++++++++++ 12 files changed, 398 insertions(+) create mode 100644 tools/fixtures/node20-compat/package.json create mode 100644 tools/fixtures/node20-compat/rspack.config.cjs create mode 100644 tools/fixtures/node20-compat/smoke-cjs.cjs create mode 100644 tools/fixtures/node20-compat/smoke-esm.mjs create mode 100644 tools/fixtures/node20-compat/src/exposed.ts create mode 100644 tools/fixtures/node20-compat/src/index.ts create mode 100644 tools/fixtures/node20-compat/tsconfig.json create mode 100644 tools/fixtures/node20-compat/webpack.config.cjs create mode 100644 tools/scripts/prepare-node20-compat-packages.mjs create mode 100644 tools/scripts/verify-node20-compat.mjs diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index e7a8f86dd54..1f1be3681e8 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -85,6 +85,17 @@ jobs: - name: Run affected package tests run: node tools/scripts/run-affected-package-tests.mjs + - name: Pack Node.js 20 compatibility artifacts + run: node tools/scripts/prepare-node20-compat-packages.mjs + + - name: Upload Node.js 20 compatibility artifacts + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: node20-compat-packages + path: artifacts/node20-compat/*.tgz + if-no-files-found: error + retention-days: 1 + - name: Save Turborepo cache if: ${{ success() && steps.turbo-cache.outputs.cache-hit != 'true' }} uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 @@ -97,6 +108,28 @@ jobs: uses: ./.github/workflows/e2e-modern.yml secrets: inherit + node20-compat: + needs: checkout-install + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout Repository + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + + - name: Setup Node.js 20.19.5 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: '20.19.5' + + - name: Download Node.js 20 compatibility artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: node20-compat-packages + path: artifacts/node20-compat + + - name: Verify published packages on Node.js 20.19.5 + run: node tools/scripts/verify-node20-compat.mjs + e2e-runtime: needs: checkout-install uses: ./.github/workflows/e2e-runtime.yml diff --git a/README.md b/README.md index 4d43d56612d..7b8e7e1b71d 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,24 @@ Come and chat with us on [Discussions](https://github.com/module-federation/univ Please read the [Contributing Guide](https://github.com/module-federation/core/blob/main/CONTRIBUTING.md). +### Node.js support + +Working on this repository requires Node.js 24 and pnpm 10.28.0. The repository's +development, test, build, and release workflows run on Node.js 24. + +Published packages that execute in Node.js, including build plugins, command-line +tools, type generation, workers, and server-side runtime code, remain compatible +with Node.js 20.19.5. CI builds the packages on Node.js 24, installs the resulting +package tarballs in a clean Node.js 20.19.5 project, and verifies their CommonJS, +ES module, command-line, and type entry points. The clean TypeScript project is +also built with both Webpack and Rspack, and the resulting Node.js bundles are +executed on Node.js 20.19.5. + +Browser runtime compatibility is defined by the browser build targets rather than +the Node.js version used to maintain this repository. Node.js 20 compatibility is +provided for legacy consumers even though Node.js 20 no longer receives upstream +maintenance. + ![Alt](https://repobeats.axiom.co/api/embed/856dc1d4a6965d225232b1bd2da5d54549dc169e.svg 'Repobeats analytics image') ## 🙌 Code of Conduct diff --git a/tools/fixtures/node20-compat/package.json b/tools/fixtures/node20-compat/package.json new file mode 100644 index 00000000000..f9c2984a903 --- /dev/null +++ b/tools/fixtures/node20-compat/package.json @@ -0,0 +1,12 @@ +{ + "name": "module-federation-node20-compat-consumer", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build:rspack": "rspack build --config rspack.config.cjs", + "build:webpack": "webpack --config webpack.config.cjs", + "typecheck": "tsc --project tsconfig.json" + }, + "dependencies": {} +} diff --git a/tools/fixtures/node20-compat/rspack.config.cjs b/tools/fixtures/node20-compat/rspack.config.cjs new file mode 100644 index 00000000000..cbdb5a744f6 --- /dev/null +++ b/tools/fixtures/node20-compat/rspack.config.cjs @@ -0,0 +1,49 @@ +const path = require('node:path'); +const { + ModuleFederationPlugin, +} = require('@module-federation/enhanced/rspack'); + +module.exports = { + mode: 'production', + target: 'node20', + entry: './src/index.ts', + output: { + clean: true, + filename: 'main.js', + path: path.resolve(__dirname, 'dist/rspack'), + }, + resolve: { + extensions: ['.ts', '.js'], + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: { + loader: 'builtin:swc-loader', + options: { + jsc: { + parser: { syntax: 'typescript' }, + target: 'es2022', + }, + }, + }, + type: 'javascript/auto', + }, + ], + }, + optimization: { + minimize: false, + }, + plugins: [ + new ModuleFederationPlugin({ + name: 'node20_rspack_consumer', + filename: 'remoteEntry.js', + exposes: { + './Greeting': './src/exposed.ts', + }, + dts: false, + }), + ], +}; diff --git a/tools/fixtures/node20-compat/smoke-cjs.cjs b/tools/fixtures/node20-compat/smoke-cjs.cjs new file mode 100644 index 00000000000..7a35080a7a9 --- /dev/null +++ b/tools/fixtures/node20-compat/smoke-cjs.cjs @@ -0,0 +1,16 @@ +const modules = [ + '@module-federation/sdk', + '@module-federation/runtime-core', + '@module-federation/runtime', + '@module-federation/dts-plugin', + '@module-federation/enhanced', + '@module-federation/enhanced/webpack', + '@module-federation/node', + '@module-federation/cli', +]; + +for (const moduleName of modules) { + require(moduleName); +} + +console.log(`[node20-compat] CommonJS loaded ${modules.length} entry points`); diff --git a/tools/fixtures/node20-compat/smoke-esm.mjs b/tools/fixtures/node20-compat/smoke-esm.mjs new file mode 100644 index 00000000000..2982417f4d4 --- /dev/null +++ b/tools/fixtures/node20-compat/smoke-esm.mjs @@ -0,0 +1,16 @@ +const modules = [ + '@module-federation/sdk', + '@module-federation/runtime-core', + '@module-federation/runtime', + '@module-federation/dts-plugin', + '@module-federation/enhanced', + '@module-federation/enhanced/webpack', + '@module-federation/node', + '@module-federation/cli', +]; + +for (const moduleName of modules) { + await import(moduleName); +} + +console.log(`[node20-compat] ESM loaded ${modules.length} entry points`); diff --git a/tools/fixtures/node20-compat/src/exposed.ts b/tools/fixtures/node20-compat/src/exposed.ts new file mode 100644 index 00000000000..357a29a07a5 --- /dev/null +++ b/tools/fixtures/node20-compat/src/exposed.ts @@ -0,0 +1,3 @@ +export function node20CompatibleGreeting(name: string): string { + return `Hello, ${name}`; +} diff --git a/tools/fixtures/node20-compat/src/index.ts b/tools/fixtures/node20-compat/src/index.ts new file mode 100644 index 00000000000..2fe35ce8969 --- /dev/null +++ b/tools/fixtures/node20-compat/src/index.ts @@ -0,0 +1,20 @@ +import { init } from '@module-federation/runtime'; +import type * as dtsPlugin from '@module-federation/dts-plugin'; +import type * as enhanced from '@module-federation/enhanced'; +import type * as node from '@module-federation/node'; +import type * as runtime from '@module-federation/runtime'; +import type * as runtimeCore from '@module-federation/runtime-core'; +import type * as sdk from '@module-federation/sdk'; + +export type PublicPackageTypes = { + sdk: typeof sdk; + runtimeCore: typeof runtimeCore; + runtime: typeof runtime; + dtsPlugin: typeof dtsPlugin; + enhanced: typeof enhanced; + node: typeof node; +}; + +export const runtimeInitType = typeof init; + +console.log(`[node20-compat] Bundled runtime init type: ${runtimeInitType}`); diff --git a/tools/fixtures/node20-compat/tsconfig.json b/tools/fixtures/node20-compat/tsconfig.json new file mode 100644 index 00000000000..76f6a15f313 --- /dev/null +++ b/tools/fixtures/node20-compat/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "ES2022", + "types": ["node"] + }, + "include": ["src/**/*.ts"] +} diff --git a/tools/fixtures/node20-compat/webpack.config.cjs b/tools/fixtures/node20-compat/webpack.config.cjs new file mode 100644 index 00000000000..aee90e79d10 --- /dev/null +++ b/tools/fixtures/node20-compat/webpack.config.cjs @@ -0,0 +1,48 @@ +const path = require('node:path'); +const { + ModuleFederationPlugin, +} = require('@module-federation/enhanced/webpack'); + +module.exports = { + mode: 'production', + target: 'node20', + entry: './src/index.ts', + output: { + clean: true, + filename: 'main.js', + path: path.resolve(__dirname, 'dist/webpack'), + }, + resolve: { + extensions: ['.ts', '.js'], + }, + module: { + rules: [ + { + test: /\.ts$/, + exclude: /node_modules/, + use: { + loader: 'swc-loader', + options: { + jsc: { + parser: { syntax: 'typescript' }, + target: 'es2022', + }, + }, + }, + }, + ], + }, + optimization: { + minimize: false, + }, + plugins: [ + new ModuleFederationPlugin({ + name: 'node20_webpack_consumer', + filename: 'remoteEntry.js', + exposes: { + './Greeting': './src/exposed.ts', + }, + dts: false, + }), + ], +}; diff --git a/tools/scripts/prepare-node20-compat-packages.mjs b/tools/scripts/prepare-node20-compat-packages.mjs new file mode 100644 index 00000000000..a4c43de6c9c --- /dev/null +++ b/tools/scripts/prepare-node20-compat-packages.mjs @@ -0,0 +1,56 @@ +import { + existsSync, + mkdirSync, + readFileSync, + readdirSync, + rmSync, +} from 'node:fs'; +import { basename, join, resolve } from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +const ROOT = resolve(fileURLToPath(new URL('../..', import.meta.url))); +const PACKAGES_DIR = join(ROOT, 'packages'); +const OUTPUT_DIR = resolve(ROOT, process.argv[2] || 'artifacts/node20-compat'); + +rmSync(OUTPUT_DIR, { recursive: true, force: true }); +mkdirSync(OUTPUT_DIR, { recursive: true }); + +const packageDirs = readdirSync(PACKAGES_DIR, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => join(PACKAGES_DIR, entry.name)) + .filter((packageDir) => existsSync(join(packageDir, 'package.json'))) + .filter((packageDir) => { + const packageJson = JSON.parse( + readFileSync(join(packageDir, 'package.json'), 'utf8'), + ); + return packageJson.private !== true; + }) + .sort(); + +for (const packageDir of packageDirs) { + const result = spawnSync('pnpm', ['pack', '--pack-destination', OUTPUT_DIR], { + cwd: packageDir, + encoding: 'utf8', + stdio: 'pipe', + }); + + if (result.status !== 0) { + process.stderr.write(result.stdout || ''); + process.stderr.write(result.stderr || ''); + throw new Error(`Failed to pack ${basename(packageDir)}`); + } +} + +const tarballs = readdirSync(OUTPUT_DIR).filter((file) => + file.endsWith('.tgz'), +); +if (tarballs.length !== packageDirs.length) { + throw new Error( + `Expected ${packageDirs.length} tarballs, found ${tarballs.length}`, + ); +} + +console.log( + `[node20-compat] Packed ${tarballs.length} publishable packages into ${OUTPUT_DIR}`, +); diff --git a/tools/scripts/verify-node20-compat.mjs b/tools/scripts/verify-node20-compat.mjs new file mode 100644 index 00000000000..d0136826ea2 --- /dev/null +++ b/tools/scripts/verify-node20-compat.mjs @@ -0,0 +1,115 @@ +import { + cpSync, + mkdtempSync, + readFileSync, + readdirSync, + rmSync, + writeFileSync, +} from 'node:fs'; +import { tmpdir } from 'node:os'; +import { basename, join, resolve } from 'node:path'; +import { spawnSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; + +const ROOT = resolve(fileURLToPath(new URL('../..', import.meta.url))); +const FIXTURE_DIR = join(ROOT, 'tools/fixtures/node20-compat'); +const TARBALL_DIR = resolve(ROOT, process.argv[2] || 'artifacts/node20-compat'); +const EXPECTED_NODE_VERSION = '20.19.5'; + +if (process.versions.node !== EXPECTED_NODE_VERSION) { + throw new Error( + `This compatibility check must run on Node.js ${EXPECTED_NODE_VERSION}; received ${process.versions.node}`, + ); +} + +const tarballs = readdirSync(TARBALL_DIR) + .filter((file) => file.endsWith('.tgz')) + .map((file) => resolve(TARBALL_DIR, file)); + +if (tarballs.length === 0) { + throw new Error(`No package tarballs found in ${TARBALL_DIR}`); +} + +const consumerDir = mkdtempSync(join(tmpdir(), 'mf-node20-compat-')); + +try { + cpSync(FIXTURE_DIR, consumerDir, { recursive: true }); + + const rootPackageJson = JSON.parse( + readFileSync(join(ROOT, 'package.json'), 'utf8'), + ); + const packageJson = JSON.parse( + readFileSync(join(consumerDir, 'package.json'), 'utf8'), + ); + + packageJson.devDependencies = { + '@rspack/cli': rootPackageJson.devDependencies['@rspack/cli'], + '@rspack/core': rootPackageJson.devDependencies['@rspack/core'], + '@swc/core': rootPackageJson.devDependencies['@swc/core'], + '@types/node': rootPackageJson.devDependencies['@types/node'], + 'swc-loader': rootPackageJson.devDependencies['swc-loader'], + typescript: rootPackageJson.devDependencies.typescript, + webpack: rootPackageJson.devDependencies.webpack, + 'webpack-cli': rootPackageJson.devDependencies['webpack-cli'], + }; + for (const tarball of tarballs) { + const packageJsonOutput = run( + 'tar', + ['-xOf', tarball, 'package/package.json'], + { cwd: consumerDir, printOutput: false }, + ); + const packageName = JSON.parse(packageJsonOutput); + packageJson.dependencies[packageName.name] = `file:${tarball}`; + } + + writeFileSync( + join(consumerDir, 'package.json'), + `${JSON.stringify(packageJson, null, 2)}\n`, + ); + + run('npm', ['install', '--legacy-peer-deps'], { + cwd: consumerDir, + env: { + ...process.env, + npm_config_cache: join(consumerDir, '.npm-cache'), + }, + }); + run('node', ['smoke-cjs.cjs'], { cwd: consumerDir }); + run('node', ['smoke-esm.mjs'], { cwd: consumerDir }); + run('node', ['node_modules/@module-federation/cli/bin/mf.js', '--help'], { + cwd: consumerDir, + }); + run('npm', ['run', 'typecheck'], { cwd: consumerDir }); + run('npm', ['run', 'build:webpack'], { cwd: consumerDir }); + run('npm', ['run', 'build:rspack'], { cwd: consumerDir }); + run('node', ['dist/webpack/main.js'], { cwd: consumerDir }); + run('node', ['dist/rspack/main.js'], { cwd: consumerDir }); + + console.log( + `[node20-compat] Installed and verified ${tarballs.length} package tarballs on Node.js ${process.versions.node}`, + ); +} finally { + rmSync(consumerDir, { recursive: true, force: true }); +} + +function run(command, args, options) { + const { printOutput = true, ...spawnOptions } = options; + const result = spawnSync(command, args, { + ...spawnOptions, + encoding: 'utf8', + stdio: 'pipe', + }); + + if (result.status !== 0) { + process.stderr.write(result.stdout || ''); + process.stderr.write(result.stderr || ''); + throw new Error( + `Command failed: ${command} ${args.map((arg) => basename(arg)).join(' ')}`, + ); + } + + if (printOutput && result.stdout) { + process.stdout.write(result.stdout); + } + return result.stdout.trim(); +} From 7c4ac9fc068301f5b3247a832f6cba17df73143f Mon Sep 17 00:00:00 2001 From: Hanric Date: Tue, 14 Jul 2026 16:00:06 +0800 Subject: [PATCH 21/37] chore(metro): support TypeScript 7 (#4898) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Néstor --- .changeset/metro-typescript-7.md | 5 + apps/metro-example-host/ios/Podfile | 10 + apps/metro-example-host/package.json | 2 +- apps/metro-example-mini/package.json | 2 +- apps/metro-example-nested-mini/package.json | 2 +- packages/metro-core/package.json | 4 +- packages/metro-core/tsconfig.build.json | 4 +- packages/metro-core/tsconfig.json | 2 +- packages/metro-core/tsconfig.spec.json | 1 - packages/metro-plugin-rnc-cli/jest.config.ts | 2 +- packages/metro-plugin-rnc-cli/package.json | 4 +- packages/metro-plugin-rnef/package.json | 4 +- packages/metro-plugin-rock/package.json | 4 +- pnpm-lock.yaml | 529 +++++-------------- 14 files changed, 173 insertions(+), 402 deletions(-) create mode 100644 .changeset/metro-typescript-7.md diff --git a/.changeset/metro-typescript-7.md b/.changeset/metro-typescript-7.md new file mode 100644 index 00000000000..31e7b3a9d52 --- /dev/null +++ b/.changeset/metro-typescript-7.md @@ -0,0 +1,5 @@ +--- +"@module-federation/metro": patch +--- + +Support TypeScript 7 in Metro projects. diff --git a/apps/metro-example-host/ios/Podfile b/apps/metro-example-host/ios/Podfile index ed9ba5d996a..5f2264d6890 100644 --- a/apps/metro-example-host/ios/Podfile +++ b/apps/metro-example-host/ios/Podfile @@ -31,5 +31,15 @@ target 'MFExampleHost' do :mac_catalyst_enabled => false, # :ccache_enabled => true ) + + # fmt 11.0.2 fails as C++20 with Apple Clang 21 (Xcode 26.4+). + # Remove after React Native upgrades to fmt 12.1.0 or newer. + installer.pods_project.targets.each do |target| + next unless target.name == 'fmt' + + target.build_configurations.each do |build_config| + build_config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++17' + end + end end end diff --git a/apps/metro-example-host/package.json b/apps/metro-example-host/package.json index e7bcd7f8930..02dfba8e381 100644 --- a/apps/metro-example-host/package.json +++ b/apps/metro-example-host/package.json @@ -51,7 +51,7 @@ "nodemon": "^3.1.9", "prettier": "2.8.8", "react-test-renderer": "19.1.0", - "typescript": "5.0.4" + "typescript": "7.0.2" }, "engines": { "node": ">=18" diff --git a/apps/metro-example-mini/package.json b/apps/metro-example-mini/package.json index 0758a79fd34..fb6f9bef2f4 100644 --- a/apps/metro-example-mini/package.json +++ b/apps/metro-example-mini/package.json @@ -50,7 +50,7 @@ "prettier": "2.8.8", "react-test-renderer": "19.1.0", "serve": "^14.2.4", - "typescript": "5.0.4" + "typescript": "7.0.2" }, "engines": { "node": ">=18" diff --git a/apps/metro-example-nested-mini/package.json b/apps/metro-example-nested-mini/package.json index e1719789eef..781b70f404c 100644 --- a/apps/metro-example-nested-mini/package.json +++ b/apps/metro-example-nested-mini/package.json @@ -49,7 +49,7 @@ "prettier": "2.8.8", "react-test-renderer": "19.1.0", "serve": "^14.2.4", - "typescript": "5.0.4" + "typescript": "7.0.2" }, "engines": { "node": ">=18" diff --git a/packages/metro-core/package.json b/packages/metro-core/package.json index 199c19a7a40..54ceca15779 100644 --- a/packages/metro-core/package.json +++ b/packages/metro-core/package.json @@ -88,8 +88,8 @@ }, "devDependencies": { "@rslib/core": "^0.23.2", - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "@types/node": "^20.19.5", "@types/react": "^19.1.0", "memfs": "4.46.0", diff --git a/packages/metro-core/tsconfig.build.json b/packages/metro-core/tsconfig.build.json index 587e9fb1b90..f28f69f1b74 100644 --- a/packages/metro-core/tsconfig.build.json +++ b/packages/metro-core/tsconfig.build.json @@ -2,8 +2,8 @@ "extends": "./tsconfig.json", "exclude": ["src/modules"], "compilerOptions": { - "rootDir": "src", - "outDir": "dist", + "rootDir": "./src", + "outDir": "./dist", "sourceMap": false, "declarationMap": false } diff --git a/packages/metro-core/tsconfig.json b/packages/metro-core/tsconfig.json index a00e9cb01f5..21260bfe236 100644 --- a/packages/metro-core/tsconfig.json +++ b/packages/metro-core/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.base.json", "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts"], "compilerOptions": { - "rootDir": "src", + "rootDir": "./src", "jsx": "react-jsx", "paths": { "metro/private/*": ["./node_modules/metro/src/*"] diff --git a/packages/metro-core/tsconfig.spec.json b/packages/metro-core/tsconfig.spec.json index 18ecb730d87..a8a1ad9e59c 100644 --- a/packages/metro-core/tsconfig.spec.json +++ b/packages/metro-core/tsconfig.spec.json @@ -3,7 +3,6 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", - "moduleResolution": "node10", "types": ["@rstest/core/globals", "node"] }, "include": [ diff --git a/packages/metro-plugin-rnc-cli/jest.config.ts b/packages/metro-plugin-rnc-cli/jest.config.ts index 1db901e7000..bf341717937 100644 --- a/packages/metro-plugin-rnc-cli/jest.config.ts +++ b/packages/metro-plugin-rnc-cli/jest.config.ts @@ -3,7 +3,7 @@ export default { preset: '../../jest.preset.js', testEnvironment: 'node', transform: { - '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + '^.+\\.[tj]sx?$': ['@swc/jest'], }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/packages/metro-rnc-cli', diff --git a/packages/metro-plugin-rnc-cli/package.json b/packages/metro-plugin-rnc-cli/package.json index 48a888e82dc..2817dca210d 100644 --- a/packages/metro-plugin-rnc-cli/package.json +++ b/packages/metro-plugin-rnc-cli/package.json @@ -34,8 +34,8 @@ }, "devDependencies": { "@module-federation/metro": "workspace:*", - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "typescript": "^6.0.3" }, "scripts": { diff --git a/packages/metro-plugin-rnef/package.json b/packages/metro-plugin-rnef/package.json index cf836b1e58c..471bae45619 100644 --- a/packages/metro-plugin-rnef/package.json +++ b/packages/metro-plugin-rnef/package.json @@ -47,8 +47,8 @@ "@rnef/config": "^0.7.18", "@rnef/tools": "^0.7.18", "@rslib/core": "^0.23.2", - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "@types/node": "^20.0.0", "typescript": "^6.0.3" } diff --git a/packages/metro-plugin-rock/package.json b/packages/metro-plugin-rock/package.json index 859cf1d71b6..bd7513039ef 100644 --- a/packages/metro-plugin-rock/package.json +++ b/packages/metro-plugin-rock/package.json @@ -45,8 +45,8 @@ "@rock-js/config": "^0.13.0", "@rock-js/tools": "^0.13.0", "@rslib/core": "^0.23.2", - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", "@types/node": "^20.0.0", "typescript": "^6.0.3" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f686e02965..a47b188c604 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -818,7 +818,7 @@ importers: version: 19.1.0 react-native: specifier: 0.80.0 - version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0) + version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0) devDependencies: '@babel/core': specifier: ^7.25.2 @@ -843,7 +843,7 @@ importers: version: 0.80.0(@babel/core@7.29.0) '@react-native/eslint-config': specifier: 0.80.0 - version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4) + version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))(prettier@2.8.8)(typescript@7.0.2) '@react-native/gradle-plugin': specifier: 0.80.0 version: 0.80.0 @@ -858,7 +858,7 @@ importers: version: 0.14.1 '@rock-js/platform-ios': specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) '@rock-js/plugin-metro': specifier: ^0.14.1 version: 0.14.1 @@ -882,7 +882,7 @@ importers: version: 8.57.1 jest: specifier: ^29.6.3 - version: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + version: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) nodemon: specifier: ^3.1.9 version: 3.1.14 @@ -894,10 +894,10 @@ importers: version: 19.1.0(react@19.1.0) rock: specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) typescript: - specifier: 5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 apps/metro-example-mini: dependencies: @@ -909,7 +909,7 @@ importers: version: 19.1.0 react-native: specifier: 0.80.0 - version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0) + version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0) devDependencies: '@babel/core': specifier: ^7.25.2 @@ -931,13 +931,13 @@ importers: version: link:../../packages/runtime '@react-native-community/cli': specifier: ^19.1.0 - version: 19.1.2(typescript@5.0.4) + version: 19.1.2(typescript@7.0.2) '@react-native/babel-preset': specifier: 0.80.0 version: 0.80.0(@babel/core@7.29.0) '@react-native/eslint-config': specifier: 0.80.0 - version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4) + version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)))(prettier@2.8.8)(typescript@7.0.2) '@react-native/metro-config': specifier: 0.80.0 version: 0.80.0(@babel/core@7.29.0) @@ -949,7 +949,7 @@ importers: version: 0.14.1 '@rock-js/platform-ios': specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) '@rock-js/plugin-metro': specifier: ^0.14.1 version: 0.14.1 @@ -973,7 +973,7 @@ importers: version: 8.57.1 jest: specifier: ^29.6.3 - version: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + version: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) nodemon: specifier: ^3.1.9 version: 3.1.14 @@ -985,13 +985,13 @@ importers: version: 19.1.0(react@19.1.0) rock: specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) serve: specifier: ^14.2.4 version: 14.2.5 typescript: - specifier: 5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 apps/metro-example-nested-mini: dependencies: @@ -1003,7 +1003,7 @@ importers: version: 19.1.0 react-native: specifier: 0.80.0 - version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0) + version: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0) devDependencies: '@babel/core': specifier: ^7.25.2 @@ -1028,7 +1028,7 @@ importers: version: 0.80.0(@babel/core@7.29.0) '@react-native/eslint-config': specifier: 0.80.0 - version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4) + version: 0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)))(prettier@2.8.8)(typescript@7.0.2) '@react-native/metro-config': specifier: 0.80.0 version: 0.80.0(@babel/core@7.29.0) @@ -1040,7 +1040,7 @@ importers: version: 0.14.1 '@rock-js/platform-ios': specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) '@rock-js/plugin-metro': specifier: ^0.14.1 version: 0.14.1 @@ -1064,7 +1064,7 @@ importers: version: 8.57.1 jest: specifier: ^29.6.3 - version: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + version: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) nodemon: specifier: ^3.1.9 version: 3.1.14 @@ -1076,13 +1076,13 @@ importers: version: 19.1.0(react@19.1.0) rock: specifier: ^0.14.1 - version: 0.14.1(typescript@5.0.4) + version: 0.14.1(typescript@7.0.2) serve: specifier: ^14.2.4 version: 14.2.5 typescript: - specifier: 5.0.4 - version: 5.0.4 + specifier: 7.0.2 + version: 7.0.2 apps/modern-component-data-fetch/host: dependencies: @@ -3477,11 +3477,11 @@ importers: specifier: ^19.1.0 version: 19.2.14 '@typescript-eslint/eslint-plugin': - specifier: 8.54.0 - version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.54.0 - version: 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) memfs: specifier: 4.46.0 version: 4.46.0 @@ -3519,11 +3519,11 @@ importers: specifier: workspace:* version: link:../metro-core '@typescript-eslint/eslint-plugin': - specifier: 8.54.0 - version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.54.0 - version: 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -3546,11 +3546,11 @@ importers: specifier: ^20.0.0 version: 20.19.5 '@typescript-eslint/eslint-plugin': - specifier: 8.54.0 - version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.54.0 - version: 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -3573,11 +3573,11 @@ importers: specifier: ^20.0.0 version: 20.19.5 '@typescript-eslint/eslint-plugin': - specifier: 8.54.0 - version: 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(@typescript-eslint/parser@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.54.0 - version: 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) + specifier: 8.56.1 + version: 8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -8442,18 +8442,12 @@ packages: '@swc/helpers': optional: true - '@modern-js/tsconfig@2.70.5': - resolution: {integrity: sha512-Yv6EKtgkEG5+YmTxRed/zbp6Rieq0yN9ucsc09ZrE/p+wsQ8RUK9ILumHIX8hjz9Dy1b6+rqC7ZfuC0VHe/lLw==} - '@modern-js/tsconfig@2.70.8': resolution: {integrity: sha512-Z+lVMxO1z1E5ZuoWD6tnOxdDBMyqzrg4THTJnje2tgr9BB+7zF9cAzFTchdv3Bjm/IdQLq/pr1lpM6LnGq/GuQ==} '@modern-js/tsconfig@3.0.1': resolution: {integrity: sha512-DmiXMLRg4H7ZSivZZYgTblN4Rnm1C8bfRPZcZESWjqdisXrq/Ztugsv9bGHh5s1IVk9tNBvGiMeSi7prCZaDCw==} - '@modern-js/tsconfig@3.5.0': - resolution: {integrity: sha512-QjEI25TF066NIF8HlWp8K09qUvIzkppsmynn/ejHnW5ASzhcAGXdRQaALn5lfMS7i/uTZXIl0Dsf9KuMttDHAQ==} - '@modern-js/types@2.68.0': resolution: {integrity: sha512-tL8nuFRuYNzIYpL1Gy0hK+p50RmUJmLeJJ4i2Ba237/tPSf+dOGrUooQJRTNh+hoe4e1kiEQP9XGqIufZuqb0A==} @@ -14367,14 +14361,6 @@ packages: typescript: optional: true - '@typescript-eslint/eslint-plugin@8.54.0': - resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.54.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/eslint-plugin@8.56.1': resolution: {integrity: sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14421,13 +14407,6 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.54.0': - resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.56.1': resolution: {integrity: sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14442,12 +14421,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.54.0': - resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.56.1': resolution: {integrity: sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14472,10 +14445,6 @@ packages: resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/scope-manager@8.54.0': - resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.56.1': resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14484,12 +14453,6 @@ packages: resolution: {integrity: sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.54.0': - resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/tsconfig-utils@8.56.1': resolution: {integrity: sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14522,13 +14485,6 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@8.54.0': - resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.56.1': resolution: {integrity: sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14555,10 +14511,6 @@ packages: resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/types@8.54.0': - resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.56.1': resolution: {integrity: sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14594,12 +14546,6 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.54.0': - resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.56.1': resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14624,13 +14570,6 @@ packages: peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/utils@8.54.0': - resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.56.1': resolution: {integrity: sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -14657,10 +14596,6 @@ packages: resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/visitor-keys@8.54.0': - resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.56.1': resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -27082,11 +27017,6 @@ packages: engines: {node: '>=4.2.0'} hasBin: true - typescript@5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} - hasBin: true - typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -32184,7 +32114,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -32198,7 +32128,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -32219,7 +32149,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -32233,7 +32163,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -34562,14 +34492,10 @@ snapshots: '@modern-js/swc-plugins-win32-x64-msvc': 0.6.11 '@swc/helpers': 0.5.19 - '@modern-js/tsconfig@2.70.5': {} - '@modern-js/tsconfig@2.70.8': {} '@modern-js/tsconfig@3.0.1': {} - '@modern-js/tsconfig@3.5.0': {} - '@modern-js/types@2.68.0': {} '@modern-js/types@2.70.5': {} @@ -38076,33 +38002,33 @@ snapshots: fast-glob: 3.3.3 picocolors: 1.1.1 - '@react-native-community/cli-config@19.1.2(typescript@5.0.4)': + '@react-native-community/cli-config@19.1.2(typescript@6.0.3)': dependencies: '@react-native-community/cli-tools': 19.1.2 chalk: 4.1.2 - cosmiconfig: 9.0.1(typescript@5.0.4) + cosmiconfig: 9.0.1(typescript@6.0.3) deepmerge: 4.3.1 fast-glob: 3.3.3 joi: 17.13.3 transitivePeerDependencies: - typescript + optional: true - '@react-native-community/cli-config@19.1.2(typescript@6.0.3)': + '@react-native-community/cli-config@19.1.2(typescript@7.0.2)': dependencies: '@react-native-community/cli-tools': 19.1.2 chalk: 4.1.2 - cosmiconfig: 9.0.1(typescript@6.0.3) + cosmiconfig: 9.0.1(typescript@7.0.2) deepmerge: 4.3.1 fast-glob: 3.3.3 joi: 17.13.3 transitivePeerDependencies: - typescript - optional: true - '@react-native-community/cli-config@20.1.3(typescript@5.0.4)': + '@react-native-community/cli-config@20.1.3(typescript@7.0.2)': dependencies: '@react-native-community/cli-tools': 20.1.3 - cosmiconfig: 9.0.1(typescript@5.0.4) + cosmiconfig: 9.0.1(typescript@7.0.2) deepmerge: 4.3.1 fast-glob: 3.3.3 joi: 17.13.3 @@ -38110,9 +38036,9 @@ snapshots: transitivePeerDependencies: - typescript - '@react-native-community/cli-doctor@19.1.2(typescript@5.0.4)': + '@react-native-community/cli-doctor@19.1.2(typescript@6.0.3)': dependencies: - '@react-native-community/cli-config': 19.1.2(typescript@5.0.4) + '@react-native-community/cli-config': 19.1.2(typescript@6.0.3) '@react-native-community/cli-platform-android': 19.1.2 '@react-native-community/cli-platform-apple': 19.1.2 '@react-native-community/cli-platform-ios': 19.1.2 @@ -38129,10 +38055,11 @@ snapshots: yaml: 2.8.2 transitivePeerDependencies: - typescript + optional: true - '@react-native-community/cli-doctor@19.1.2(typescript@6.0.3)': + '@react-native-community/cli-doctor@19.1.2(typescript@7.0.2)': dependencies: - '@react-native-community/cli-config': 19.1.2(typescript@6.0.3) + '@react-native-community/cli-config': 19.1.2(typescript@7.0.2) '@react-native-community/cli-platform-android': 19.1.2 '@react-native-community/cli-platform-apple': 19.1.2 '@react-native-community/cli-platform-ios': 19.1.2 @@ -38149,7 +38076,6 @@ snapshots: yaml: 2.8.2 transitivePeerDependencies: - typescript - optional: true '@react-native-community/cli-platform-android@19.1.2': dependencies: @@ -38240,11 +38166,11 @@ snapshots: dependencies: joi: 17.13.3 - '@react-native-community/cli@19.1.2(typescript@5.0.4)': + '@react-native-community/cli@19.1.2(typescript@6.0.3)': dependencies: '@react-native-community/cli-clean': 19.1.2 - '@react-native-community/cli-config': 19.1.2(typescript@5.0.4) - '@react-native-community/cli-doctor': 19.1.2(typescript@5.0.4) + '@react-native-community/cli-config': 19.1.2(typescript@6.0.3) + '@react-native-community/cli-doctor': 19.1.2(typescript@6.0.3) '@react-native-community/cli-server-api': 19.1.2 '@react-native-community/cli-tools': 19.1.2 '@react-native-community/cli-types': 19.1.2 @@ -38262,12 +38188,13 @@ snapshots: - supports-color - typescript - utf-8-validate + optional: true - '@react-native-community/cli@19.1.2(typescript@6.0.3)': + '@react-native-community/cli@19.1.2(typescript@7.0.2)': dependencies: '@react-native-community/cli-clean': 19.1.2 - '@react-native-community/cli-config': 19.1.2(typescript@6.0.3) - '@react-native-community/cli-doctor': 19.1.2(typescript@6.0.3) + '@react-native-community/cli-config': 19.1.2(typescript@7.0.2) + '@react-native-community/cli-doctor': 19.1.2(typescript@7.0.2) '@react-native-community/cli-server-api': 19.1.2 '@react-native-community/cli-tools': 19.1.2 '@react-native-community/cli-types': 19.1.2 @@ -38285,7 +38212,6 @@ snapshots: - supports-color - typescript - utf-8-validate - optional: true '@react-native/assets-registry@0.80.0': {} @@ -38365,7 +38291,7 @@ snapshots: nullthrows: 1.1.1 yargs: 17.7.2 - '@react-native/community-cli-plugin@0.80.0(@react-native-community/cli@19.1.2(typescript@5.0.4))': + '@react-native/community-cli-plugin@0.80.0(@react-native-community/cli@19.1.2(typescript@6.0.3))': dependencies: '@react-native/dev-middleware': 0.80.0 chalk: 4.1.2 @@ -38376,13 +38302,13 @@ snapshots: metro-core: 0.82.5 semver: 7.6.3 optionalDependencies: - '@react-native-community/cli': 19.1.2(typescript@5.0.4) + '@react-native-community/cli': 19.1.2(typescript@6.0.3) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@react-native/community-cli-plugin@0.80.0(@react-native-community/cli@19.1.2(typescript@6.0.3))': + '@react-native/community-cli-plugin@0.80.0(@react-native-community/cli@19.1.2(typescript@7.0.2))': dependencies: '@react-native/dev-middleware': 0.80.0 chalk: 4.1.2 @@ -38393,7 +38319,7 @@ snapshots: metro-core: 0.82.5 semver: 7.6.3 optionalDependencies: - '@react-native-community/cli': 19.1.2(typescript@6.0.3) + '@react-native-community/cli': 19.1.2(typescript@7.0.2) transitivePeerDependencies: - bufferutil - supports-color @@ -38419,18 +38345,18 @@ snapshots: - supports-color - utf-8-validate - '@react-native/eslint-config@0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4)': + '@react-native/eslint-config@0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))(prettier@2.8.8)(typescript@7.0.2)': dependencies: '@babel/core': 7.29.0 '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) '@react-native/eslint-plugin': 0.80.0 - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 eslint-config-prettier: 8.10.2(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-ft-flow: 2.0.3(@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)))(typescript@5.0.4) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))(typescript@7.0.2) eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) eslint-plugin-react-native: 4.1.0(eslint@8.57.1) @@ -38440,18 +38366,18 @@ snapshots: - supports-color - typescript - '@react-native/eslint-config@0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)))(prettier@2.8.8)(typescript@5.0.4)': + '@react-native/eslint-config@0.80.0(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)))(prettier@2.8.8)(typescript@7.0.2)': dependencies: '@babel/core': 7.29.0 '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) '@react-native/eslint-plugin': 0.80.0 - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 eslint-config-prettier: 8.10.2(eslint@8.57.1) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) eslint-plugin-ft-flow: 2.0.3(@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)))(typescript@5.0.4) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)))(typescript@7.0.2) eslint-plugin-react: 7.37.2(eslint@8.57.1) eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) eslint-plugin-react-native: 4.1.0(eslint@8.57.1) @@ -38490,12 +38416,12 @@ snapshots: '@react-native/typescript-config@0.80.0': {} - '@react-native/virtualized-lists@0.80.0(@types/react@19.2.14)(react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0))(react@19.1.0)': + '@react-native/virtualized-lists@0.80.0(@types/react@19.2.14)(react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0))(react@19.1.0)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 19.1.0 - react-native: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0) + react-native: 0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0) optionalDependencies: '@types/react': 19.2.14 @@ -38655,9 +38581,9 @@ snapshots: '@rock-js/tools': 0.14.1 tslib: 2.8.1 - '@rock-js/platform-apple-helpers@0.14.1(typescript@5.0.4)': + '@rock-js/platform-apple-helpers@0.14.1(typescript@7.0.2)': dependencies: - '@react-native-community/cli-config': 20.1.3(typescript@5.0.4) + '@react-native-community/cli-config': 20.1.3(typescript@7.0.2) '@react-native-community/cli-config-apple': 20.1.3 '@rock-js/tools': 0.14.1 adm-zip: 0.5.16 @@ -38666,11 +38592,11 @@ snapshots: transitivePeerDependencies: - typescript - '@rock-js/platform-ios@0.14.1(typescript@5.0.4)': + '@rock-js/platform-ios@0.14.1(typescript@7.0.2)': dependencies: '@react-native-community/cli-config-apple': 20.1.3 '@react-native-community/cli-types': 20.1.3 - '@rock-js/platform-apple-helpers': 0.14.1(typescript@5.0.4) + '@rock-js/platform-apple-helpers': 0.14.1(typescript@7.0.2) '@rock-js/tools': 0.14.1 tslib: 2.8.1 transitivePeerDependencies: @@ -42849,37 +42775,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@7.0.2) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.0.4) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@7.0.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@7.0.2) '@typescript-eslint/visitor-keys': 7.18.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.4.3(typescript@5.0.4) + ts-api-utils: 1.4.3(typescript@7.0.2) optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3))(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.54.0 - '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/utils': 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.54.0 - eslint: 9.39.3(jiti@2.6.1) - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@6.0.3) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -42956,28 +42866,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.0.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@7.0.2) '@typescript-eslint/visitor-keys': 7.18.0 debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.54.0 - '@typescript-eslint/types': 8.54.0 - '@typescript-eslint/typescript-estree': 8.54.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.54.0 - debug: 4.4.3(supports-color@8.1.1) - eslint: 9.39.3(jiti@2.6.1) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43017,15 +42915,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.54.0(typescript@6.0.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) - '@typescript-eslint/types': 8.57.1 - debug: 4.4.3(supports-color@8.1.1) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.56.1(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.57.1(typescript@6.0.3) @@ -43068,11 +42957,6 @@ snapshots: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - '@typescript-eslint/scope-manager@8.54.0': - dependencies: - '@typescript-eslint/types': 8.54.0 - '@typescript-eslint/visitor-keys': 8.54.0 - '@typescript-eslint/scope-manager@8.56.1': dependencies: '@typescript-eslint/types': 8.56.1 @@ -43083,10 +42967,6 @@ snapshots: '@typescript-eslint/types': 8.57.1 '@typescript-eslint/visitor-keys': 8.57.1 - '@typescript-eslint/tsconfig-utils@8.54.0(typescript@6.0.3)': - dependencies: - typescript: 6.0.3 - '@typescript-eslint/tsconfig-utils@8.56.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 @@ -43111,27 +42991,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.0.4) - '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@7.0.2) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@7.0.2) debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 - ts-api-utils: 1.4.3(typescript@5.0.4) + ts-api-utils: 1.4.3(typescript@7.0.2) optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/type-utils@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3)': - dependencies: - '@typescript-eslint/types': 8.54.0 - '@typescript-eslint/typescript-estree': 8.54.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3) - debug: 4.4.3(supports-color@8.1.1) - eslint: 9.39.3(jiti@2.6.1) - ts-api-utils: 2.4.0(typescript@6.0.3) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43177,26 +43045,10 @@ snapshots: '@typescript-eslint/types@7.18.0': {} - '@typescript-eslint/types@8.54.0': {} - '@typescript-eslint/types@8.56.1': {} '@typescript-eslint/types@8.57.1': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.0.4)': - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.3(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.6.3 - tsutils: 3.21.0(typescript@5.0.4) - optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@5.62.0(typescript@7.0.2)': dependencies: '@typescript-eslint/types': 5.62.0 @@ -43226,7 +43078,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.0.4)': + '@typescript-eslint/typescript-estree@7.18.0(typescript@7.0.2)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 @@ -43235,24 +43087,9 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.9 semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.0.4) + ts-api-utils: 1.4.3(typescript@7.0.2) optionalDependencies: - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.54.0(typescript@6.0.3)': - dependencies: - '@typescript-eslint/project-service': 8.54.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@6.0.3) - '@typescript-eslint/types': 8.54.0 - '@typescript-eslint/visitor-keys': 8.54.0 - debug: 4.4.3(supports-color@8.1.1) - minimatch: 9.0.9 - semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@6.0.3) - typescript: 6.0.3 + typescript: 7.0.2 transitivePeerDependencies: - supports-color @@ -43301,21 +43138,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.0.4)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4) - eslint: 8.57.1 - eslint-scope: 5.1.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) @@ -43331,28 +43153,17 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.0.4)': + '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.0.4) + '@typescript-eslint/typescript-estree': 7.18.0(typescript@7.0.2) eslint: 8.57.1 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.54.0(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.54.0 - '@typescript-eslint/types': 8.54.0 - '@typescript-eslint/typescript-estree': 8.54.0(typescript@6.0.3) - eslint: 9.39.3(jiti@2.6.1) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.56.1(eslint@9.39.3(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.6.1)) @@ -43401,11 +43212,6 @@ snapshots: '@typescript-eslint/types': 7.18.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.54.0': - dependencies: - '@typescript-eslint/types': 8.54.0 - eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.56.1': dependencies: '@typescript-eslint/types': 8.56.1 @@ -46756,23 +46562,23 @@ snapshots: optionalDependencies: typescript: 7.0.2 - cosmiconfig@9.0.1(typescript@5.0.4): + cosmiconfig@9.0.1(typescript@6.0.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.2.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.0.4 + typescript: 6.0.3 - cosmiconfig@9.0.1(typescript@6.0.3): + cosmiconfig@9.0.1(typescript@7.0.2): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.2.0 parse-json: 5.2.0 optionalDependencies: - typescript: 6.0.3 + typescript: 7.0.2 create-ecdh@4.0.4: dependencies: @@ -46811,13 +46617,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)): + create-jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -46826,13 +46632,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): + create-jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -48647,24 +48453,24 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)))(typescript@5.0.4): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)))(typescript@7.0.2): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) - jest: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2) + jest: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)))(typescript@5.0.4): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)))(typescript@7.0.2): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@7.0.2) eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) - jest: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@7.0.2))(eslint@8.57.1)(typescript@7.0.2) + jest: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) transitivePeerDependencies: - supports-color - typescript @@ -51449,16 +51255,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)): + jest-cli@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + create-jest: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -51468,16 +51274,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): + jest-cli@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + create-jest: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + jest-config: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -51518,7 +51324,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)): + jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 @@ -51544,12 +51350,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.5 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): + jest-config@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): dependencies: '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 @@ -51575,12 +51381,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.5 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): + jest-config@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): dependencies: '@babel/core': 7.29.7 '@jest/test-sequencer': 29.7.0 @@ -51606,7 +51412,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 26.1.0 - ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4) + ts-node: 10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -51889,24 +51695,24 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)): + jest@29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4)) + jest-cli: 29.7.0(@types/node@20.19.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)): + jest@29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4)) + jest-cli: 29.7.0(@types/node@26.1.0)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -57509,16 +57315,16 @@ snapshots: react-lazy-with-preload@2.2.1: {} - react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0): + react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0): dependencies: '@jest/create-cache-key-function': 29.7.0 '@react-native/assets-registry': 0.80.0 '@react-native/codegen': 0.80.0(@babel/core@7.29.0) - '@react-native/community-cli-plugin': 0.80.0(@react-native-community/cli@19.1.2(typescript@5.0.4)) + '@react-native/community-cli-plugin': 0.80.0(@react-native-community/cli@19.1.2(typescript@7.0.2)) '@react-native/gradle-plugin': 0.80.0 '@react-native/js-polyfills': 0.80.0 '@react-native/normalize-colors': 0.80.0 - '@react-native/virtualized-lists': 0.80.0(@types/react@19.2.14)(react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@5.0.4))(@types/react@19.2.14)(react@19.1.0))(react@19.1.0) + '@react-native/virtualized-lists': 0.80.0(@types/react@19.2.14)(react-native@0.80.0(@babel/core@7.29.0)(@react-native-community/cli@19.1.2(typescript@7.0.2))(@types/react@19.2.14)(react@19.1.0))(react@19.1.0) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 @@ -58525,9 +58331,9 @@ snapshots: robust-predicates@3.0.3: {} - rock@0.14.1(typescript@5.0.4): + rock@0.14.1(typescript@7.0.2): dependencies: - '@react-native-community/cli-config': 20.1.3(typescript@5.0.4) + '@react-native-community/cli-config': 20.1.3(typescript@7.0.2) '@rock-js/config': 0.14.1 '@rock-js/tools': 0.14.1 adm-zip: 0.5.16 @@ -60821,14 +60627,14 @@ snapshots: trough@2.2.0: {} - ts-api-utils@1.4.3(typescript@5.0.4): - dependencies: - typescript: 5.0.4 - ts-api-utils@1.4.3(typescript@5.9.3): dependencies: typescript: 5.9.3 + ts-api-utils@1.4.3(typescript@7.0.2): + dependencies: + typescript: 7.0.2 + ts-api-utils@2.4.0(typescript@6.0.3): dependencies: typescript: 6.0.3 @@ -61048,27 +60854,6 @@ snapshots: '@swc/core': 1.15.41(@swc/helpers@0.5.19) optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@5.0.4): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.5 - acorn: 8.17.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.0.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.15.41(@swc/helpers@0.5.23) - optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@6.0.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -61109,27 +60894,6 @@ snapshots: optionalDependencies: '@swc/core': 1.15.41(@swc/helpers@0.5.23) - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.0.4): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 26.1.0 - acorn: 8.17.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.4 - make-error: 1.3.6 - typescript: 5.0.4 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.15.41(@swc/helpers@0.5.23) - optional: true - ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -61331,11 +61095,6 @@ snapshots: - supports-color - ts-node - tsutils@3.21.0(typescript@5.0.4): - dependencies: - tslib: 1.14.1 - typescript: 5.0.4 - tsutils@3.21.0(typescript@7.0.2): dependencies: tslib: 1.14.1 @@ -61479,8 +61238,6 @@ snapshots: typescript@4.9.5: {} - typescript@5.0.4: {} - typescript@5.8.2: optional: true From 6ee67dc31957c0b89c3200ea2d256fb6901a514c Mon Sep 17 00:00:00 2001 From: Hanric Date: Tue, 14 Jul 2026 18:57:54 +0800 Subject: [PATCH 22/37] perf: slim deps (#4897) --- .changeset/slim-cache-path-dependencies.md | 12 ++ .../__tests__/utils.spec.ts | 9 ++ .../bridge-react-webpack-plugin/package.json | 4 +- .../bridge-react-webpack-plugin/src/utils.ts | 21 +--- packages/bridge/bridge-react/package.json | 12 +- .../scripts/write-dts-entrypoints.mjs | 3 + .../bridge-react/src/error-boundary.spec.tsx | 41 +++++++ .../bridge-react/src/error-boundary.tsx | 44 +++++++ .../src/lazy/data-fetch/cache.spec.ts | 48 ++++++++ .../bridge-react/src/lazy/data-fetch/cache.ts | 21 ++-- .../bridge/bridge-react/src/lazy/types.ts | 4 +- .../src/provider/versions/bridge-base.tsx | 16 +-- .../bridge-react/src/remote/createHelpers.tsx | 11 +- .../src/shared/size-limited-cache.spec.ts | 74 +++++++++++ .../src/shared/size-limited-cache.ts | 115 ++++++++++++++++++ packages/bridge/bridge-react/vite.config.ts | 4 + packages/dts-plugin/package.json | 2 - .../dts-plugin/src/server/broker/Broker.ts | 75 +++++++++--- .../src/server/broker/schedule.spec.ts | 37 ++++++ packages/enhanced/package.json | 1 - .../container/runtime/normalizeToPosixPath.ts | 22 ++++ .../src/lib/container/runtime/utils.ts | 5 +- .../runtime/normalizeToPosixPath.test.ts | 20 +++ .../__tests__/findPackageJson.spec.ts | 23 ++++ packages/managers/package.json | 3 +- packages/managers/src/PKGJsonManager.ts | 4 +- packages/managers/src/SharedManager.ts | 9 +- packages/managers/src/findPackageJson.ts | 19 +++ packages/modernjs-v3/package.json | 8 +- .../cli/mfRuntimePlugins/inject-node-fetch.ts | 6 +- .../modernjs-v3/src/server/fileCache.spec.ts | 24 +++- packages/modernjs-v3/src/server/fileCache.ts | 10 +- packages/modernjs/package.json | 9 +- .../cli/mfRuntimePlugins/inject-node-fetch.ts | 6 +- .../modernjs/src/server/fileCache.spec.ts | 24 +++- packages/modernjs/src/server/fileCache.ts | 10 +- .../third-party-dts-extractor/package.json | 4 - .../src/ThirdPartyExtractor.spec.ts | 10 +- .../src/ThirdPartyExtractor.ts | 14 +-- .../third-party-dts-extractor/src/utils.ts | 36 +++++- .../third-party-dts-extractor/tsup.config.ts | 2 +- pnpm-lock.yaml | 52 -------- 42 files changed, 689 insertions(+), 185 deletions(-) create mode 100644 .changeset/slim-cache-path-dependencies.md create mode 100644 packages/bridge/bridge-react/src/error-boundary.spec.tsx create mode 100644 packages/bridge/bridge-react/src/error-boundary.tsx create mode 100644 packages/bridge/bridge-react/src/lazy/data-fetch/cache.spec.ts create mode 100644 packages/bridge/bridge-react/src/shared/size-limited-cache.spec.ts create mode 100644 packages/bridge/bridge-react/src/shared/size-limited-cache.ts create mode 100644 packages/dts-plugin/src/server/broker/schedule.spec.ts create mode 100644 packages/enhanced/src/lib/container/runtime/normalizeToPosixPath.ts create mode 100644 packages/enhanced/test/unit/container/runtime/normalizeToPosixPath.test.ts create mode 100644 packages/managers/__tests__/findPackageJson.spec.ts create mode 100644 packages/managers/src/findPackageJson.ts diff --git a/.changeset/slim-cache-path-dependencies.md b/.changeset/slim-cache-path-dependencies.md new file mode 100644 index 00000000000..436595efe6f --- /dev/null +++ b/.changeset/slim-cache-path-dependencies.md @@ -0,0 +1,12 @@ +--- +'@module-federation/bridge-react': patch +'@module-federation/modern-js': patch +'@module-federation/modern-js-v3': patch +'@module-federation/enhanced': patch +'@module-federation/bridge-react-webpack-plugin': patch +'@module-federation/dts-plugin': patch +'@module-federation/managers': patch +'@module-federation/third-party-dts-extractor': patch +--- + +Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. diff --git a/packages/bridge/bridge-react-webpack-plugin/__tests__/utils.spec.ts b/packages/bridge/bridge-react-webpack-plugin/__tests__/utils.spec.ts index 898c49fe497..407a60f5818 100644 --- a/packages/bridge/bridge-react-webpack-plugin/__tests__/utils.spec.ts +++ b/packages/bridge/bridge-react-webpack-plugin/__tests__/utils.spec.ts @@ -59,6 +59,15 @@ describe('test checkVersion: should return the correct major version for react-r it('should return 7', () => { expect(checkVersion('^7.0.0')).toBe(7); }); + + it('should normalize newer major versions to 7', () => { + expect(checkVersion('^10.2.1')).toBe(7); + }); + + it('should return 0 for missing or unsupported versions', () => { + expect(checkVersion('latest')).toBe(0); + expect(checkVersion('^4.9.0')).toBe(0); + }); }); describe('test findPackageJson: should return the correct package.json path for react-router-dom v5, v6 and react-router v7', () => { diff --git a/packages/bridge/bridge-react-webpack-plugin/package.json b/packages/bridge/bridge-react-webpack-plugin/package.json index 37bd4b4317f..2eb6e6f9ba5 100644 --- a/packages/bridge/bridge-react-webpack-plugin/package.json +++ b/packages/bridge/bridge-react-webpack-plugin/package.json @@ -33,9 +33,7 @@ "test": "rstest" }, "dependencies": { - "@module-federation/sdk": "workspace:*", - "semver": "7.6.3", - "@types/semver": "7.5.8" + "@module-federation/sdk": "workspace:*" }, "devDependencies": { "typescript": "7.0.2", diff --git a/packages/bridge/bridge-react-webpack-plugin/src/utils.ts b/packages/bridge/bridge-react-webpack-plugin/src/utils.ts index 23eb6dbac98..f8381154c61 100644 --- a/packages/bridge/bridge-react-webpack-plugin/src/utils.ts +++ b/packages/bridge/bridge-react-webpack-plugin/src/utils.ts @@ -1,26 +1,9 @@ import fs from 'node:fs'; import path from 'node:path'; -import semver from 'semver'; export const checkVersion = (version: string) => { - // Extract the version number starting from the first digit - const versionMatch = version.match(/\d.*/); - if (!versionMatch) return 0; - - const cleanVersion = versionMatch[0]; - - if (semver.gte(cleanVersion, '5.0.0') && semver.lt(cleanVersion, '6.0.0')) { - return 5; - } else if ( - semver.gte(cleanVersion, '6.0.0') && - semver.lt(cleanVersion, '7.0.0') - ) { - return 6; - } else if (semver.gte(cleanVersion, '7.0.0')) { - return 7; - } - - return 0; + const major = Number(version.match(/\d+/)?.[0]); + return major === 5 || major === 6 ? major : major >= 7 ? 7 : 0; }; export const findPackageJson = (startPath: string): string | null => { diff --git a/packages/bridge/bridge-react/package.json b/packages/bridge/bridge-react/package.json index 3e51aad6c48..ae4ebadfdb8 100644 --- a/packages/bridge/bridge-react/package.json +++ b/packages/bridge/bridge-react/package.json @@ -90,6 +90,11 @@ "import": "./dist/lazy-load-component-plugin.es.js", "require": "./dist/lazy-load-component-plugin.cjs.js" }, + "./size-limited-cache": { + "types": "./dist/size-limited-cache.d.ts", + "import": "./dist/size-limited-cache.es.js", + "require": "./dist/size-limited-cache.cjs.js" + }, "./*": "./*" }, "typesVersions": { @@ -135,6 +140,9 @@ ], "data-fetch-server-middleware": [ "./dist/data-fetch-server-middleware.d.ts" + ], + "size-limited-cache": [ + "./dist/size-limited-cache.d.ts" ] } }, @@ -147,8 +155,7 @@ "test:rstest": "pnpm exec rstest --passWithNoTests" }, "dependencies": { - "@module-federation/sdk": "workspace:*", - "lru-cache": "10.4.3" + "@module-federation/sdk": "workspace:*" }, "peerDependencies": { "react": ">=16.9.0", @@ -165,7 +172,6 @@ } }, "devDependencies": { - "react-error-boundary": "^4.1.2", "@module-federation/bridge-shared": "workspace:*", "@rsbuild/plugin-react": "2.1.0", "@testing-library/react": "15.0.7", diff --git a/packages/bridge/bridge-react/scripts/write-dts-entrypoints.mjs b/packages/bridge/bridge-react/scripts/write-dts-entrypoints.mjs index 7dc2ae432f9..2f5d48d5189 100644 --- a/packages/bridge/bridge-react/scripts/write-dts-entrypoints.mjs +++ b/packages/bridge/bridge-react/scripts/write-dts-entrypoints.mjs @@ -19,6 +19,9 @@ const entrypoints = { 'dist/data-fetch-server-middleware.d.ts': [ "export { default } from './lazy/data-fetch/data-fetch-server-middleware';", ], + 'dist/size-limited-cache.d.ts': [ + "export * from './shared/size-limited-cache';", + ], }; for (const [file, lines] of Object.entries(entrypoints)) { diff --git a/packages/bridge/bridge-react/src/error-boundary.spec.tsx b/packages/bridge/bridge-react/src/error-boundary.spec.tsx new file mode 100644 index 00000000000..a0e50bd887c --- /dev/null +++ b/packages/bridge/bridge-react/src/error-boundary.spec.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import { describe, expect, it, rs } from '@rstest/core'; +import { ErrorBoundary } from './error-boundary'; +import type { ErrorFallbackProps } from './types'; + +describe('ErrorBoundary', () => { + it('renders the fallback and can recover after reset', () => { + const consoleError = rs + .spyOn(console, 'error') + .mockImplementation(() => {}); + let shouldThrow = true; + + const Child = () => { + if (shouldThrow) { + throw new Error('render failed'); + } + return
recovered
; + }; + const Fallback = ({ error, resetErrorBoundary }: ErrorFallbackProps) => ( + + ); + + render( + + + , + ); + + fireEvent.click(screen.getByRole('button', { name: 'render failed' })); + expect(screen.getByText('recovered')).not.toBeNull(); + consoleError.mockRestore(); + }); +}); diff --git a/packages/bridge/bridge-react/src/error-boundary.tsx b/packages/bridge/bridge-react/src/error-boundary.tsx new file mode 100644 index 00000000000..36f10be2463 --- /dev/null +++ b/packages/bridge/bridge-react/src/error-boundary.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import type { ErrorFallbackProps } from './types'; + +type ErrorBoundaryProps = { + children: React.ReactNode; + FallbackComponent: React.ComponentType; +}; + +type ErrorBoundaryState = { + didCatch: boolean; + error: Error | null; +}; + +const initialState: ErrorBoundaryState = { didCatch: false, error: null }; + +export class ErrorBoundary extends React.Component< + ErrorBoundaryProps, + ErrorBoundaryState +> { + state = initialState; + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + return { didCatch: true, error }; + } + + private resetErrorBoundary = (..._args: unknown[]) => { + if (this.state.didCatch) { + this.setState(initialState); + } + }; + + render() { + if (this.state.didCatch) { + return ( + + ); + } + + return this.props.children; + } +} diff --git a/packages/bridge/bridge-react/src/lazy/data-fetch/cache.spec.ts b/packages/bridge/bridge-react/src/lazy/data-fetch/cache.spec.ts new file mode 100644 index 00000000000..f8a6261281c --- /dev/null +++ b/packages/bridge/bridge-react/src/lazy/data-fetch/cache.spec.ts @@ -0,0 +1,48 @@ +import { beforeEach, describe, expect, it, rs } from '@rstest/core'; +import { cache, clearStore, configureCache } from './cache'; + +describe('data fetch size-limited cache', () => { + beforeEach(() => { + globalThis.__MF_DATA_FETCH_CACHE__ = undefined; + }); + + it('evicts the least recently used result when full', async () => { + const dataFetch = rs.fn(async ({ key }) => key); + const cachedDataFetch = cache(dataFetch, { + getKey: (...args: any[]) => args[0].key, + }); + configureCache({ maxSize: 28 }); + + await cachedDataFetch({ _id: 'id', isDowngrade: false, key: 'a' }); + await cachedDataFetch({ _id: 'id', isDowngrade: false, key: 'b' }); + await cachedDataFetch({ _id: 'id', isDowngrade: false, key: 'a' }); + await cachedDataFetch({ _id: 'id', isDowngrade: false, key: 'c' }); + await cachedDataFetch({ _id: 'id', isDowngrade: false, key: 'b' }); + + expect(dataFetch).toHaveBeenCalledTimes(4); + }); + + it('does not retain a result larger than the configured limit', async () => { + const dataFetch = rs.fn(async () => 'large result'); + const cachedDataFetch = cache(dataFetch, { + getKey: () => 'large', + }); + configureCache({ maxSize: 10 }); + + await cachedDataFetch({ _id: 'id', isDowngrade: false }); + await cachedDataFetch({ _id: 'id', isDowngrade: false }); + + expect(dataFetch).toHaveBeenCalledTimes(2); + }); + + it('clears cached results', async () => { + const dataFetch = rs.fn(async () => 'result'); + const cachedDataFetch = cache(dataFetch); + + await cachedDataFetch({ _id: 'id', isDowngrade: false }); + clearStore(); + await cachedDataFetch({ _id: 'id', isDowngrade: false }); + + expect(dataFetch).toHaveBeenCalledTimes(2); + }); +}); diff --git a/packages/bridge/bridge-react/src/lazy/data-fetch/cache.ts b/packages/bridge/bridge-react/src/lazy/data-fetch/cache.ts index 17760268dea..e24bdc6c178 100644 --- a/packages/bridge/bridge-react/src/lazy/data-fetch/cache.ts +++ b/packages/bridge/bridge-react/src/lazy/data-fetch/cache.ts @@ -1,4 +1,4 @@ -import { LRUCache } from 'lru-cache'; +import { SizeLimitedCache } from '../../shared/size-limited-cache'; import { getDataFetchCache } from '../utils'; import type { @@ -79,12 +79,15 @@ export function configureCache(config: CacheConfig): void { Object.assign(cacheConfig, config); } -function getLRUCache() { +function getSizeLimitedCache() { const dataFetchCache = getDataFetchCache(); const cacheConfig = getCacheConfig(); if (!dataFetchCache || !dataFetchCache.cacheStore) { - const cacheStore = new LRUCache>>({ + const cacheStore = new SizeLimitedCache< + string, + Map> + >({ maxSize: cacheConfig.maxSize ?? CacheSize.GB, sizeCalculation: (value: Map>): number => { if (!value.size) { @@ -99,8 +102,6 @@ function getLRUCache() { } return size; }, - updateAgeOnGet: true, - updateAgeOnHas: true, }); globalThis.__MF_DATA_FETCH_CACHE__ ||= {}; globalThis.__MF_DATA_FETCH_CACHE__.cacheStore = cacheStore; @@ -183,7 +184,7 @@ export function cache( if (dataFetchOptions.isDowngrade || !dataFetchOptions._id) { return fn(dataFetchOptions); } - const store = getLRUCache(); + const store = getSizeLimitedCache(); const now = Date.now(); const storeKey = dataFetchOptions._id; @@ -273,19 +274,19 @@ export function cache( export function revalidateTag(tag: string): void { const tagKeyMap = getTagKeyMap(); const keys = tagKeyMap.get(tag); - const lruCache = getLRUCache(); + const cacheStore = getSizeLimitedCache(); if (keys) { keys.forEach((key) => { - lruCache?.delete(key); + cacheStore?.delete(key); }); } } export function clearStore(): void { - const lruCache = getLRUCache(); + const cacheStore = getSizeLimitedCache(); const tagKeyMap = getTagKeyMap(); - lruCache?.clear(); + cacheStore?.clear(); delete globalThis.__MF_DATA_FETCH_CACHE__?.cacheStore; tagKeyMap.clear(); } diff --git a/packages/bridge/bridge-react/src/lazy/types.ts b/packages/bridge/bridge-react/src/lazy/types.ts index 36a4da055f9..060f0254981 100644 --- a/packages/bridge/bridge-react/src/lazy/types.ts +++ b/packages/bridge/bridge-react/src/lazy/types.ts @@ -1,5 +1,5 @@ import { MF_DATA_FETCH_TYPE, MF_DATA_FETCH_STATUS } from './constant'; -import type { LRUCache } from 'lru-cache'; +import type { SizeLimitedCache } from '../shared/size-limited-cache'; export type dataFetchFunctionOptions = [ id?: string, @@ -69,7 +69,7 @@ export interface CacheConfig { // key is the id, default is the same with dataFetchMapId, but it can be custom by passing dataFetchParams.id export type MF_DATA_FETCH_CACHE = { - cacheStore?: LRUCache>>; + cacheStore?: SizeLimitedCache>>; tagKeyMap?: Map>; cacheConfig?: CacheConfig; }; diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx index 5e1619c9ba6..174dbf0f3f8 100644 --- a/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx @@ -10,8 +10,9 @@ import type { DestroyParams, RenderParams, CreateRootOptions, + ErrorFallbackProps, } from '../../types'; -import { ErrorBoundary, FallbackProps } from 'react-error-boundary'; +import { ErrorBoundary } from '../../error-boundary'; import { RouterContext } from '../context'; import { LoggerInstance } from '../../utils'; import { federationRuntime } from '../plugin'; @@ -43,16 +44,15 @@ export function createBaseBridgeComponent({ ); }; - const DefaultFallback = ({ error }: FallbackProps) => ( + const DefaultFallback = ({ error }: ErrorFallbackProps) => (

Something went wrong:

-
{error.message}
+
+          {error instanceof Error ? error.message : String(error)}
+        
); - const ErrorBoundaryComponent = - ErrorBoundary as unknown as React.ComponentType; - const omitHostFallback =

>(props: P) => { const nextProps = { ...props }; delete nextProps.fallback; @@ -70,7 +70,7 @@ export function createBaseBridgeComponent({ memoryRoute?: any; propsInfo: T; }) => ( - + ({ }} propsInfo={propsInfo} /> - + ); return { diff --git a/packages/bridge/bridge-react/src/remote/createHelpers.tsx b/packages/bridge/bridge-react/src/remote/createHelpers.tsx index e2c1d47068a..b0580acacde 100644 --- a/packages/bridge/bridge-react/src/remote/createHelpers.tsx +++ b/packages/bridge/bridge-react/src/remote/createHelpers.tsx @@ -1,7 +1,8 @@ import React, { forwardRef } from 'react'; -import { ErrorBoundary, FallbackProps } from 'react-error-boundary'; +import { ErrorBoundary } from '../error-boundary'; import { LoggerInstance } from '../utils'; import { + ErrorFallbackProps, RemoteComponentParams, RemoteComponentProps, RemoteModule, @@ -91,8 +92,6 @@ export function createLazyRemoteComponentFactory( export function createRemoteAppComponentFactory( RemoteApp: React.ComponentType, ) { - const ErrorBoundaryComponent = - ErrorBoundary as unknown as React.ComponentType; const createLazyRemoteComponent = createLazyRemoteComponentFactory(RemoteApp); return function createRemoteAppComponent< @@ -102,15 +101,15 @@ export function createRemoteAppComponentFactory( const LazyComponent = createLazyRemoteComponent(info); return forwardRef((props, ref) => { return ( - + info.fallback as React.ComponentType } > - + ); }); }; diff --git a/packages/bridge/bridge-react/src/shared/size-limited-cache.spec.ts b/packages/bridge/bridge-react/src/shared/size-limited-cache.spec.ts new file mode 100644 index 00000000000..b815c62453a --- /dev/null +++ b/packages/bridge/bridge-react/src/shared/size-limited-cache.spec.ts @@ -0,0 +1,74 @@ +import { describe, expect, it } from '@rstest/core'; +import { SizeLimitedCache } from './size-limited-cache'; + +describe('SizeLimitedCache', () => { + it('evicts the least recently used entries by total size', () => { + const cache = new SizeLimitedCache({ + maxSize: 6, + sizeCalculation: (value) => value.length, + }); + + cache.set('first', 'aaa').set('second', 'bbb'); + expect(cache.get('first')).toBe('aaa'); + + cache.set('third', 'ccc'); + + expect(cache.has('first')).toBe(true); + expect(cache.has('second')).toBe(false); + expect(cache.has('third')).toBe(true); + expect(cache.calculatedSize).toBe(6); + }); + + it('updates size when replacing an entry', () => { + const cache = new SizeLimitedCache({ maxSize: 5 }); + + cache.set('entry', 'first', { size: 2 }); + cache.set('entry', 'second', { size: 4 }); + + expect(cache.get('entry')).toBe('second'); + expect(cache.size).toBe(1); + expect(cache.calculatedSize).toBe(4); + }); + + it('removes an existing entry when its replacement is oversized', () => { + const cache = new SizeLimitedCache({ maxSize: 5 }); + + cache.set('entry', 'first', { size: 2 }); + cache.set('entry', 'oversized', { size: 6 }); + + expect(cache.has('entry')).toBe(false); + expect(cache.calculatedSize).toBe(0); + }); + + it('deletes and clears entries while keeping size accurate', () => { + const cache = new SizeLimitedCache({ maxSize: 5 }); + + cache.set('first', 'a', { size: 2 }); + cache.set('second', 'b', { size: 3 }); + expect(cache.delete('first')).toBe(true); + expect(cache.calculatedSize).toBe(3); + + cache.clear(); + expect(cache.size).toBe(0); + expect(cache.calculatedSize).toBe(0); + }); + + it('can evict an undefined key', () => { + const cache = new SizeLimitedCache({ + maxSize: 2, + }); + + cache.set(undefined, 'first', { size: 2 }); + cache.set('second', 'second', { size: 2 }); + + expect(cache.has(undefined)).toBe(false); + expect(cache.get('second')).toBe('second'); + }); + + it('rejects invalid limits and entry sizes', () => { + expect(() => new SizeLimitedCache({ maxSize: 0 })).toThrow(TypeError); + + const cache = new SizeLimitedCache({ maxSize: 5 }); + expect(() => cache.set('entry', 'value', { size: 0 })).toThrow(TypeError); + }); +}); diff --git a/packages/bridge/bridge-react/src/shared/size-limited-cache.ts b/packages/bridge/bridge-react/src/shared/size-limited-cache.ts new file mode 100644 index 00000000000..a43c0f84d68 --- /dev/null +++ b/packages/bridge/bridge-react/src/shared/size-limited-cache.ts @@ -0,0 +1,115 @@ +export interface SizeLimitedCacheOptions { + maxSize: number; + sizeCalculation?: (value: V, key: K) => number; +} + +export interface SizeLimitedCacheSetOptions { + size?: number; +} + +interface CacheEntry { + value: V; + size: number; +} + +/** + * A small, size-aware least-recently-used cache. + * + * This intentionally implements only the operations used by federation + * packages. Reading or checking an entry refreshes its recency. + */ +export class SizeLimitedCache { + readonly maxSize: number; + + private readonly entries = new Map>(); + private readonly sizeCalculation?: (value: V, key: K) => number; + private currentSize = 0; + + constructor(options: SizeLimitedCacheOptions) { + if (!Number.isInteger(options.maxSize) || options.maxSize <= 0) { + throw new TypeError('maxSize must be a positive integer'); + } + + this.maxSize = options.maxSize; + this.sizeCalculation = options.sizeCalculation; + } + + get size(): number { + return this.entries.size; + } + + get calculatedSize(): number { + return this.currentSize; + } + + get(key: K): V | undefined { + const entry = this.entries.get(key); + if (!entry) { + return undefined; + } + + this.refresh(key, entry); + return entry.value; + } + + has(key: K): boolean { + const entry = this.entries.get(key); + if (!entry) { + return false; + } + + this.refresh(key, entry); + return true; + } + + set(key: K, value: V, options: SizeLimitedCacheSetOptions = {}): this { + const entrySize = options.size ?? this.sizeCalculation?.(value, key) ?? 1; + + if (!Number.isInteger(entrySize) || entrySize <= 0) { + throw new TypeError('entry size must be a positive integer'); + } + + this.delete(key); + + if (entrySize > this.maxSize) { + return this; + } + + this.entries.set(key, { value, size: entrySize }); + this.currentSize += entrySize; + this.evictUntilWithinLimit(); + + return this; + } + + delete(key: K): boolean { + const entry = this.entries.get(key); + if (!entry) { + return false; + } + + this.currentSize -= entry.size; + return this.entries.delete(key); + } + + clear(): void { + this.entries.clear(); + this.currentSize = 0; + } + + private refresh(key: K, entry: CacheEntry): void { + this.entries.delete(key); + this.entries.set(key, entry); + } + + private evictUntilWithinLimit(): void { + while (this.currentSize > this.maxSize) { + const oldest = this.entries.keys().next(); + if (oldest.done) { + this.currentSize = 0; + return; + } + this.delete(oldest.value); + } + } +} diff --git a/packages/bridge/bridge-react/vite.config.ts b/packages/bridge/bridge-react/vite.config.ts index 34568cbef0e..e703d5ea572 100644 --- a/packages/bridge/bridge-react/vite.config.ts +++ b/packages/bridge/bridge-react/vite.config.ts @@ -31,6 +31,10 @@ export default defineConfig({ 'src/lazy/data-fetch/index.ts', ), 'data-fetch': path.resolve(__dirname, 'src/data-fetch.ts'), + 'size-limited-cache': path.resolve( + __dirname, + 'src/shared/size-limited-cache.ts', + ), }, formats: ['cjs', 'es'], fileName: (format, entryName) => `${entryName}.${format}.js`, diff --git a/packages/dts-plugin/package.json b/packages/dts-plugin/package.json index 77146883789..6c662bcb24d 100644 --- a/packages/dts-plugin/package.json +++ b/packages/dts-plugin/package.json @@ -72,13 +72,11 @@ "adm-zip": "0.5.10", "isomorphic-ws": "5.0.0", "undici": "7.28.0", - "node-schedule": "2.1.1", "ws": "8.21.0" }, "devDependencies": { "@module-federation/runtime": "workspace:*", "@rstest/core": "^0.10.6", - "@types/node-schedule": "2.1.7", "@types/ws": "8.5.12", "@vue/tsconfig": "^0.7.0", "directory-tree": "3.5.2", diff --git a/packages/dts-plugin/src/server/broker/Broker.ts b/packages/dts-plugin/src/server/broker/Broker.ts index 4fdca8ec15b..c214dec2e3c 100644 --- a/packages/dts-plugin/src/server/broker/Broker.ts +++ b/packages/dts-plugin/src/server/broker/Broker.ts @@ -1,7 +1,6 @@ import { IncomingMessage, createServer } from 'http'; import { UpdateMode } from '../constant'; import WebSocket from 'isomorphic-ws'; -import schedule from 'node-schedule'; import { parse } from 'url'; import { Publisher } from '../Publisher'; import { getIdentifier, fileLog, error } from '../utils'; @@ -32,6 +31,59 @@ import { DEFAULT_WEB_SOCKET_PORT, WEB_SOCKET_CONNECT_MAGIC_ID as DEFAULT_WEB_SOCKET_CONNECT_MAGIC_ID, } from '../constant'; + +const CLEANUP_HOURS = [0, 3, 6, 9, 12, 15, 18]; + +interface ScheduledTask { + cancel(): void; +} + +export function getNextCleanupDelay(now = new Date()): number { + for (const hour of CLEANUP_HOURS) { + const candidate = new Date(now); + candidate.setHours(hour, 0, 0, 0); + if (candidate.getTime() > now.getTime()) { + return candidate.getTime() - now.getTime(); + } + } + + const nextDay = new Date(now); + nextDay.setDate(nextDay.getDate() + 1); + nextDay.setHours(CLEANUP_HOURS[0], 0, 0, 0); + return nextDay.getTime() - now.getTime(); +} + +export function scheduleCleanup( + callback: () => void, + testIntervalMs = 0, +): ScheduledTask { + let timeout: ReturnType | undefined; + let cancelled = false; + + const scheduleNext = () => { + const delay = testIntervalMs > 0 ? testIntervalMs : getNextCleanupDelay(); + timeout = setTimeout(() => { + if (cancelled) { + return; + } + callback(); + scheduleNext(); + }, delay); + }; + + scheduleNext(); + + return { + cancel() { + cancelled = true; + if (timeout) { + clearTimeout(timeout); + timeout = undefined; + } + }, + }; +} + export class Broker { static readonly WEB_SOCKET_CONNECT_MAGIC_ID = DEFAULT_WEB_SOCKET_CONNECT_MAGIC_ID; @@ -44,7 +96,7 @@ export class Broker { private _webSocketServer?: WebSocket.Server; private _secureWebSocketServer?: WebSocket.Server; private _tmpSubscriberShelter: TmpSubscriberShelter = new Map(); - private _scheduleJob: schedule.Job | null = null; + private _scheduleJob: ScheduledTask | null = null; constructor() { this._setSchedule(); @@ -680,24 +732,11 @@ export class Broker { }); } - // Every day on 0/6/9/12/15//18, Publishers that have not been connected within 1.5 hours will be cleared regularly. + // Every day at 0/3/6/9/12/15/18, publishers that have not been connected within 1.5 hours will be cleared. // If process.env.FEDERATION_SERVER_TEST is set, it will be read at a specified time. private _setSchedule(): void { - const rule = new schedule.RecurrenceRule(); - if (Number(process.env['FEDERATION_SERVER_TEST'])) { - const interval = Number(process.env['FEDERATION_SERVER_TEST']) / 1000; - const second = []; - for (let i = 0; i < 60; i = i + interval) { - second.push(i); - } - rule.second = second; - } else { - rule.second = 0; - rule.hour = [0, 3, 6, 9, 12, 15, 18]; - rule.minute = 0; - } const serverTest = Number(process.env['FEDERATION_SERVER_TEST']); - this._scheduleJob = schedule.scheduleJob(rule, () => { + this._scheduleJob = scheduleCleanup(() => { this._tmpSubscriberShelter.forEach((tmpSubscriber, identifier) => { fileLog( ` _clearTmpSubScriberRelation ${identifier}, ${ @@ -718,7 +757,7 @@ export class Broker { this._clearTmpSubScriberRelation(identifier); } }); - }); + }, serverTest); } private _clearSchedule(): void { diff --git a/packages/dts-plugin/src/server/broker/schedule.spec.ts b/packages/dts-plugin/src/server/broker/schedule.spec.ts new file mode 100644 index 00000000000..40c69f59dfe --- /dev/null +++ b/packages/dts-plugin/src/server/broker/schedule.spec.ts @@ -0,0 +1,37 @@ +import { describe, expect, it, rs } from '@rstest/core'; +import { getNextCleanupDelay, scheduleCleanup } from './Broker'; + +describe('broker cleanup schedule', () => { + it('calculates the next configured cleanup time', () => { + const now = new Date(2026, 0, 1, 7, 30, 0, 0); + const next = new Date(now.getTime() + getNextCleanupDelay(now)); + + expect(next.getFullYear()).toBe(2026); + expect(next.getMonth()).toBe(0); + expect(next.getDate()).toBe(1); + expect(next.getHours()).toBe(9); + expect(next.getMinutes()).toBe(0); + }); + + it('rolls over to midnight after the last cleanup time', () => { + const now = new Date(2026, 0, 1, 19, 0, 0, 0); + const next = new Date(now.getTime() + getNextCleanupDelay(now)); + + expect(next.getDate()).toBe(2); + expect(next.getHours()).toBe(0); + }); + + it('runs at the test interval and stops after cancellation', async () => { + rs.useFakeTimers(); + const callback = rs.fn(); + const task = scheduleCleanup(callback, 5_000); + + await rs.advanceTimersByTimeAsync(10_000); + expect(callback).toHaveBeenCalledTimes(2); + + task.cancel(); + await rs.advanceTimersByTimeAsync(10_000); + expect(callback).toHaveBeenCalledTimes(2); + rs.useRealTimers(); + }); +}); diff --git a/packages/enhanced/package.json b/packages/enhanced/package.json index 50a20300ab8..975cf4aeb5d 100644 --- a/packages/enhanced/package.json +++ b/packages/enhanced/package.json @@ -94,7 +94,6 @@ "@module-federation/runtime-tools": "workspace:*", "@module-federation/sdk": "workspace:*", "@module-federation/cli": "workspace:*", - "upath": "2.0.1", "schema-utils": "4.3.0", "tapable": "2.3.0" }, diff --git a/packages/enhanced/src/lib/container/runtime/normalizeToPosixPath.ts b/packages/enhanced/src/lib/container/runtime/normalizeToPosixPath.ts new file mode 100644 index 00000000000..25928e6e42e --- /dev/null +++ b/packages/enhanced/src/lib/container/runtime/normalizeToPosixPath.ts @@ -0,0 +1,22 @@ +import path from 'path'; + +function toPosixSeparators(value: string): string { + return value.replace(/\\/g, '/').replace(/(? - upath.normalizeSafe(path.normalize(p || '')); +export { normalizeToPosixPath } from './normalizeToPosixPath'; diff --git a/packages/enhanced/test/unit/container/runtime/normalizeToPosixPath.test.ts b/packages/enhanced/test/unit/container/runtime/normalizeToPosixPath.test.ts new file mode 100644 index 00000000000..631713f27d0 --- /dev/null +++ b/packages/enhanced/test/unit/container/runtime/normalizeToPosixPath.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from '@rstest/core'; +import { normalizeToPosixPath } from '../../../../src/lib/container/runtime/normalizeToPosixPath'; + +describe('normalizeToPosixPath', () => { + it.each([ + ['', '.'], + ['a\\b', 'a/b'], + ['.\\a\\b', './a/b'], + ['C:\\foo\\..\\bar', 'C:/bar'], + ['\\\\server\\share\\a\\..\\b', '//server/share/b'], + ['a//b///c', 'a/b/c'], + ['../a/./b', '../a/b'], + ['/a/b/../', '/a/'], + ['C:/foo//bar/', 'C:/foo/bar/'], + ['\\\\.\\pipe\\name', '//./pipe/name'], + ['\\\\?\\C:\\foo\\..\\bar', '//?/C:/bar'], + ])('normalizes %s', (input, expected) => { + expect(normalizeToPosixPath(input)).toBe(expected); + }); +}); diff --git a/packages/managers/__tests__/findPackageJson.spec.ts b/packages/managers/__tests__/findPackageJson.spec.ts new file mode 100644 index 00000000000..f407e103dcc --- /dev/null +++ b/packages/managers/__tests__/findPackageJson.spec.ts @@ -0,0 +1,23 @@ +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { findPackageJson } from '../src/findPackageJson'; + +describe('findPackageJson', () => { + it('finds the closest package.json from a nested directory', () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'mf-managers-')); + const nested = path.join(root, 'a', 'b'); + fs.mkdirSync(nested, { recursive: true }); + fs.writeFileSync(path.join(root, 'package.json'), '{}'); + + expect(findPackageJson(nested)).toBe(path.join(root, 'package.json')); + fs.rmSync(root, { recursive: true, force: true }); + }); + + it('returns undefined when no package.json exists', () => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'mf-managers-')); + + expect(findPackageJson(root)).toBeUndefined(); + fs.rmSync(root, { recursive: true, force: true }); + }); +}); diff --git a/packages/managers/package.json b/packages/managers/package.json index 8bfa57b8198..d56d0937e27 100644 --- a/packages/managers/package.json +++ b/packages/managers/package.json @@ -25,8 +25,7 @@ "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "dependencies": { - "@module-federation/sdk": "workspace:*", - "empathic": "2.0.0" + "@module-federation/sdk": "workspace:*" }, "devDependencies": { "webpack": "5.104.1" diff --git a/packages/managers/src/PKGJsonManager.ts b/packages/managers/src/PKGJsonManager.ts index 8e152fa751d..e81d03d6e06 100644 --- a/packages/managers/src/PKGJsonManager.ts +++ b/packages/managers/src/PKGJsonManager.ts @@ -1,7 +1,7 @@ import path from 'path'; -import { up as findPkgUp } from 'empathic/package'; import fs from 'fs'; import { MFModuleType, logger } from '@module-federation/sdk'; +import { findPackageJson } from './findPackageJson'; export class PKGJsonManager { private _pkg?: Record; @@ -23,7 +23,7 @@ export class PKGJsonManager { return pkg; } catch (_err) { try { - const pkgPath = findPkgUp({ cwd: root }); + const pkgPath = findPackageJson(root); if (!pkgPath) { return {}; } diff --git a/packages/managers/src/SharedManager.ts b/packages/managers/src/SharedManager.ts index d99852db240..514161ca70a 100644 --- a/packages/managers/src/SharedManager.ts +++ b/packages/managers/src/SharedManager.ts @@ -1,4 +1,3 @@ -import { up as findPkgUp } from 'empathic/package'; import path from 'path'; import fs from 'fs'; import { @@ -9,6 +8,7 @@ import { import { NormalizedSharedOptions } from './types'; import { BasicPluginOptionsManager } from './BasicPluginOptionsManager'; import { parseOptions } from './utils'; +import { findPackageJson } from './findPackageJson'; class SharedManager extends BasicPluginOptionsManager { normalizedOptions: NormalizedSharedOptions = {}; @@ -69,9 +69,10 @@ class SharedManager extends BasicPluginOptionsManager", "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, "dependencies": { "@module-federation/rsbuild-plugin": "workspace:*", "@module-federation/bridge-react": "workspace:*", - "lru-cache": "10.4.3", "@module-federation/enhanced": "workspace:*", "@module-federation/runtime": "workspace:*", "@module-federation/node": "workspace:*", "@module-federation/sdk": "workspace:*", "@module-federation/cli": "workspace:*", "@swc/helpers": "0.5.17", - "node-fetch": "3.3.0", - "jiti": "2.4.2", - "react-error-boundary": "4.1.2" + "jiti": "2.4.2" }, "devDependencies": { "@rsbuild/plugin-react": "1.4.5", diff --git a/packages/modernjs-v3/src/cli/mfRuntimePlugins/inject-node-fetch.ts b/packages/modernjs-v3/src/cli/mfRuntimePlugins/inject-node-fetch.ts index 7ea5c64bf32..71a2761e37c 100644 --- a/packages/modernjs-v3/src/cli/mfRuntimePlugins/inject-node-fetch.ts +++ b/packages/modernjs-v3/src/cli/mfRuntimePlugins/inject-node-fetch.ts @@ -1,12 +1,12 @@ import type { ModuleFederationRuntimePlugin } from '@module-federation/enhanced/runtime'; -import nodeFetch from 'node-fetch'; const injectNodeFetchPlugin: () => ModuleFederationRuntimePlugin = () => ({ name: 'inject-node-fetch-plugin', beforeInit(args) { if (!globalThis.fetch) { - // @ts-expect-error inject node-fetch - globalThis.fetch = nodeFetch; + throw new Error( + '@module-federation/modern-js-v3 requires Node.js 18 or later.', + ); } return args; }, diff --git a/packages/modernjs-v3/src/server/fileCache.spec.ts b/packages/modernjs-v3/src/server/fileCache.spec.ts index fc90a0c7c6f..87b08665b55 100644 --- a/packages/modernjs-v3/src/server/fileCache.spec.ts +++ b/packages/modernjs-v3/src/server/fileCache.spec.ts @@ -1,21 +1,39 @@ -import { it, expect, describe, rs } from '@rstest/core'; +import { beforeEach, describe, expect, it, rs } from '@rstest/core'; rs.mock('fs/promises', () => ({ access: () => Promise.resolve(), lstat: () => Promise.resolve({ - mtimeMs: Date.now(), + mtimeMs: 1, size: 4, }), - readFile: () => Promise.resolve('test'), + readFile: rs.fn(() => Promise.resolve('test')), })); +import { readFile } from 'fs/promises'; import { FileCache } from './fileCache'; describe('modern serve static file cache', async () => { + beforeEach(() => { + rs.mocked(readFile).mockClear(); + }); + it('should cache file', async () => { const cache = new FileCache(); const result = await cache.getFile('test.txt'); expect(result?.content).toBe('test'); + + await cache.getFile('test.txt'); + expect(readFile).toHaveBeenCalledTimes(1); + }); + + it('evicts the least recently used file when full', async () => { + const cache = new FileCache(4); + + await cache.getFile('first.txt'); + await cache.getFile('second.txt'); + await cache.getFile('first.txt'); + + expect(readFile).toHaveBeenCalledTimes(3); }); }); diff --git a/packages/modernjs-v3/src/server/fileCache.ts b/packages/modernjs-v3/src/server/fileCache.ts index f509557753f..237a232d0e9 100644 --- a/packages/modernjs-v3/src/server/fileCache.ts +++ b/packages/modernjs-v3/src/server/fileCache.ts @@ -1,5 +1,5 @@ import { access, lstat, readFile } from 'fs/promises'; -import { LRUCache } from 'lru-cache'; +import { SizeLimitedCache } from '@module-federation/bridge-react/size-limited-cache'; const pathExists = async (filepath: string): Promise => { try { @@ -16,9 +16,11 @@ export interface FileResult { } export class FileCache { - private cache = new LRUCache({ - maxSize: 200 * 1024 * 1024, // 200MB - }); + private cache: SizeLimitedCache; + + constructor(maxSize = 200 * 1024 * 1024) { + this.cache = new SizeLimitedCache({ maxSize }); + } /** * Check if file exists and return file info diff --git a/packages/modernjs/package.json b/packages/modernjs/package.json index d4f6ca8c3e6..cf404331f03 100644 --- a/packages/modernjs/package.json +++ b/packages/modernjs/package.json @@ -137,20 +137,19 @@ "types": "./dist/types/cli/index.d.ts", "author": "hanric ", "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, "dependencies": { - "@modern-js/utils": "2.70.5", "@module-federation/rsbuild-plugin": "workspace:*", "@module-federation/bridge-react": "workspace:*", - "lru-cache": "10.4.3", "@module-federation/enhanced": "workspace:*", "@module-federation/runtime": "workspace:*", "@module-federation/node": "workspace:*", "@module-federation/sdk": "workspace:*", "@module-federation/cli": "workspace:*", "@swc/helpers": "0.5.17", - "node-fetch": "3.3.0", - "jiti": "2.4.2", - "react-error-boundary": "4.1.2" + "jiti": "2.4.2" }, "devDependencies": { "@rsbuild/plugin-react": "1.4.5", diff --git a/packages/modernjs/src/cli/mfRuntimePlugins/inject-node-fetch.ts b/packages/modernjs/src/cli/mfRuntimePlugins/inject-node-fetch.ts index 7ea5c64bf32..9c0910f3fc1 100644 --- a/packages/modernjs/src/cli/mfRuntimePlugins/inject-node-fetch.ts +++ b/packages/modernjs/src/cli/mfRuntimePlugins/inject-node-fetch.ts @@ -1,12 +1,12 @@ import type { ModuleFederationRuntimePlugin } from '@module-federation/enhanced/runtime'; -import nodeFetch from 'node-fetch'; const injectNodeFetchPlugin: () => ModuleFederationRuntimePlugin = () => ({ name: 'inject-node-fetch-plugin', beforeInit(args) { if (!globalThis.fetch) { - // @ts-expect-error inject node-fetch - globalThis.fetch = nodeFetch; + throw new Error( + '@module-federation/modern-js requires Node.js 18 or later.', + ); } return args; }, diff --git a/packages/modernjs/src/server/fileCache.spec.ts b/packages/modernjs/src/server/fileCache.spec.ts index fc90a0c7c6f..87b08665b55 100644 --- a/packages/modernjs/src/server/fileCache.spec.ts +++ b/packages/modernjs/src/server/fileCache.spec.ts @@ -1,21 +1,39 @@ -import { it, expect, describe, rs } from '@rstest/core'; +import { beforeEach, describe, expect, it, rs } from '@rstest/core'; rs.mock('fs/promises', () => ({ access: () => Promise.resolve(), lstat: () => Promise.resolve({ - mtimeMs: Date.now(), + mtimeMs: 1, size: 4, }), - readFile: () => Promise.resolve('test'), + readFile: rs.fn(() => Promise.resolve('test')), })); +import { readFile } from 'fs/promises'; import { FileCache } from './fileCache'; describe('modern serve static file cache', async () => { + beforeEach(() => { + rs.mocked(readFile).mockClear(); + }); + it('should cache file', async () => { const cache = new FileCache(); const result = await cache.getFile('test.txt'); expect(result?.content).toBe('test'); + + await cache.getFile('test.txt'); + expect(readFile).toHaveBeenCalledTimes(1); + }); + + it('evicts the least recently used file when full', async () => { + const cache = new FileCache(4); + + await cache.getFile('first.txt'); + await cache.getFile('second.txt'); + await cache.getFile('first.txt'); + + expect(readFile).toHaveBeenCalledTimes(3); }); }); diff --git a/packages/modernjs/src/server/fileCache.ts b/packages/modernjs/src/server/fileCache.ts index f509557753f..237a232d0e9 100644 --- a/packages/modernjs/src/server/fileCache.ts +++ b/packages/modernjs/src/server/fileCache.ts @@ -1,5 +1,5 @@ import { access, lstat, readFile } from 'fs/promises'; -import { LRUCache } from 'lru-cache'; +import { SizeLimitedCache } from '@module-federation/bridge-react/size-limited-cache'; const pathExists = async (filepath: string): Promise => { try { @@ -16,9 +16,11 @@ export interface FileResult { } export class FileCache { - private cache = new LRUCache({ - maxSize: 200 * 1024 * 1024, // 200MB - }); + private cache: SizeLimitedCache; + + constructor(maxSize = 200 * 1024 * 1024) { + this.cache = new SizeLimitedCache({ maxSize }); + } /** * Check if file exists and return file info diff --git a/packages/third-party-dts-extractor/package.json b/packages/third-party-dts-extractor/package.json index 33b41ffc463..b9fd242dca7 100644 --- a/packages/third-party-dts-extractor/package.json +++ b/packages/third-party-dts-extractor/package.json @@ -31,10 +31,6 @@ "types": "./dist/index.d.ts", "author": "hanric ", "license": "MIT", - "dependencies": { - "empathic": "2.0.0", - "exsolve": "1.0.8" - }, "devDependencies": { "@rstest/core": "^0.10.6", "@types/node": "^20.19.5", diff --git a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts index fedd1116790..a2d989804c3 100644 --- a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts +++ b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.spec.ts @@ -1,7 +1,8 @@ import { existsSync, readFileSync, readdirSync } from 'fs'; -import { join } from 'path'; +import { dirname, join } from 'path'; import { describe, expect, it } from '@rstest/core'; import { ThirdPartyExtractor } from './ThirdPartyExtractor'; +import { resolvePackageJson } from './utils'; const readJSONSync = (filePath: string) => JSON.parse(readFileSync(filePath, 'utf-8')); @@ -36,6 +37,13 @@ describe('ThirdPartyExtractor', () => { expect(pkgJson.name).toBe('@types/react'); }); + it('should resolve package.json even when the package does not export it', () => { + const pkgJsonPath = resolvePackageJson('@types/react', packageRoot); + + expect(readJSONSync(pkgJsonPath).name).toBe('@types/react'); + expect(dirname(pkgJsonPath)).toContain('@types'); + }); + it('should correctly collect third party pkg types dir while passing dts file', () => { thirdPartyExtractor.pkgs = {}; thirdPartyExtractor.collectPkgs(` diff --git a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts index 6951ac8e7d3..27315c59a2d 100644 --- a/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts +++ b/packages/third-party-dts-extractor/src/ThirdPartyExtractor.ts @@ -1,9 +1,7 @@ -import { up as findPkgUp } from 'empathic/package'; import { copyFile, lstat, mkdir, readdir } from 'fs/promises'; import { existsSync, readFileSync } from 'fs'; import path from 'path'; -import { resolveModulePath } from 'exsolve'; -import { getTypedName, getPackageRootDir } from './utils'; +import { getTypedName, getPackageRootDir, resolvePackageJson } from './utils'; const ignoredPkgs = ['typescript']; @@ -75,7 +73,7 @@ class ThirdPartyExtractor { if (isNodeUtils(importEntry, importPath)) { return; } - const packageDir = getPackageRootDir(importPath); + const packageDir = getPackageRootDir(importPath, this.context); const pkgJsonPath = path.join(packageDir, 'package.json'); const dir = path.dirname(pkgJsonPath); @@ -97,13 +95,7 @@ class ThirdPartyExtractor { return dir; } else { const typedPkgName = getTypedName(pkg.name); - const typedPkgJsonPath = findPkgUp({ - cwd: path.dirname( - resolveModulePath(`${typedPkgName}/package.json`, { - from: this.context, - }), - ), - }) as string; + const typedPkgJsonPath = resolvePackageJson(typedPkgName, this.context); const typedDir = path.dirname(typedPkgJsonPath); readFileSync(typedPkgJsonPath, 'utf-8'); this.addPkgs(typedPkgName, typedDir); diff --git a/packages/third-party-dts-extractor/src/utils.ts b/packages/third-party-dts-extractor/src/utils.ts index 23dd8316afe..8f5ca5ad68f 100644 --- a/packages/third-party-dts-extractor/src/utils.ts +++ b/packages/third-party-dts-extractor/src/utils.ts @@ -15,13 +15,16 @@ function getTypedName(name: string) { * 5. Otherwise, return the fallback directory (if it contains a package.json). * 6. If all else fails, throw an error. */ -function getPackageRootDir(packageName: string | undefined): string { +function getPackageRootDir( + packageName: string | undefined, + context = process.cwd(), +): string { if (!packageName) { throw new Error('No package name provided.'); } // 1) Resolve the entry file - const entryFile = require.resolve(packageName); + const entryFile = require.resolve(packageName, { paths: [context] }); const entryDir = path.dirname(entryFile); // 2) Fallback: check if there's a package.json in entryDir @@ -81,4 +84,31 @@ function getPackageRootDir(packageName: string | undefined): string { ); } -export { getTypedName, getPackageRootDir }; +function resolvePackageJson(packageName: string, context: string): string { + try { + return require.resolve(`${packageName}/package.json`, { + paths: [context], + }); + } catch { + let currentPath = path.resolve(context); + while (true) { + const candidate = path.join( + currentPath, + 'node_modules', + packageName, + 'package.json', + ); + if (fs.existsSync(candidate)) { + return candidate; + } + + const parentPath = path.dirname(currentPath); + if (parentPath === currentPath) { + throw new Error(`Could not resolve package.json for "${packageName}".`); + } + currentPath = parentPath; + } + } +} + +export { getTypedName, getPackageRootDir, resolvePackageJson }; diff --git a/packages/third-party-dts-extractor/tsup.config.ts b/packages/third-party-dts-extractor/tsup.config.ts index 14fa411aede..ac400be964c 100644 --- a/packages/third-party-dts-extractor/tsup.config.ts +++ b/packages/third-party-dts-extractor/tsup.config.ts @@ -10,6 +10,6 @@ const shared = { }; export default defineConfig([ - { ...shared, format: 'cjs' as const, clean: true, noExternal: ['exsolve'] }, + { ...shared, format: 'cjs' as const, clean: true }, { ...shared, format: 'esm' as const }, ]); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a47b188c604..1ea99f92f2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2925,9 +2925,6 @@ importers: '@module-federation/sdk': specifier: workspace:* version: link:../../sdk - lru-cache: - specifier: 10.4.3 - version: 10.4.3 devDependencies: '@module-federation/bridge-shared': specifier: workspace:* @@ -2971,9 +2968,6 @@ importers: react-dom: specifier: 18.3.1 version: 18.3.1(react@18.3.1) - react-error-boundary: - specifier: ^4.1.2 - version: 4.1.2(react@18.3.1) react-router: specifier: 7.16.0 version: 7.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2992,12 +2986,6 @@ importers: '@module-federation/sdk': specifier: workspace:* version: link:../../sdk - '@types/semver': - specifier: 7.5.8 - version: 7.5.8 - semver: - specifier: 7.6.3 - version: 7.6.3 devDependencies: typescript: specifier: 7.0.2 @@ -3255,9 +3243,6 @@ importers: isomorphic-ws: specifier: 5.0.0 version: 5.0.0(ws@8.21.0) - node-schedule: - specifier: 2.1.1 - version: 2.1.1 undici: specifier: 7.28.0 version: 7.28.0 @@ -3271,9 +3256,6 @@ importers: '@rstest/core': specifier: ^0.10.6 version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) - '@types/node-schedule': - specifier: 2.1.7 - version: 2.1.7 '@types/ws': specifier: 8.5.12 version: 8.5.12 @@ -3343,9 +3325,6 @@ importers: tapable: specifier: 2.3.0 version: 2.3.0 - upath: - specifier: 2.0.1 - version: 2.0.1 vue-tsc: specifier: '>=1.0.24' version: 2.2.12(typescript@7.0.2) @@ -3422,9 +3401,6 @@ importers: '@module-federation/sdk': specifier: workspace:* version: link:../sdk - empathic: - specifier: 2.0.0 - version: 2.0.0 devDependencies: webpack: specifier: 5.104.1 @@ -3584,9 +3560,6 @@ importers: packages/modernjs: dependencies: - '@modern-js/utils': - specifier: 2.70.5 - version: 2.70.5 '@module-federation/bridge-react': specifier: workspace:* version: link:../bridge/bridge-react @@ -3614,21 +3587,12 @@ importers: jiti: specifier: 2.4.2 version: 2.4.2 - lru-cache: - specifier: 10.4.3 - version: 10.4.3 - node-fetch: - specifier: 3.3.0 - version: 3.3.0 react: specifier: '>=17' version: 19.2.7 react-dom: specifier: '>=17' version: 19.2.7(react@19.2.7) - react-error-boundary: - specifier: 4.1.2 - version: 4.1.2(react@19.2.7) react-router: specifier: ^7 version: 7.12.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -3705,15 +3669,6 @@ importers: jiti: specifier: 2.4.2 version: 2.4.2 - lru-cache: - specifier: 10.4.3 - version: 10.4.3 - node-fetch: - specifier: 3.3.0 - version: 3.3.0 - react-error-boundary: - specifier: 4.1.2 - version: 4.1.2(react@18.3.1) react-router: specifier: ^7 version: 7.12.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -4187,13 +4142,6 @@ importers: version: 0.6.2 packages/third-party-dts-extractor: - dependencies: - empathic: - specifier: 2.0.0 - version: 2.0.0 - exsolve: - specifier: 1.0.8 - version: 1.0.8 devDependencies: '@rstest/core': specifier: ^0.10.6 From 9d386adcf5dd31ceb92a9ee60d5a5655688a7513 Mon Sep 17 00:00:00 2001 From: Rodrigo Yokota <53323214+ryok90@users.noreply.github.com> Date: Tue, 14 Jul 2026 20:07:16 -0300 Subject: [PATCH 23/37] ci(release): show release type in approval (#4904) --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d51c7a667a9..9c54e0e261e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,5 @@ name: Release +run-name: Release ${{ inputs.version }} from ${{ inputs.branch }} on: workflow_dispatch: inputs: @@ -20,7 +21,7 @@ permissions: jobs: release: - name: Release + name: Release ${{ inputs.version }} from ${{ inputs.branch }} if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' }} runs-on: ubuntu-latest environment: npm From f7964589d0fe0bf6c4d648ffcc738b0673b830af Mon Sep 17 00:00:00 2001 From: Hanric Date: Wed, 15 Jul 2026 11:21:15 +0800 Subject: [PATCH 24/37] fix(modern-js): set optimization target from ssr config (#4900) --- .changeset/tidy-cats-optimize.md | 7 +++ .../modernjs-v3/src/cli/configPlugin.spec.ts | 57 ++++++++++++++++++- packages/modernjs-v3/src/cli/configPlugin.ts | 22 +++++++ packages/modernjs-v3/src/types/index.ts | 6 ++ .../modernjs/src/cli/configPlugin.spec.ts | 53 ++++++++++++++++- packages/modernjs/src/cli/configPlugin.ts | 22 +++++++ packages/modernjs/src/types/index.ts | 6 ++ 7 files changed, 171 insertions(+), 2 deletions(-) create mode 100644 .changeset/tidy-cats-optimize.md diff --git a/.changeset/tidy-cats-optimize.md b/.changeset/tidy-cats-optimize.md new file mode 100644 index 00000000000..76ecb26da1c --- /dev/null +++ b/.changeset/tidy-cats-optimize.md @@ -0,0 +1,7 @@ +--- +"@module-federation/modern-js": patch +"@module-federation/modern-js-v3": patch +--- + +Automatically select federation optimization targets for Modern.js browser and +SSR builds, with an option to disable this behavior. diff --git a/packages/modernjs-v3/src/cli/configPlugin.spec.ts b/packages/modernjs-v3/src/cli/configPlugin.spec.ts index c034e2c80eb..b2d4866144c 100644 --- a/packages/modernjs-v3/src/cli/configPlugin.spec.ts +++ b/packages/modernjs-v3/src/cli/configPlugin.spec.ts @@ -1,5 +1,9 @@ import { it, expect, describe, rs, afterEach } from '@rstest/core'; -import { moduleFederationConfigPlugin, patchMFConfig } from './configPlugin'; +import { + moduleFederationConfigPlugin, + patchMFConfig, + setDefaultOptimizationTarget, +} from './configPlugin'; import logger from '../logger'; const mfConfig = { @@ -110,6 +114,57 @@ describe('patchMFConfig', async () => { }); }); +describe('setDefaultOptimizationTarget', () => { + it('defaults to web when SSR is disabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, false, false); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'web' } }, + }); + }); + + it('defaults to web for the browser target when SSR is enabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, false); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'web' } }, + }); + }); + + it('defaults to node for the server target when SSR is enabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, true); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'node' } }, + }); + }); + + it('preserves an explicitly configured target', () => { + const config = { + name: 'host', + experiments: { optimization: { target: 'web' as const } }, + }; + + setDefaultOptimizationTarget(config, true, true); + + expect(config.experiments.optimization.target).toBe('web'); + }); + + it('does not set a target when autoOptimization is disabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, true, false); + + expect(config).toStrictEqual({ name: 'host' }); + }); +}); + describe('moduleFederationConfigPlugin', async () => { it('disables lazyCompilation when the project is a producer', async () => { const warnSpy = rs.spyOn(logger, 'warn').mockImplementation(() => {}); diff --git a/packages/modernjs-v3/src/cli/configPlugin.ts b/packages/modernjs-v3/src/cli/configPlugin.ts index 9822c0f6328..98ea54c0ed3 100644 --- a/packages/modernjs-v3/src/cli/configPlugin.ts +++ b/packages/modernjs-v3/src/cli/configPlugin.ts @@ -232,6 +232,22 @@ export const patchMFConfig = ( return mfConfig; }; +export const setDefaultOptimizationTarget = ( + mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions, + enableSSR: boolean, + isServer: boolean, + autoOptimization = true, +) => { + if (!autoOptimization) { + return; + } + + mfConfig.experiments ||= {}; + mfConfig.experiments.optimization ||= {}; + mfConfig.experiments.optimization.target ??= + enableSSR && isServer ? 'node' : 'web'; +}; + function patchIgnoreWarning(chain: BundlerChainConfig) { const ignoreWarnings = chain.get('ignoreWarnings') || []; const ignoredMsgs = [ @@ -404,6 +420,12 @@ export const moduleFederationConfigPlugin = ( addMyTypes2Ignored(chain, !isWeb ? ssrConfig : csrConfig); const targetMFConfig = !isWeb ? ssrConfig : csrConfig; + setDefaultOptimizationTarget( + targetMFConfig, + enableSSR, + !isWeb, + userConfig.originPluginOptions.autoOptimization, + ); patchMFConfig(targetMFConfig, !isWeb); if ( diff --git a/packages/modernjs-v3/src/types/index.ts b/packages/modernjs-v3/src/types/index.ts index fa1d505437a..5a94cd184b1 100644 --- a/packages/modernjs-v3/src/types/index.ts +++ b/packages/modernjs-v3/src/types/index.ts @@ -4,6 +4,12 @@ import type { StatsAssetResource } from '@module-federation/rsbuild-plugin/utils export interface PluginOptions { config?: moduleFederationPlugin.ModuleFederationPluginOptions; configPath?: string; + /** + * Automatically set the federation optimization target from the Modern.js + * SSR and bundler target configuration. + * @default true + */ + autoOptimization?: boolean; ssr?: | { distOutputDir?: string; diff --git a/packages/modernjs/src/cli/configPlugin.spec.ts b/packages/modernjs/src/cli/configPlugin.spec.ts index 2bb3eaebee0..fc4f032a6b6 100644 --- a/packages/modernjs/src/cli/configPlugin.spec.ts +++ b/packages/modernjs/src/cli/configPlugin.spec.ts @@ -1,5 +1,5 @@ import { it, expect, describe } from '@rstest/core'; -import { patchMFConfig } from './configPlugin'; +import { patchMFConfig, setDefaultOptimizationTarget } from './configPlugin'; import { getIPV4 } from './utils'; const mfConfig = { @@ -80,3 +80,54 @@ describe('patchMFConfig', async () => { }); }); }); + +describe('setDefaultOptimizationTarget', () => { + it('defaults to web when SSR is disabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, false, false); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'web' } }, + }); + }); + + it('defaults to web for the browser target when SSR is enabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, false); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'web' } }, + }); + }); + + it('defaults to node for the server target when SSR is enabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, true); + + expect(config).toMatchObject({ + experiments: { optimization: { target: 'node' } }, + }); + }); + + it('preserves an explicitly configured target', () => { + const config = { + name: 'host', + experiments: { optimization: { target: 'web' as const } }, + }; + + setDefaultOptimizationTarget(config, true, true); + + expect(config.experiments.optimization.target).toBe('web'); + }); + + it('does not set a target when autoOptimization is disabled', () => { + const config = { name: 'host' }; + + setDefaultOptimizationTarget(config, true, true, false); + + expect(config).toStrictEqual({ name: 'host' }); + }); +}); diff --git a/packages/modernjs/src/cli/configPlugin.ts b/packages/modernjs/src/cli/configPlugin.ts index c5efdb9700f..f079d99bcf3 100644 --- a/packages/modernjs/src/cli/configPlugin.ts +++ b/packages/modernjs/src/cli/configPlugin.ts @@ -238,6 +238,22 @@ export const patchMFConfig = ( return mfConfig; }; +export const setDefaultOptimizationTarget = ( + mfConfig: moduleFederationPlugin.ModuleFederationPluginOptions, + enableSSR: boolean, + isServer: boolean, + autoOptimization = true, +) => { + if (!autoOptimization) { + return; + } + + mfConfig.experiments ||= {}; + mfConfig.experiments.optimization ||= {}; + mfConfig.experiments.optimization.target ??= + enableSSR && isServer ? 'node' : 'web'; +}; + function patchIgnoreWarning(chain: BundlerChainConfig) { const ignoreWarnings = chain.get('ignoreWarnings') || []; const ignoredMsgs = [ @@ -414,6 +430,12 @@ export const moduleFederationConfigPlugin = ( addMyTypes2Ignored(chain, !isWeb ? ssrConfig : csrConfig); const targetMFConfig = !isWeb ? ssrConfig : csrConfig; + setDefaultOptimizationTarget( + targetMFConfig, + enableSSR, + !isWeb, + userConfig.originPluginOptions.autoOptimization, + ); patchMFConfig(targetMFConfig, !isWeb); if ( diff --git a/packages/modernjs/src/types/index.ts b/packages/modernjs/src/types/index.ts index fa1d505437a..5a94cd184b1 100644 --- a/packages/modernjs/src/types/index.ts +++ b/packages/modernjs/src/types/index.ts @@ -4,6 +4,12 @@ import type { StatsAssetResource } from '@module-federation/rsbuild-plugin/utils export interface PluginOptions { config?: moduleFederationPlugin.ModuleFederationPluginOptions; configPath?: string; + /** + * Automatically set the federation optimization target from the Modern.js + * SSR and bundler target configuration. + * @default true + */ + autoOptimization?: boolean; ssr?: | { distOutputDir?: string; From ea490ae13f49447ca19a02b3ad29c9fc57597391 Mon Sep 17 00:00:00 2001 From: Hanric Date: Wed, 15 Jul 2026 15:32:17 +0800 Subject: [PATCH 25/37] feat(runtime): allow disabling unused capabilities (#4901) --- .changeset/quiet-runtime-capabilities.md | 9 + .../docs/en/configure/experiments.mdx | 54 +++-- .../docs/en/guide/advanced/_meta.json | 5 + .../advanced/runtime-size-optimization.mdx | 219 ++++++++++++++++++ .../docs/pt-BR/configure/experiments.mdx | 54 +++-- .../docs/pt-BR/guide/advanced/_meta.json | 5 + .../advanced/runtime-size-optimization.mdx | 219 ++++++++++++++++++ .../docs/zh/configure/experiments.mdx | 57 +++-- apps/website-new/docs/zh/configure/index.mdx | 2 + .../docs/zh/guide/advanced/_meta.json | 5 + .../advanced/runtime-size-optimization.mdx | 219 ++++++++++++++++++ .../lib/container/ModuleFederationPlugin.ts | 40 +++- .../container/ModuleFederationPlugin.check.ts | 94 ++++++-- .../container/ModuleFederationPlugin.json | 8 + .../container/ModuleFederationPlugin.ts | 10 +- .../experiments-optimization/index.js | 54 +++++ .../webpack.config.js | 45 +++- .../__tests__/ModuleFederationPlugin.spec.ts | 66 ++++++ packages/rspack/src/ModuleFederationPlugin.ts | 18 +- packages/runtime-core/src/core.ts | 50 ++-- packages/runtime-core/src/index.ts | 12 +- .../src/plugins/snapshot/disabled.ts | 5 + packages/runtime-core/src/remote/disabled.ts | 38 +++ packages/runtime-core/src/remote/index.ts | 15 ++ packages/runtime-core/src/shared/disabled.ts | 40 ++++ packages/runtime-core/src/shared/index.ts | 2 +- packages/runtime-core/src/type/plugin.ts | 10 +- .../types/plugins/ModuleFederationPlugin.ts | 8 + packages/webpack-bundler-runtime/src/index.ts | 39 +++- packages/webpack-bundler-runtime/src/init.ts | 211 +++++++++-------- 30 files changed, 1388 insertions(+), 225 deletions(-) create mode 100644 .changeset/quiet-runtime-capabilities.md create mode 100644 apps/website-new/docs/en/guide/advanced/runtime-size-optimization.mdx create mode 100644 apps/website-new/docs/pt-BR/guide/advanced/runtime-size-optimization.mdx create mode 100644 apps/website-new/docs/zh/guide/advanced/runtime-size-optimization.mdx create mode 100644 packages/runtime-core/src/plugins/snapshot/disabled.ts create mode 100644 packages/runtime-core/src/remote/disabled.ts create mode 100644 packages/runtime-core/src/shared/disabled.ts diff --git a/.changeset/quiet-runtime-capabilities.md b/.changeset/quiet-runtime-capabilities.md new file mode 100644 index 00000000000..d981c50ffbf --- /dev/null +++ b/.changeset/quiet-runtime-capabilities.md @@ -0,0 +1,9 @@ +--- +'@module-federation/enhanced': patch +'@module-federation/rspack': patch +'@module-federation/runtime-core': patch +'@module-federation/sdk': patch +'@module-federation/webpack-bundler-runtime': patch +--- + +Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. diff --git a/apps/website-new/docs/en/configure/experiments.mdx b/apps/website-new/docs/en/configure/experiments.mdx index 0ccfb9b7208..5c85dff1d08 100644 --- a/apps/website-new/docs/en/configure/experiments.mdx +++ b/apps/website-new/docs/en/configure/experiments.mdx @@ -56,16 +56,30 @@ This object contains flags related to build-time optimizations that can affect t When set to `true`, this option defines the `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during the build. In the `@module-federation/runtime-core`, this prevents the `snapshotPlugin()` and `generatePreloadAssetsPlugin()` from being included and initialized within the Module Federation instance. **Impact:** -* **Benefit:** Can reduce the overall bundle size of the Module Federation runtime by excluding the code for these two plugins. -* **Cost:** Disables the functionality provided by these plugins. The `snapshotPlugin` is crucial for the "mf-manifest protocol" – it's responsible for generating or providing runtime access to a build manifest (e.g., `mf-manifest.json`) containing metadata about exposed modules, shared dependencies, versions, and remotes. Disabling it means: - * The runtime loses access to this build manifest data. - * Features relying on the manifest, such as dynamic remote discovery, manifest-based version compatibility checks, advanced asset preloading (also handled by the removed `generatePreloadAssetsPlugin`), and potentially runtime debugging/introspection tools, will not function correctly or will be unavailable. - * Use this option only if you do not rely on these manifest-driven features and prioritize a minimal runtime footprint. + +- **Benefit:** Can reduce the overall bundle size of the Module Federation runtime by excluding the code for these two plugins. +- **Cost:** Disables the functionality provided by these plugins. The `snapshotPlugin` is crucial for the "mf-manifest protocol" – it's responsible for generating or providing runtime access to a build manifest (e.g., `mf-manifest.json`) containing metadata about exposed modules, shared dependencies, versions, and remotes. Disabling it means: + - The runtime loses access to this build manifest data. + - Features relying on the manifest, such as dynamic remote discovery, manifest-based version compatibility checks, advanced asset preloading (also handled by the removed `generatePreloadAssetsPlugin`), and potentially runtime debugging/introspection tools, will not function correctly or will be unavailable. + - Use this option only if you do not rely on these manifest-driven features and prioritize a minimal runtime footprint. :::warning **Caution:** Setting `disableSnapshot: true` will disable the mf-manifest protocol. This means you will lose TypeScript syncing support and hot module replacement (HMR) for federated modules. If you are only using `.js` remotes (not manifest-based remotes), you will not lose any functionality as the `js` remotes do not support these capabilities anyways. ::: +### disableRemote and disableShared + +- Type: `boolean` +- Required: No +- Default: `false` + +These options remove independent runtime-core capabilities at build time: + +- `disableRemote` removes the complete remote consumption path, including registration, entry loading, preloading, reading and executing exposed modules, and related snapshot handling. It does not remove the `exposes` or `container.get` generated for the current producer. Use it only when the build never consumes or dynamically registers remotes. +- `disableShared` removes shared dependency registration, resolution, and loading. A minimal empty share scope is retained so a remote without shared dependencies can still initialize. + +The options can be combined. Calling an API for a disabled capability throws an explicit error. Keep every option at its default unless the build is guaranteed not to use that capability. + ### target - Type: `'web' | 'node'` @@ -75,12 +89,13 @@ When set to `true`, this option defines the `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLU This option defines the `ENV_TARGET` global constant during the build, specifying the intended execution environment. **Impact:** -* **`target: 'web'`**: Optimizes the build for browser environments. - * Ensures browser-specific remote entry loading mechanisms are used (`loadEntryDom`). - * Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within the `@module-federation/sdk`. Functions like `createScriptNode` and `loadScriptNode`, along with their required Node.js built-in modules (e.g., `vm`, `path`, `http`), are completely removed from the bundle, significantly reducing its size. -* **`target: 'node'`**: Optimizes the build for Node.js environments. - * Ensures Node.js-specific remote entry loading mechanisms are used (`loadEntryNode`). - * Includes the necessary Node.js-specific functions from the SDK (`createScriptNode`, `loadScriptNode`) in the bundle, allowing the federated application to function correctly in Node.js. + +- **`target: 'web'`**: Optimizes the build for browser environments. + - Ensures browser-specific remote entry loading mechanisms are used (`loadEntryDom`). + - Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within the `@module-federation/sdk`. Functions like `createScriptNode` and `loadScriptNode`, along with their required Node.js built-in modules (e.g., `vm`, `path`, `http`), are completely removed from the bundle, significantly reducing its size. +- **`target: 'node'`**: Optimizes the build for Node.js environments. + - Ensures Node.js-specific remote entry loading mechanisms are used (`loadEntryNode`). + - Includes the necessary Node.js-specific functions from the SDK (`createScriptNode`, `loadScriptNode`) in the bundle, allowing the federated application to function correctly in Node.js. Explicitly setting this value is recommended to ensure the intended optimizations are applied, especially in universal or server-side rendering scenarios. @@ -88,16 +103,17 @@ Explicitly setting this value is recommended to ensure the intended optimization The following table demonstrates how different combinations of the `disableSnapshot`, `target: 'web'`, and `externalRuntime` optimization flags affect the size of the generated `remoteEntry.js` file. These measurements can help you choose the right trade-off between runtime features and bundle size for your use case. -| Optimization Flags | remoteEntry.js | Gzip Size | Brotli Size | -|---------------------------------------------|:--------------:|:---------:|:-----------:| -| No optimization flags enabled | 69K | 21437 B | 19024 B | -| `disableSnapshot: true` | 65K | 20096 B | 17860 B | -| `target: 'web'` | 60K | 19314 B | 17105 B | -| Both enabled | 56K | 17998 B | 15982 B | -| Both enabled + `externalRuntime: true` | 14K | 5381 B | 4703 B | -| Both disabled + `externalRuntime: true` | 22K | 8222 B | 7269 B | +| Optimization Flags | remoteEntry.js | Gzip Size | Brotli Size | +| --------------------------------------- | :------------: | :-------: | :---------: | +| No optimization flags enabled | 69K | 21437 B | 19024 B | +| `disableSnapshot: true` | 65K | 20096 B | 17860 B | +| `target: 'web'` | 60K | 19314 B | 17105 B | +| Both enabled | 56K | 17998 B | 15982 B | +| Both enabled + `externalRuntime: true` | 14K | 5381 B | 4703 B | +| Both disabled + `externalRuntime: true` | 22K | 8222 B | 7269 B | **Notes:** + - Enabling both `disableSnapshot` and `target: 'web'` provides the greatest reduction in bundle size, especially when combined with `externalRuntime: true`. - Using the external runtime (`externalRuntime: true`) can dramatically reduce the size of your remote entry, but requires that the consumer provides the runtime. - Smaller bundle sizes can lead to faster load times and improved performance, but may disable certain features (see above for details on what each flag does). diff --git a/apps/website-new/docs/en/guide/advanced/_meta.json b/apps/website-new/docs/en/guide/advanced/_meta.json index c75da14498f..4dc184c495f 100644 --- a/apps/website-new/docs/en/guide/advanced/_meta.json +++ b/apps/website-new/docs/en/guide/advanced/_meta.json @@ -1,4 +1,9 @@ [ + { + "type": "file", + "name": "runtime-size-optimization", + "label": "Optimize Runtime Size" + }, "shared-tree-shaking", "multiple-shared-scope", { diff --git a/apps/website-new/docs/en/guide/advanced/runtime-size-optimization.mdx b/apps/website-new/docs/en/guide/advanced/runtime-size-optimization.mdx new file mode 100644 index 00000000000..75213ffe767 --- /dev/null +++ b/apps/website-new/docs/en/guide/advanced/runtime-size-optimization.mdx @@ -0,0 +1,219 @@ +# Optimize Runtime Size + +The {props.name || 'Module Federation'} runtime includes remote consumption, shared dependencies, and Manifest / Snapshot capabilities by default. This covers most use cases out of the box, but code for unused capabilities can still be included in the final output. + +Use `experiments.optimization` to remove capabilities that a build will definitely not use and reduce its runtime size. + +:::warning Before you enable these options + +These options remove code at build time. They are not feature flags that can be re-enabled after the page starts. Calling an API whose capability was removed throws an error. Rebuild and redeploy after changing an option. + +::: + +## Decide what this build needs + +Do not decide from the Host or Remote label alone. A Remote can consume other Remotes, while a Host can avoid shared dependencies entirely. Base the decision on what this build actually does. + +| Capability | Keep it when | Enable when it is definitely unused | +| --- | --- | --- | +| Remote consumption | `remotes` is configured, or the build calls `loadRemote`, `registerRemotes`, or `preloadRemote` | `disableRemote` | +| Shared dependencies | `shared` is configured, or the build registers, initializes, or loads shared dependencies | `disableShared` | +| Manifest / Snapshot | The build uses Manifest remotes, preloading, type synchronization, hot updates, DevTools, or runtime plugins that depend on Snapshot data | `disableSnapshot` | + +`disableRemote` removes the ability of the current build to consume other Remotes. It does not remove the producer-side `exposes` or `container.get` generated by the bundler. A producer that only exposes modules and never consumes another Remote can still enable it. + +When a build has no `exposes`, the Webpack and Rspack plugins also remove container entry initialization from the consumer's `main.js` automatically. No `disableExpose` option is needed. This does not change the producer's `remoteEntry.js`. + +## Configuration + +Webpack and Rspack accept the same options in `ModuleFederationPlugin`: + +```ts title="rspack.config.ts" +import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack'; + +export default { + plugins: [ + new ModuleFederationPlugin({ + name: 'app_remote', + filename: 'remoteEntry.js', + exposes: { + './Button': './src/Button', + }, + experiments: { + optimization: { + target: 'web', + disableRemote: true, + disableShared: true, + disableSnapshot: true, + }, + }, + }), + ], +}; +``` + +For Webpack, change the import to `@module-federation/enhanced/webpack`. + +This combination is suitable for a minimal producer that only exposes modules, does not consume other Remotes, does not use shared dependencies, and does not depend on Manifest / Snapshot data. Start from the defaults and enable only options that are safe for your build. + +### Configure a runtime-only project with environment variables + +If your project bundles `@module-federation/runtime` or `@module-federation/runtime-core` directly without `ModuleFederationPlugin`, use environment variables and replace them with build-time booleans in your bundler configuration. + +For example, a project that does not consume Remotes, use shared dependencies or Snapshot data, and has no `exposes` can build with: + +```bash +FEDERATION_OPTIMIZE_NO_REMOTE=true \ +FEDERATION_OPTIMIZE_NO_SHARED=true \ +FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \ +FEDERATION_HAS_EXPOSES=false \ +pnpm build +``` + +Webpack must replace the values explicitly: + +```ts title="webpack.config.ts" +import webpack from 'webpack'; + +const federationDefines = { + FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true', + ), + FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true', + ), + FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true', + ), + FEDERATION_HAS_EXPOSES: JSON.stringify( + process.env.FEDERATION_HAS_EXPOSES !== 'false', + ), +}; + +export default { + plugins: [new webpack.DefinePlugin(federationDefines)], +}; +``` + +With Rspack, pass the same `federationDefines` object to `rspack.DefinePlugin`. With Vite, pass it to the top-level `define` option. + +Leaving environment variables as runtime strings is not enough. The bundler must replace them with `true` or `false` at build time so the minifier can remove the corresponding code. All capabilities remain enabled when no value is provided, preserving existing behavior. + +## What each option removes + +### disableRemote + +Removes remote registration, entry loading, preloading, exposed-module retrieval and execution. It also removes Snapshot handling used only for remote loading and the remote-loading function generated by Webpack. + +Suitable for: + +- producers that only expose modules and never consume another Remote; +- standalone builds without `remotes` that never register a Remote at runtime. + +Do not use it for: + +- Hosts with configured `remotes`; +- applications that call `loadRemote`, `registerRemotes`, or `preloadRemote`; +- applications that rely on a Manifest to discover or load Remotes dynamically. + +### disableShared + +Removes shared dependency registration, selection, and loading, together with Webpack shared consumption, shared initialization, initial shared installation, fallback handling, and the shared tree-shaking plugin. A minimal empty share scope remains so a remote entry that does not use shared dependencies can still initialize. + +Use it only when the build has no `shared` configuration and never registers or loads a shared dependency through runtime APIs. + +Keep this capability when React, Vue, a component library, or another dependency must be reused across applications, remain a singleton, or participate in version selection. + +### disableSnapshot + +Removes Manifest / Snapshot and related preload capabilities. It can reduce the output further, but its impact is broader than the other options. + +Enable it only when using plain JavaScript Remotes without type synchronization, hot updates, preloading, DevTools, dynamic discovery, or another Snapshot-dependent feature. See the [Manifest / Snapshot guide](/guide/basic/manifest-snapshot.html#impact-of-disablesnapshot) for the complete impact. + +## Common combinations + +### Producer that only exposes modules + +If it does not consume other Remotes, enable: + +```ts +optimization: { + disableRemote: true, +} +``` + +Enable `disableShared` or `disableSnapshot` as well only when the producer does not use those capabilities. + +### Host without shared dependencies + +The Host still needs remote consumption, so disable only shared handling: + +```ts +optimization: { + disableShared: true, +} +``` + +### Lightweight Host using plain JavaScript Remotes + +If it does not use shared dependencies or Manifest / Snapshot data: + +```ts +optimization: { + target: 'web', + disableShared: true, + disableSnapshot: true, +} +``` + +Remote consumption must remain enabled. + +## Difference from externalRuntime + +`externalRuntime` extracts runtime code from each `remoteEntry.js` so multiple builds can reuse one external runtime. It mainly reduces duplicate downloads. `disableRemote`, `disableShared`, and `disableSnapshot` remove capabilities that the build does not need. + +You can combine both approaches: remove unused capabilities first, then use `externalRuntime` to reduce duplicated code across outputs. When using an external runtime, the page must provide a compatible runtime in advance. See [experiments.externalRuntime](/configure/experiments.html#externalruntime) for configuration details. + +## Verify that the optimization works + +### 1. Establish a comparable baseline + +Record the output size before optimization with the same build mode, minification settings, and dependency versions. Do not compare development output with production output. + +### 2. Enable one option at a time + +Build and record the size of `remoteEntry.js` or the file that actually contains the runtime. Confirm each reduction before combining options so it is easier to identify both the benefit and any lost behavior. + +The repository test fixture produced the following results. All three builds target the web and disable Snapshot support to isolate the two options. These values illustrate the relative reduction; actual results vary by project and version. + +| Configuration | Minified size | Reduction | +| --- | ---: | ---: | +| Remote and shared enabled | 73,154 B | - | +| `disableRemote: true` | 52,916 B | about 27.66% | +| `disableShared: true` | 50,008 B | about 31.64% | + +When `exposes` is not configured, the reduction affects the consumer's `main.js`, not the producer's `remoteEntry.js`. The following builds use the same entry, dependencies, and production settings; only container entry initialization changes. + +| Consumer `main.js` | Minified | Gzip | Reduction | +| --- | ---: | ---: | ---: | +| Container entry initialization included | 79,328 B | 23,897 B | - | +| No `exposes` | 78,344 B | 23,689 B | 984 B (1.24%), 208 B gzip (0.87%) | + +### 3. Test real application flows + +At minimum, verify: + +- initial page load and refresh; +- every remote module entry; +- dynamic registration and preload paths; +- shared dependency singleton and version behavior; +- development hot updates and type synchronization; +- DevTools, runtime plugins, and monitoring. + +If an explicit disabled-capability error appears, the build still needs that capability. Restore the corresponding option to `false` and rebuild. + +## Further reading + +- [Complete experiments configuration](/configure/experiments.html) +- [Manifest / Snapshot](/guide/basic/manifest-snapshot.html) +- [Shared Dependency Tree Shaking](/guide/advanced/shared-tree-shaking.html) diff --git a/apps/website-new/docs/pt-BR/configure/experiments.mdx b/apps/website-new/docs/pt-BR/configure/experiments.mdx index af14fe7fe3b..1556fa1a6d8 100644 --- a/apps/website-new/docs/pt-BR/configure/experiments.mdx +++ b/apps/website-new/docs/pt-BR/configure/experiments.mdx @@ -56,16 +56,30 @@ Este objeto contains flags related para build-time optimizations esse pode affec Quando definir para `true`, este opção defines o `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during o build. No `@module-federation/runtime-core`, este prevents o `snapshotPlugin()` e `generatePreloadAssetsPlugin()` de being included e initialized within o Module Federation instance. **Impact:** -* **Benefit:** Can reduce o overall bundle size do Module Federation runtime by excluding o code for these two plugins. -* **Cost:** Disables o functionality fornecido by these plugins. O `snapshotPlugin` é crucial para o "mf-manifest protocol" – it's responsible for generating ou providing runtime access para uma build manifest (e.g., `mf-manifest.json`) containing metadata about módulo expostos, dependências compartilhadas, versões, e remotes. Disabling it means: - * O runtime loses access para este build manifest dados. - * Features relying no manifest, such as dynamic remote discovery, manifest-based versão compatibility checks, advanced asset preloading (também handled pelo removed `generatePreloadAssetsPlugin`), e potentially runtime debugging/introspection tools, vai não função correctly ou vai ser unavailable. - * Use este opção apenas se você não rely on these manifest-driven features e prioritize uma minimal runtime footprint. + +- **Benefit:** Can reduce o overall bundle size do Module Federation runtime by excluding o code for these two plugins. +- **Cost:** Disables o functionality fornecido by these plugins. O `snapshotPlugin` é crucial para o "mf-manifest protocol" – it's responsible for generating ou providing runtime access para uma build manifest (e.g., `mf-manifest.json`) containing metadata about módulo expostos, dependências compartilhadas, versões, e remotes. Disabling it means: + - O runtime loses access para este build manifest dados. + - Features relying no manifest, such as dynamic remote discovery, manifest-based versão compatibility checks, advanced asset preloading (também handled pelo removed `generatePreloadAssetsPlugin`), e potentially runtime debugging/introspection tools, vai não função correctly ou vai ser unavailable. + - Use este opção apenas se você não rely on these manifest-driven features e prioritize uma minimal runtime footprint. :::warning **Caution:** Setting `disableSnapshot: true` vai disable o mf-manifest protocol. Este means você vai lose TypeScript syncing suporte e hot módulo replacement (HMR) for módulos federados. Se você são apenas usando `.js` remotes (não manifest-based remotes), você vai não lose any functionality as o `js` remotes não suporte these capabilities anyways. ::: +### disableRemote e disableShared + +- Tipo: `boolean` +- Obrigatório: Não +- Padrão: `false` + +Estas opções removem capacidades independentes do runtime-core durante o build: + +- `disableRemote` remove todo o fluxo de consumo de remotes, incluindo registro, carregamento da entrada, pré-carregamento, leitura e execução de módulos expostos e processamento de snapshots relacionado. Ele não remove os `exposes` nem o `container.get` gerados para o produtor atual. Use apenas quando o build nunca consumir ou registrar remotes dinamicamente. +- `disableShared` remove o registro, a resolução e o carregamento de dependências compartilhadas. Um escopo compartilhado vazio e mínimo é mantido para permitir a inicialização de remotes sem dependências compartilhadas. + +As opções podem ser combinadas. Chamar uma API de uma capacidade desabilitada gera um erro explícito. Mantenha o valor padrão sempre que o build ainda puder usar a capacidade correspondente. + ### target - Tipo: `'web' | 'node'` @@ -75,12 +89,13 @@ Quando definir para `true`, este opção defines o `FEDERATION_OPTIMIZE_NO_SNAPS Este opção defines o `ENV_TARGET` global constant during o build, specifying o intended execution environment. **Impact:** -* **`target: 'web'`**: Optimizes o build for navegador environments. - * Ensures navegador-specific remote entry carregamento mechanisms são usado (`loadEntryDom`). - * Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within o `@module-federation/sdk`. Funções like `createScriptNode` e `loadScriptNode`, along com their obrigatório Node.js built-em módulos (e.g., `vm`, `path`, `http`), são completamente removed do bundle, significantly reducing its size. -* **`target: 'node'`**: Optimizes o build for Node.js environments. - * Ensures Node.js-specific remote entry carregamento mechanisms são usado (`loadEntryNode`). - * Includes o necessário Node.js-specific funções do SDK (`createScriptNode`, `loadScriptNode`) no bundle, allowing o federated aplicação para função correctly em Node.js. + +- **`target: 'web'`**: Optimizes o build for navegador environments. + - Ensures navegador-specific remote entry carregamento mechanisms são usado (`loadEntryDom`). + - Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within o `@module-federation/sdk`. Funções like `createScriptNode` e `loadScriptNode`, along com their obrigatório Node.js built-em módulos (e.g., `vm`, `path`, `http`), são completamente removed do bundle, significantly reducing its size. +- **`target: 'node'`**: Optimizes o build for Node.js environments. + - Ensures Node.js-specific remote entry carregamento mechanisms são usado (`loadEntryNode`). + - Includes o necessário Node.js-specific funções do SDK (`createScriptNode`, `loadScriptNode`) no bundle, allowing o federated aplicação para função correctly em Node.js. Explicitly setting este valor é recomendado para garantir o intended optimizations são applied, especialmente em universal ou do lado do servidor renderização scenarios. @@ -88,16 +103,17 @@ Explicitly setting este valor é recomendado para garantir o intended optimizati O seguinte table demonstrates como diferente combinations do `disableSnapshot`, `target: 'web'`, e `externalRuntime` optimization flags affect o size do generated `remoteEntry.js` arquivo. Esses measurements pode help você choose o right trade-off entre runtime features e bundle size for your use case. -| Optimization Flags | remoteEntry.js | Gzip Size | Brotli Size | -|---------------------------------------------|:--------------:|:---------:|:-----------:| -| No optimization flags habilitado | 69K | 21437 B | 19024 B | -| `disableSnapshot: true` | 65K | 20096 B | 17860 B | -| `target: 'web'` | 60K | 19314 B | 17105 B | -| Both habilitado | 56K | 17998 B | 15982 B | -| Both habilitado + `externalRuntime: true` | 14K | 5381 B | 4703 B | -| Both disabled + `externalRuntime: true` | 22K | 8222 B | 7269 B | +| Optimization Flags | remoteEntry.js | Gzip Size | Brotli Size | +| ----------------------------------------- | :------------: | :-------: | :---------: | +| No optimization flags habilitado | 69K | 21437 B | 19024 B | +| `disableSnapshot: true` | 65K | 20096 B | 17860 B | +| `target: 'web'` | 60K | 19314 B | 17105 B | +| Both habilitado | 56K | 17998 B | 15982 B | +| Both habilitado + `externalRuntime: true` | 14K | 5381 B | 4703 B | +| Both disabled + `externalRuntime: true` | 22K | 8222 B | 7269 B | **Notes:** + - Enabling both `disableSnapshot` e `target: 'web'` fornece uma ferramenta greatest reduction em bundle size, especialmente quando combined com `externalRuntime: true`. - Usando o external runtime (`externalRuntime: true`) pode dramatically reduce o size de your remote entry, but requires esse o consumer fornece uma ferramenta runtime. - Smaller bundle sizes pode lead para faster carregue times e improved performance, but may disable certain features (see above for details no que each flag does). diff --git a/apps/website-new/docs/pt-BR/guide/advanced/_meta.json b/apps/website-new/docs/pt-BR/guide/advanced/_meta.json index c75da14498f..2331e7de251 100644 --- a/apps/website-new/docs/pt-BR/guide/advanced/_meta.json +++ b/apps/website-new/docs/pt-BR/guide/advanced/_meta.json @@ -1,4 +1,9 @@ [ + { + "type": "file", + "name": "runtime-size-optimization", + "label": "Otimizar o tamanho do runtime" + }, "shared-tree-shaking", "multiple-shared-scope", { diff --git a/apps/website-new/docs/pt-BR/guide/advanced/runtime-size-optimization.mdx b/apps/website-new/docs/pt-BR/guide/advanced/runtime-size-optimization.mdx new file mode 100644 index 00000000000..240ec0c983e --- /dev/null +++ b/apps/website-new/docs/pt-BR/guide/advanced/runtime-size-optimization.mdx @@ -0,0 +1,219 @@ +# Otimizar o tamanho do runtime + +O runtime do {props.name || 'Module Federation'} inclui, por padrão, consumo de módulos remotos, dependências compartilhadas e recursos de Manifest / Snapshot. Isso atende à maioria dos cenários sem configuração adicional, mas o código de recursos não utilizados ainda pode entrar no resultado final. + +Use `experiments.optimization` para remover, durante o build, recursos que uma aplicação certamente não utilizará e reduzir o tamanho do runtime. + +:::warning Antes de habilitar estas opções + +Estas opções removem código durante o build. Elas não são flags que podem ser reativadas depois que a página inicia. Chamar uma API cujo recurso foi removido gera um erro. Depois de alterar uma opção, faça um novo build e uma nova publicação. + +::: + +## Decida do que este build precisa + +Não decida apenas pelo nome Host ou Remote. Um Remote também pode consumir outros Remotes, enquanto um Host pode não usar dependências compartilhadas. Considere o que este build realmente faz. + +| Recurso | Quando deve ser mantido | Habilite quando não for utilizado | +| --- | --- | --- | +| Consumo de módulos remotos | `remotes` está configurado, ou o build chama `loadRemote`, `registerRemotes` ou `preloadRemote` | `disableRemote` | +| Dependências compartilhadas | `shared` está configurado, ou o build registra, inicializa ou carrega dependências compartilhadas | `disableShared` | +| Manifest / Snapshot | O build usa Remotes por Manifest, preloading, sincronização de tipos, atualizações a quente, DevTools ou plugins de runtime que dependem de Snapshot | `disableSnapshot` | + +`disableRemote` remove a capacidade do build atual de consumir outros Remotes. Ele não remove o `exposes` nem o `container.get` gerados pelo bundler para o produtor. Um produtor que apenas expõe módulos e nunca consome outro Remote pode habilitar essa opção. + +Quando um build não tem `exposes`, os plugins de Webpack e Rspack também removem automaticamente a inicialização do container do `main.js` do consumidor. Não é necessária uma opção `disableExpose`. Isso não altera o `remoteEntry.js` do produtor. + +## Configuração + +Webpack e Rspack aceitam as mesmas opções em `ModuleFederationPlugin`: + +```ts title="rspack.config.ts" +import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack'; + +export default { + plugins: [ + new ModuleFederationPlugin({ + name: 'app_remote', + filename: 'remoteEntry.js', + exposes: { + './Button': './src/Button', + }, + experiments: { + optimization: { + target: 'web', + disableRemote: true, + disableShared: true, + disableSnapshot: true, + }, + }, + }), + ], +}; +``` + +Para Webpack, altere o import para `@module-federation/enhanced/webpack`. + +Essa combinação é adequada para um produtor mínimo que apenas expõe módulos, não consome outros Remotes, não usa dependências compartilhadas e não depende de Manifest / Snapshot. Comece com os valores padrão e habilite somente opções que sejam seguras para o seu build. + +### Configurar um projeto que usa apenas o runtime com variáveis de ambiente + +Se o projeto empacota `@module-federation/runtime` ou `@module-federation/runtime-core` diretamente, sem `ModuleFederationPlugin`, use variáveis de ambiente e substitua-as por valores booleanos durante o build na configuração do bundler. + +Por exemplo, um projeto que não consome Remotes, não usa dependências compartilhadas nem Snapshot e não tem `exposes` pode usar: + +```bash +FEDERATION_OPTIMIZE_NO_REMOTE=true \ +FEDERATION_OPTIMIZE_NO_SHARED=true \ +FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \ +FEDERATION_HAS_EXPOSES=false \ +pnpm build +``` + +No Webpack, os valores devem ser substituídos explicitamente: + +```ts title="webpack.config.ts" +import webpack from 'webpack'; + +const federationDefines = { + FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true', + ), + FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true', + ), + FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true', + ), + FEDERATION_HAS_EXPOSES: JSON.stringify( + process.env.FEDERATION_HAS_EXPOSES !== 'false', + ), +}; + +export default { + plugins: [new webpack.DefinePlugin(federationDefines)], +}; +``` + +No Rspack, passe o mesmo objeto `federationDefines` para `rspack.DefinePlugin`. No Vite, passe-o para a opção `define` no nível principal. + +Não basta deixar as variáveis de ambiente como strings no código executado. O bundler deve substituí-las por `true` ou `false` durante o build para que o minificador remova o código correspondente. Quando nenhum valor é fornecido, todos os recursos continuam habilitados, preservando o comportamento existente. + +## O que cada opção remove + +### disableRemote + +Remove o registro de Remotes, o carregamento de entradas, o preloading, a obtenção e a execução de módulos expostos. Também remove o tratamento de Snapshot usado apenas pelo carregamento remoto e a função de carregamento remoto gerada pelo Webpack. + +É adequado para: + +- produtores que apenas expõem módulos e nunca consomem outro Remote; +- builds independentes sem `remotes` que nunca registram um Remote em runtime. + +Não use em: + +- Hosts com `remotes` configurados; +- aplicações que chamam `loadRemote`, `registerRemotes` ou `preloadRemote`; +- aplicações que dependem de Manifest para descobrir ou carregar Remotes dinamicamente. + +### disableShared + +Remove o registro, a seleção e o carregamento de dependências compartilhadas, além do consumo compartilhado, da inicialização compartilhada, da instalação compartilhada inicial, do fallback e do plugin de tree shaking compartilhado do Webpack. Um escopo compartilhado vazio e mínimo permanece para que uma entrada remota sem dependências compartilhadas ainda possa ser inicializada. + +Use apenas quando o build não tiver configuração `shared` e nunca registrar ou carregar uma dependência compartilhada pelas APIs de runtime. + +Mantenha esse recurso quando React, Vue, uma biblioteca de componentes ou outra dependência precisar ser reutilizada entre aplicações, permanecer singleton ou participar da seleção de versões. + +### disableSnapshot + +Remove Manifest / Snapshot e os recursos relacionados de preloading. Isso pode reduzir ainda mais o resultado, mas o impacto é mais amplo que o das outras opções. + +Habilite apenas ao usar Remotes JavaScript comuns, sem sincronização de tipos, atualizações a quente, preloading, DevTools, descoberta dinâmica ou outro recurso que dependa de Snapshot. Consulte o [guia de Manifest / Snapshot](/guide/basic/manifest-snapshot.html#impact-de-disablesnapshot) para ver o impacto completo. + +## Combinações comuns + +### Produtor que apenas expõe módulos + +Se ele não consome outros Remotes, habilite: + +```ts +optimization: { + disableRemote: true, +} +``` + +Habilite também `disableShared` ou `disableSnapshot` somente se o produtor não usar esses recursos. + +### Host sem dependências compartilhadas + +O Host ainda precisa consumir módulos remotos, portanto desabilite apenas o tratamento compartilhado: + +```ts +optimization: { + disableShared: true, +} +``` + +### Host leve usando Remotes JavaScript comuns + +Se ele não usa dependências compartilhadas nem Manifest / Snapshot: + +```ts +optimization: { + target: 'web', + disableShared: true, + disableSnapshot: true, +} +``` + +O consumo de módulos remotos deve permanecer habilitado. + +## Diferença em relação a externalRuntime + +`externalRuntime` extrai o código de runtime de cada `remoteEntry.js` para que vários builds reutilizem um único runtime externo. Ele reduz principalmente downloads duplicados. `disableRemote`, `disableShared` e `disableSnapshot` removem recursos de que o build não precisa. + +As duas abordagens podem ser combinadas: primeiro remova os recursos não utilizados e depois use `externalRuntime` para reduzir código duplicado entre os resultados. Ao usar um runtime externo, a página deve fornecer antecipadamente um runtime compatível. Consulte [experiments.externalRuntime](/configure/experiments.html#externalruntime) para ver os detalhes de configuração. + +## Verifique se a otimização funciona + +### 1. Estabeleça uma referência comparável + +Registre o tamanho do resultado antes da otimização usando o mesmo modo de build, as mesmas opções de minificação e as mesmas versões de dependências. Não compare um build de desenvolvimento com um build de produção. + +### 2. Habilite uma opção de cada vez + +Faça o build e registre o tamanho do `remoteEntry.js` ou do arquivo que realmente contém o runtime. Confirme cada redução antes de combinar opções. Isso facilita identificar tanto o benefício quanto a perda de algum comportamento necessário. + +O caso de teste do repositório produziu os resultados abaixo. Os três builds usam o alvo web e desabilitam Snapshot para isolar as duas opções. Os valores demonstram a redução relativa; os resultados reais variam conforme o projeto e a versão. + +| Configuração | Tamanho minificado | Redução | +| --- | ---: | ---: | +| Recursos remotos e compartilhados habilitados | 73.154 B | - | +| `disableRemote: true` | 52.916 B | cerca de 27,66% | +| `disableShared: true` | 50.008 B | cerca de 31,64% | + +Quando `exposes` não está configurado, a redução afeta o `main.js` do consumidor, não o `remoteEntry.js` do produtor. Os builds abaixo usam a mesma entrada, dependências e opções de produção; apenas a inicialização da entrada do container muda. + +| `main.js` do consumidor | Minificado | Gzip | Redução | +| --- | ---: | ---: | ---: | +| Inicialização da entrada do container incluída | 79.328 B | 23.897 B | - | +| Sem `exposes` | 78.344 B | 23.689 B | 984 B (1,24%), 208 B com gzip (0,87%) | + +### 3. Teste os fluxos reais da aplicação + +Verifique, no mínimo: + +- carregamento inicial e atualização da página; +- todas as entradas de módulos remotos; +- caminhos de registro dinâmico e preloading; +- comportamento de singleton e versão das dependências compartilhadas; +- atualizações a quente e sincronização de tipos no desenvolvimento; +- DevTools, plugins de runtime e monitoramento. + +Se aparecer um erro explícito informando que um recurso foi desabilitado, o build ainda precisa desse recurso. Restaure a opção correspondente para `false` e faça um novo build. + +## Leitura adicional + +- [Configuração completa de experiments](/configure/experiments.html) +- [Manifest / Snapshot](/guide/basic/manifest-snapshot.html) +- [Tree shaking de dependências compartilhadas](/guide/advanced/shared-tree-shaking.html) diff --git a/apps/website-new/docs/zh/configure/experiments.mdx b/apps/website-new/docs/zh/configure/experiments.mdx index 07fe39d0b28..dd4e9357cb3 100644 --- a/apps/website-new/docs/zh/configure/experiments.mdx +++ b/apps/website-new/docs/zh/configure/experiments.mdx @@ -8,7 +8,7 @@ - 是否必填:否 - 默认值:`false` -启用 `asyncStartup` 后,所有 {props.brandName || props.name || 'Module Federation'} 入口将默认以异步方式初始化。这意味着: +启用 `asyncStartup` 后,所有 {props.brandName || props.name || 'Module Federation'} 入口将默认以异步方式初始化。这意味着: - 无需在应用顶部手动添加 `import()` 语句(例如 `import('./bootstrap')`) - 所有入口都会自动处理异步初始化 @@ -43,7 +43,6 @@ ::: - ## optimization 该对象包含与构建期优化相关的标记,这些标记会影响 Module Federation 运行时的体积与行为。 @@ -57,16 +56,30 @@ 当设置为 `true` 时,该选项会在构建期间将全局常量 `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` 定义为 `true`。在 `@module-federation/runtime-core` 中,这会阻止 `snapshotPlugin()` 与 `generatePreloadAssetsPlugin()` 被打包并在 Module Federation 实例中初始化。 **影响:** -* **收益:** 排除这两个插件的代码后,可减小 {props.brandName || props.name || 'Module Federation'} 运行时的整体包体积。 -* **代价:** 会禁用这两个插件提供的能力。`snapshotPlugin` 对 “mf-manifest 协议” 非常关键,它负责生成或在运行时提供构建清单(例如 `mf-manifest.json`)的访问能力,清单中包含暴露模块、共享依赖、版本与远程模块等元数据。禁用后意味着: - * 运行时将无法访问这份构建清单数据。 - * 依赖清单的能力(如动态远程发现、基于清单的版本兼容检查、高级资源预加载(也由被移除的 `generatePreloadAssetsPlugin` 处理)以及可能的运行时调试/自省工具)将无法正常工作或不可用。 - * 仅当你不依赖这些由清单驱动的能力,并且更优先考虑最小化运行时体积时,才建议开启此选项。 + +- **收益:** 排除这两个插件的代码后,可减小 {props.brandName || props.name || 'Module Federation'} 运行时的整体包体积。 +- **代价:** 会禁用这两个插件提供的能力。`snapshotPlugin` 对 “mf-manifest 协议” 非常关键,它负责生成或在运行时提供构建清单(例如 `mf-manifest.json`)的访问能力,清单中包含暴露模块、共享依赖、版本与远程模块等元数据。禁用后意味着: + - 运行时将无法访问这份构建清单数据。 + - 依赖清单的能力(如动态远程发现、基于清单的版本兼容检查、高级资源预加载(也由被移除的 `generatePreloadAssetsPlugin` 处理)以及可能的运行时调试/自省工具)将无法正常工作或不可用。 + - 仅当你不依赖这些由清单驱动的能力,并且更优先考虑最小化运行时体积时,才建议开启此选项。 :::warning **注意:** 设置 `disableSnapshot: true` 会禁用 manifest 协议。这意味着你将失去联邦模块的 TypeScript 同步支持与热更新(HMR)能力。如果你只使用 `.js` 类型的远程模块(非基于 manifest 的远程模块),则不会损失功能,因为 `.js` 远程本身不支持这些能力。 ::: +### disableRemote 和 disableShared + +- 类型:`boolean` +- 是否必填:否 +- 默认值:`false` + +这两个选项会在构建时分别移除 runtime-core 中对应的能力: + +- `disableRemote`:移除完整的远程消费流程,包括注册、入口加载、预加载、读取和执行远程暴露模块及相关快照处理。它不会删除当前生产者由构建工具生成的 `exposes` 或 `container.get`。仅当当前构建不会消费或动态注册任何远程模块时使用。 +- `disableShared`:移除共享依赖的注册、选择与加载。运行时会保留最小的空共享作用域,使不使用共享依赖的远程入口仍能初始化。 + +两个选项可以组合使用。调用已关闭能力对应的接口时会直接报出明确错误。只有在确认当前构建一定不会使用某项能力时,才应开启对应选项。 + ### target - 类型:`'web' | 'node'` @@ -76,12 +89,13 @@ 该选项会在构建期间定义全局常量 `ENV_TARGET`,用于指定目标运行环境。 **影响:** -* **`target: 'web'`**:针对浏览器环境优化构建。 - * 确保使用浏览器端的远程入口加载机制(`loadEntryDom`)。 - * 关键点在于会对 `@module-federation/sdk` 中 Node.js 专属代码启用 tree-shaking/死代码消除。`createScriptNode`、`loadScriptNode` 等函数及其依赖的 Node.js 内置模块(如 `vm`、`path`、`http`)会被完全移出产物,从而显著减小包体积。 -* **`target: 'node'`**:针对 Node.js 环境优化构建。 - * 确保使用 Node.js 端的远程入口加载机制(`loadEntryNode`)。 - * 会把 SDK 中 Node.js 场景所需的函数(`createScriptNode`、`loadScriptNode`)保留在产物中,保证联邦应用在 Node.js 中正常运行。 + +- **`target: 'web'`**:针对浏览器环境优化构建。 + - 确保使用浏览器端的远程入口加载机制(`loadEntryDom`)。 + - 关键点在于会对 `@module-federation/sdk` 中 Node.js 专属代码启用 tree-shaking/死代码消除。`createScriptNode`、`loadScriptNode` 等函数及其依赖的 Node.js 内置模块(如 `vm`、`path`、`http`)会被完全移出产物,从而显著减小包体积。 +- **`target: 'node'`**:针对 Node.js 环境优化构建。 + - 确保使用 Node.js 端的远程入口加载机制(`loadEntryNode`)。 + - 会把 SDK 中 Node.js 场景所需的函数(`createScriptNode`、`loadScriptNode`)保留在产物中,保证联邦应用在 Node.js 中正常运行。 建议显式设置该值,以确保应用预期优化,尤其是在同构或服务端渲染场景中。 @@ -89,16 +103,17 @@ 下表展示了 `disableSnapshot`、`target: 'web'` 与 `externalRuntime` 这几个优化标记在不同组合下,对生成的 `remoteEntry.js` 文件体积的影响。这些数据可帮助你在运行时功能与包体积之间做出取舍。 -| 优化标记组合 | remoteEntry.js | Gzip Size | Brotli Size | -|--------------------------------------------|:--------------:|:---------:|:-----------:| -| 未启用任何优化标记 | 69K | 21437 B | 19024 B | -| `disableSnapshot: true` | 65K | 20096 B | 17860 B | -| `target: 'web'` | 60K | 19314 B | 17105 B | -| 两者同时启用 | 56K | 17998 B | 15982 B | -| 两者启用 + `externalRuntime: true` | 14K | 5381 B | 4703 B | -| 两者关闭 + `externalRuntime: true` | 22K | 8222 B | 7269 B | +| 优化标记组合 | remoteEntry.js | Gzip Size | Brotli Size | +| ---------------------------------- | :------------: | :-------: | :---------: | +| 未启用任何优化标记 | 69K | 21437 B | 19024 B | +| `disableSnapshot: true` | 65K | 20096 B | 17860 B | +| `target: 'web'` | 60K | 19314 B | 17105 B | +| 两者同时启用 | 56K | 17998 B | 15982 B | +| 两者启用 + `externalRuntime: true` | 14K | 5381 B | 4703 B | +| 两者关闭 + `externalRuntime: true` | 22K | 8222 B | 7269 B | **说明:** + - 同时开启 `disableSnapshot` 与 `target: 'web'` 可获得更明显的体积下降,配合 `externalRuntime: true` 时效果最佳。 - 使用外部运行时(`externalRuntime: true`)可大幅缩小 remote entry 体积,但前提是消费者侧提供运行时。 - 更小的包体积通常意味着更快的加载速度与更好的性能,但也可能禁用部分能力(各标记行为见上文)。 diff --git a/apps/website-new/docs/zh/configure/index.mdx b/apps/website-new/docs/zh/configure/index.mdx index 7a3d7735e1a..469172f1cc4 100644 --- a/apps/website-new/docs/zh/configure/index.mdx +++ b/apps/website-new/docs/zh/configure/index.mdx @@ -39,6 +39,8 @@ type ModuleFederationOptions { provideExternalRuntime?: boolean; optimization?: { disableSnapshot?: boolean; + disableRemote?: boolean; + disableShared?: boolean; target?: 'web' | 'node'; }; }; diff --git a/apps/website-new/docs/zh/guide/advanced/_meta.json b/apps/website-new/docs/zh/guide/advanced/_meta.json index 056f8035e52..175431613d1 100644 --- a/apps/website-new/docs/zh/guide/advanced/_meta.json +++ b/apps/website-new/docs/zh/guide/advanced/_meta.json @@ -1,4 +1,9 @@ [ + { + "type": "file", + "name": "runtime-size-optimization", + "label": "优化运行时体积" + }, "shared-tree-shaking", "multiple-shared-scope", { diff --git a/apps/website-new/docs/zh/guide/advanced/runtime-size-optimization.mdx b/apps/website-new/docs/zh/guide/advanced/runtime-size-optimization.mdx new file mode 100644 index 00000000000..d5eb498de2c --- /dev/null +++ b/apps/website-new/docs/zh/guide/advanced/runtime-size-optimization.mdx @@ -0,0 +1,219 @@ +# 优化运行时体积 + +{props.name || 'Module Federation'} 的运行时默认包含远程模块消费、共享依赖和 Manifest / Snapshot 等能力。这样可以直接覆盖大多数使用方式,但如果某个构建只使用其中一部分能力,未使用的代码仍可能进入最终产物。 + +你可以通过 `experiments.optimization` 在**构建时**移除确定不会使用的能力,从而减小运行时体积。 + +:::warning 使用前提 + +这些开关会真正移除代码,不是可以在页面运行后重新打开的功能开关。关闭某项能力后,如果代码仍然调用对应接口,运行时会直接报错。修改开关后必须重新构建和发布。 + +::: + +## 先判断当前构建需要什么 + +不要只根据应用被称为 Host 或 Remote 来决定开关。一个 Remote 也可能继续消费其他 Remote,一个 Host 也可能完全不使用共享依赖。应当根据这个构建实际执行的行为判断。 + +| 能力 | 什么时候必须保留 | 确认不会使用时可开启 | +| ------------------- | ----------------------------------------------------------------------------------- | -------------------- | +| 远程模块消费 | 配置了 `remotes`,或会调用 `loadRemote`、`registerRemotes`、`preloadRemote` | `disableRemote` | +| 共享依赖 | 配置了 `shared`,或会调用共享依赖注册、初始化、加载接口 | `disableShared` | +| Manifest / Snapshot | 使用 Manifest 远程、预加载、类型同步、热更新、DevTools 或依赖 Snapshot 的运行时插件 | `disableSnapshot` | + +`disableRemote` 关闭的是当前构建消费其他 Remote 的完整流程,不会删除构建工具为当前生产者生成的 `exposes` 或 `container.get`。因此,一个只向外提供模块、自己不消费其他 Remote 的生产者,仍然可以开启它。 + +如果当前构建没有配置 `exposes`,Webpack 和 Rspack 插件还会自动从消费者入口 `main.js` 中移除容器入口初始化代码,不需要增加 `disableExpose` 开关。这不会改变生产者的 `remoteEntry.js`。 + +## 配置方式 + +Webpack 和 Rspack 都可以在 `ModuleFederationPlugin` 中使用相同配置: + +```ts title="rspack.config.ts" +import { ModuleFederationPlugin } from '@module-federation/enhanced/rspack'; + +export default { + plugins: [ + new ModuleFederationPlugin({ + name: 'app_remote', + filename: 'remoteEntry.js', + exposes: { + './Button': './src/Button', + }, + experiments: { + optimization: { + target: 'web', + disableRemote: true, + disableShared: true, + disableSnapshot: true, + }, + }, + }), + ], +}; +``` + +使用 Webpack 时,只需要把导入地址改为 `@module-federation/enhanced/webpack`。 + +上面的组合适用于一个非常精简的纯生产者:它只对外提供模块,不消费其他 Remote、不使用共享依赖,也不依赖 Manifest / Snapshot。实际项目应从默认值开始,只打开已经确认安全的选项。 + +### 纯 Runtime 项目通过环境变量配置 + +如果项目直接打包 `@module-federation/runtime` 或 `@module-federation/runtime-core`,没有使用上面的 `ModuleFederationPlugin`,可以用环境变量控制构建,并在打包配置中把环境变量替换为编译期布尔值。 + +例如,一个不消费 Remote、不使用共享依赖和 Snapshot,也不包含 `exposes` 的项目可以这样构建: + +```bash +FEDERATION_OPTIMIZE_NO_REMOTE=true \ +FEDERATION_OPTIMIZE_NO_SHARED=true \ +FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN=true \ +FEDERATION_HAS_EXPOSES=false \ +pnpm build +``` + +Webpack 配置需要显式完成替换: + +```ts title="webpack.config.ts" +import webpack from 'webpack'; + +const federationDefines = { + FEDERATION_OPTIMIZE_NO_REMOTE: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_REMOTE === 'true', + ), + FEDERATION_OPTIMIZE_NO_SHARED: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SHARED === 'true', + ), + FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: JSON.stringify( + process.env.FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'true', + ), + FEDERATION_HAS_EXPOSES: JSON.stringify( + process.env.FEDERATION_HAS_EXPOSES !== 'false', + ), +}; + +export default { + plugins: [new webpack.DefinePlugin(federationDefines)], +}; +``` + +Rspack 使用 `rspack.DefinePlugin` 传入同一份 `federationDefines`。Vite 可以把它传给顶层 `define` 配置。 + +环境变量不能直接作为字符串留在运行时代码中,必须在构建时替换成 `true` 或 `false`,压缩工具才能删除对应代码。没有显式配置时,上述能力都会保持开启,兼容现有行为。 + +## 每个开关会移除什么 + +### disableRemote + +移除远程模块的注册、入口加载、预加载、暴露模块读取和执行能力,同时移除只服务于远程加载的 Snapshot 处理以及 Webpack 生成的远程模块装载函数。 + +适合: + +- 只向外提供模块、不会消费其他 Remote 的生产者 +- 没有 `remotes`,也不会在运行时动态注册 Remote 的独立构建 + +不要用于: + +- 配置了 `remotes` 的 Host +- 会调用 `loadRemote`、`registerRemotes` 或 `preloadRemote` 的应用 +- 依靠 Manifest 动态发现或加载 Remote 的应用 + +### disableShared + +移除共享依赖的注册、选择和加载能力,以及 Webpack 的共享消费、共享初始化、初始共享安装、共享回退和共享 Tree Shaking 插件。运行时会保留一个最小的空共享池,使完全不使用共享依赖的远程入口仍能初始化。 + +适合没有 `shared` 配置,也不会通过运行时接口注册或加载共享依赖的构建。 + +如果 React、Vue、组件库或其他依赖需要在多个应用之间复用、保持单例或进行版本选择,就必须保留该能力。 + +### disableSnapshot + +移除 Manifest / Snapshot 与相关预加载能力。它通常能继续缩小体积,但影响范围比前三个开关更广。 + +只有在使用普通 JavaScript Remote,并且不依赖类型同步、热更新、预加载、DevTools、动态发现或其他 Snapshot 能力时才建议开启。完整影响见 [Manifest / Snapshot 指南](/guide/basic/manifest-snapshot.html#disablesnapshot-的影响)。 + +## 常见组合 + +### 只提供模块的生产者 + +如果它不消费其他 Remote,可以开启: + +```ts +optimization: { + disableRemote: true, +} +``` + +是否继续开启 `disableShared` 和 `disableSnapshot`,取决于它是否使用共享依赖与 Manifest。 + +### 不使用共享依赖的 Host + +Host 仍然需要消费远程模块,只关闭共享能力: + +```ts +optimization: { + disableShared: true, +} +``` + +### 使用普通 JavaScript Remote 的轻量 Host + +如果它不使用共享依赖,也不依赖 Manifest / Snapshot: + +```ts +optimization: { + target: 'web', + disableShared: true, + disableSnapshot: true, +} +``` + +这里必须保留远程消费能力。 + +## 与 externalRuntime 的区别 + +`externalRuntime` 会把运行时代码从各个 `remoteEntry.js` 中抽离,让多个构建复用同一份外部运行时。它主要减少重复下载;`disableRemote`、`disableShared` 和 `disableSnapshot` 则会直接删除确定不用的能力。 + +两类优化可以组合:先删除不用的能力,再考虑用 `externalRuntime` 减少多个产物之间的重复代码。使用外部运行时时,必须确保页面会提前提供兼容的运行时,具体配置见 [experiments.externalRuntime](/configure/experiments.html#externalruntime)。 + +## 如何验证优化有效 + +### 1. 建立可比较的基线 + +先在相同构建模式、相同压缩设置和相同依赖版本下记录优化前的产物体积。不要把开发构建与生产构建直接比较。 + +### 2. 每次只打开一个开关 + +逐项构建并记录 `remoteEntry.js` 或实际承载运行时的文件大小。确认收益后再组合开关,这样更容易判断哪项优化有效,也更容易定位功能损失。 + +仓库中的测试样例得到以下结果。为单独比较这两个开关,三次构建都使用 Web 目标并关闭了 Snapshot。数据仅用于说明相对收益,实际数值会随配置和版本变化: + +| 配置 | 原始大小 | 减少 | +| --------------------- | -------: | --------: | +| 保留远程和共享能力 | 73,154 B | - | +| `disableRemote: true` | 52,916 B | 约 27.66% | +| `disableShared: true` | 50,008 B | 约 31.64% | + +未配置 `exposes` 时,减少的是消费者入口 `main.js`,不是生产者的 `remoteEntry.js`。下面的数据使用完全相同的入口、依赖和生产构建设置,只改变是否保留容器入口初始化: + +| 消费者 `main.js` | 压缩后大小 | Gzip 大小 | 减少 | +| ----------------------- | ---------: | --------: | ---------------------------- | +| 保留容器入口初始化 | 79,328 B | 23,897 B | - | +| 不包含 `exposes` | 78,344 B | 23,689 B | 984 B(1.24%),Gzip 208 B(0.87%) | + +### 3. 跑真实业务流程 + +至少检查以下流程: + +- 页面首次加载和刷新 +- 所有远程模块入口 +- 动态注册与预加载路径 +- 共享依赖是否保持预期的单例和版本 +- 开发环境的热更新与类型同步 +- DevTools、运行时插件和监控能力 + +如果关闭某项能力后出现明确的禁用错误,说明当前构建仍然需要它。将对应选项恢复为 `false`,重新构建即可回退。 + +## 延伸阅读 + +- [experiments 完整配置](/configure/experiments.html) +- [Manifest / Snapshot](/guide/basic/manifest-snapshot.html) +- [共享依赖 Tree Shaking](/guide/advanced/shared-tree-shaking.html) diff --git a/packages/enhanced/src/lib/container/ModuleFederationPlugin.ts b/packages/enhanced/src/lib/container/ModuleFederationPlugin.ts index 89436594f57..dc9c5a34d60 100644 --- a/packages/enhanced/src/lib/container/ModuleFederationPlugin.ts +++ b/packages/enhanced/src/lib/container/ModuleFederationPlugin.ts @@ -47,6 +47,17 @@ const validate = createSchemaValidation( }, ); +function hasExposes( + exposes: moduleFederationPlugin.ModuleFederationPluginOptions['exposes'], +): boolean { + return Boolean( + exposes && + (Array.isArray(exposes) + ? exposes.length > 0 + : Object.keys(exposes).length > 0), + ); +} + function getEnhancedPackageVersion(): string { let currentDir = __dirname; @@ -86,7 +97,7 @@ class ModuleFederationPlugin implements WebpackPluginInstance { } private _patchBundlerConfig(compiler: Compiler): void { - const { name, experiments } = this._options; + const { name, experiments, exposes } = this._options; const definePluginOptions: Record = {}; const MFPluginNum = compiler.options.plugins.filter( @@ -103,6 +114,27 @@ class ModuleFederationPlugin implements WebpackPluginInstance { const disableSnapshot = experiments?.optimization?.disableSnapshot ?? false; definePluginOptions['FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN'] = disableSnapshot; + definePluginOptions['FEDERATION_OPTIMIZE_NO_REMOTE'] = + experiments?.optimization?.disableRemote ?? false; + definePluginOptions['FEDERATION_OPTIMIZE_NO_SHARED'] = + experiments?.optimization?.disableShared ?? false; + definePluginOptions['FEDERATION_HAS_EXPOSES'] = + hasExposes(exposes) || + compiler.options.plugins.some((plugin) => { + if (!plugin || typeof plugin !== 'object') { + return false; + } + + const namedPlugin = plugin as WebpackPluginInstance & { + name?: string; + _options?: moduleFederationPlugin.ModuleFederationPluginOptions; + }; + if (namedPlugin.name !== 'ModuleFederationPlugin') { + return false; + } + + return hasExposes(namedPlugin._options?.exposes); + }); // Determine ENV_TARGET: only if manually specified in experiments.optimization.target if ( @@ -146,11 +178,7 @@ class ModuleFederationPlugin implements WebpackPluginInstance { (new RemoteEntryPlugin(options) as unknown as WebpackPluginInstance).apply( compiler, ); - const useContainerPlugin = - options.exposes && - (Array.isArray(options.exposes) - ? options.exposes.length > 0 - : Object.keys(options.exposes).length > 0); + const useContainerPlugin = hasExposes(options.exposes); if (experiments?.provideExternalRuntime) { if (useContainerPlugin) { diff --git a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts index 2d3b63fd027..bf811930a68 100644 --- a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts +++ b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.check.ts @@ -444,7 +444,7 @@ const t = { ], }, timeout: { type: 'number' }, - family: { enum: [0, 4, 6] }, + family: { enum: [4, 6] }, typesOnBuild: { type: 'boolean' }, }, }, @@ -469,6 +469,8 @@ const t = { type: 'object', properties: { disableSnapshot: { type: 'boolean' }, + disableRemote: { type: 'boolean' }, + disableShared: { type: 'boolean' }, target: { enum: ['web', 'node'] }, }, additionalProperties: !1, @@ -4361,8 +4363,6 @@ function D( const n = c; if ( - 0 !== - e && 4 !== e && 6 !== @@ -4719,6 +4719,10 @@ function D( if ( 'disableSnapshot' !== e && + 'disableRemote' !== + e && + 'disableShared' !== + e && 'target' !== e ) return ( @@ -4754,37 +4758,89 @@ function D( ); var I = e === c; } else I = !0; - if (I) + if (I) { if ( void 0 !== - r.target + r.disableRemote ) { - let e = r.target; - const n = c; + const e = c; if ( - 'web' !== e && - 'node' !== e + 'boolean' != + typeof r.disableRemote ) return ( (D.errors = [ { params: { - allowedValues: - t - .properties - .experiments - .properties - .optimization - .properties - .target - .enum, + type: 'boolean', }, }, ]), !1 ); - I = n === c; + I = e === c; } else I = !0; + if (I) { + if ( + void 0 !== + r.disableShared + ) { + const e = c; + if ( + 'boolean' != + typeof r.disableShared + ) + return ( + (D.errors = + [ + { + params: + { + type: 'boolean', + }, + }, + ]), + !1 + ); + I = e === c; + } else I = !0; + if (I) + if ( + void 0 !== + r.target + ) { + let e = + r.target; + const n = c; + if ( + 'web' !== + e && + 'node' !== e + ) + return ( + (D.errors = + [ + { + params: + { + allowedValues: + t + .properties + .experiments + .properties + .optimization + .properties + .target + .enum, + }, + }, + ]), + !1 + ); + I = n === c; + } else I = !0; + } + } } } } diff --git a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.json b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.json index 999f02b1cbf..42acc6b9ff2 100644 --- a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.json +++ b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.json @@ -889,6 +889,14 @@ "description": "Enable optimization to skip snapshot plugin", "type": "boolean" }, + "disableRemote": { + "description": "Disable remote loading code in runtime-core", + "type": "boolean" + }, + "disableShared": { + "description": "Disable shared dependency code in runtime-core", + "type": "boolean" + }, "target": { "description": "Target environment for the build", "enum": ["web", "node"] diff --git a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts index 7bf5c76f11a..0a101950abf 100644 --- a/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts +++ b/packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts @@ -936,7 +936,7 @@ export default { type: 'number', }, family: { - enum: [0, 4, 6], + enum: [4, 6], }, typesOnBuild: { type: 'boolean', @@ -989,6 +989,14 @@ export default { description: 'Enable optimization to skip snapshot plugin', type: 'boolean', }, + disableRemote: { + description: 'Disable remote loading code in runtime-core', + type: 'boolean', + }, + disableShared: { + description: 'Disable shared dependency code in runtime-core', + type: 'boolean', + }, target: { description: 'Target environment for the build', enum: ['web', 'node'], diff --git a/packages/enhanced/test/configCases/container/experiments-optimization/index.js b/packages/enhanced/test/configCases/container/experiments-optimization/index.js index 1230a4a0e47..e9679a5fa3a 100644 --- a/packages/enhanced/test/configCases/container/experiments-optimization/index.js +++ b/packages/enhanced/test/configCases/container/experiments-optimization/index.js @@ -7,11 +7,17 @@ if (!globalThis.__EXPERIMENTS_OPTIMIZATION_CASE__) { const readOutput = (filename) => fs.readFileSync(path.join(__dirname, filename), 'utf-8'); + const countOccurrences = (source, marker) => source.split(marker).length - 1; const webRemoteEntry = readOutput('remoteEntry-web.js'); const nodeRemoteEntry = readOutput('remoteEntry-node.js'); const webRemoteEntryEsm = readOutput('module/remoteEntry-web.mjs'); const nodeRemoteEntryEsm = readOutput('module/remoteEntry-node.mjs'); + const fullCapabilities = readOutput('remoteEntry-capabilities-full.js'); + const noRemote = readOutput('remoteEntry-capabilities-no-remote.js'); + const noShared = readOutput('remoteEntry-capabilities-no-shared.js'); + const fullConsumerEntry = readOutput('bundle4.js'); + const noExposesConsumerEntry = readOutput('bundle7.js'); it('should replace optimization define flags with static values', () => { expect(webRemoteEntry).not.toContain('ENV_TARGET'); @@ -33,6 +39,18 @@ if (!globalThis.__EXPERIMENTS_OPTIMIZATION_CASE__) { expect(nodeRemoteEntryEsm).not.toContain( 'FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN', ); + + [ + fullCapabilities, + noRemote, + noShared, + fullConsumerEntry, + noExposesConsumerEntry, + ].forEach((source) => { + expect(source).not.toContain('FEDERATION_OPTIMIZE_NO_REMOTE'); + expect(source).not.toContain('FEDERATION_OPTIMIZE_NO_SHARED'); + expect(source).not.toContain('FEDERATION_HAS_EXPOSES'); + }); }); it('should eliminate snapshot plugins from the web optimized CJS bundle', () => { @@ -58,4 +76,40 @@ if (!globalThis.__EXPERIMENTS_OPTIMIZATION_CASE__) { expect(nodeRemoteEntryEsm).toContain('generate-preload-assets-plugin'); expect(nodeRemoteEntryEsm).toContain('attrs:{name'); }); + + it('should eliminate the complete remote consumption path', () => { + expect(noRemote.length).toBeLessThan(fullCapabilities.length); + expect(fullCapabilities).toContain('availableExposes'); + expect(fullCapabilities).toContain('mf_module_id'); + expect(fullCapabilities).toContain('Container missing'); + expect(noRemote).not.toContain('availableExposes'); + expect(noRemote).not.toContain('mf_module_id'); + expect(noRemote).not.toContain('Container missing'); + }); + + it('should eliminate the complete shared consumption path', () => { + const sharedRuntimeMarkers = [ + 'Initialization of sharing external failed', + 'Shared module is not available for eager consumption', + 'No fallback item found for shareKey', + 'tree-shake-plugin', + ]; + + expect(noShared.length).toBeLessThan(fullCapabilities.length); + sharedRuntimeMarkers.forEach((marker) => { + expect(fullCapabilities).toContain(marker); + expect(noShared).not.toContain(marker); + }); + }); + + it('should eliminate container initialization from the consumer entry without exposes', () => { + expect(noExposesConsumerEntry.length).toBeLessThan( + fullConsumerEntry.length, + ); + expect( + countOccurrences(noExposesConsumerEntry, 'remoteEntryInitOptions'), + ).toBeLessThan( + countOccurrences(fullConsumerEntry, 'remoteEntryInitOptions'), + ); + }); } diff --git a/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js b/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js index a5124bc7d80..8797b6fc9ac 100644 --- a/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js +++ b/packages/enhanced/test/configCases/container/experiments-optimization/webpack.config.js @@ -25,6 +25,9 @@ const createConfig = ({ outputModule, optimizationTarget, disableSnapshot, + disableRemote, + disableShared, + exposes = commonConfig.exposes, uniqueName, containerName, filename, @@ -55,12 +58,14 @@ const createConfig = ({ type: 'commonjs-module', name: containerName, }, - exposes: commonConfig.exposes, + exposes, remotes: commonConfig.remotes, experiments: { optimization: { target: optimizationTarget, disableSnapshot, + disableRemote, + disableShared, }, }, }), @@ -104,4 +109,42 @@ module.exports = [ containerName: 'experiments_optimization_node_esm', filename: 'module/remoteEntry-node.mjs', }), + createConfig({ + entry: './noop.js', + outputModule: false, + optimizationTarget: 'web', + disableSnapshot: true, + uniqueName: 'experiments-optimization-capabilities-full', + containerName: 'capabilities_full', + filename: 'remoteEntry-capabilities-full.js', + }), + createConfig({ + entry: './noop.js', + outputModule: false, + optimizationTarget: 'web', + disableSnapshot: true, + disableRemote: true, + uniqueName: 'experiments-optimization-capabilities-no-remote', + containerName: 'capabilities_no_remote', + filename: 'remoteEntry-capabilities-no-remote.js', + }), + createConfig({ + entry: './noop.js', + outputModule: false, + optimizationTarget: 'web', + disableSnapshot: true, + disableShared: true, + uniqueName: 'experiments-optimization-capabilities-no-shared', + containerName: 'capabilities_no_shared', + filename: 'remoteEntry-capabilities-no-shared.js', + }), + createConfig({ + entry: './noop.js', + outputModule: false, + optimizationTarget: 'web', + disableSnapshot: true, + exposes: {}, + uniqueName: 'experiments-optimization-capabilities-full', + containerName: 'capabilities_full', + }), ]; diff --git a/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts b/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts index f8e9cfa355e..ff101840e3e 100644 --- a/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts +++ b/packages/rspack/__tests__/ModuleFederationPlugin.spec.ts @@ -1,8 +1,39 @@ import { + ModuleFederationPlugin, resolveRspackRuntimeAlias, resolveRspackRuntimeImplementation, } from '../src/ModuleFederationPlugin'; +function getOptimizationDefines( + optimization?: NonNullable< + NonNullable< + ConstructorParameters[0]['experiments'] + >['optimization'] + >, + exposes?: ConstructorParameters[0]['exposes'], +) { + let definitions: Record = {}; + class DefinePlugin { + constructor(options: Record) { + definitions = options; + } + + apply() {} + } + + const plugin = new ModuleFederationPlugin({ + name: 'test', + exposes, + experiments: { optimization }, + }); + + (plugin as any)._patchBundlerConfig({ + webpack: { DefinePlugin }, + }); + + return definitions; +} + describe('runtime resolution compatibility', () => { it('prefers the bundler implementation when available', () => { const resolve = jest.fn((request: string) => { @@ -67,3 +98,38 @@ describe('runtime resolution compatibility', () => { ); }); }); + +describe('runtime capability optimization defines', () => { + it('keeps all runtime capabilities enabled by default', () => { + expect(getOptimizationDefines()).toMatchObject({ + FEDERATION_OPTIMIZE_NO_REMOTE: false, + FEDERATION_OPTIMIZE_NO_SHARED: false, + FEDERATION_HAS_EXPOSES: false, + }); + }); + + it('derives expose capability from the container configuration', () => { + expect(getOptimizationDefines(undefined, {})).toMatchObject({ + FEDERATION_HAS_EXPOSES: false, + }); + expect( + getOptimizationDefines(undefined, { + './Button': './src/Button', + }), + ).toMatchObject({ + FEDERATION_HAS_EXPOSES: true, + }); + }); + + it('defines each disabled runtime capability independently', () => { + expect( + getOptimizationDefines({ + disableRemote: true, + disableShared: true, + }), + ).toMatchObject({ + FEDERATION_OPTIMIZE_NO_REMOTE: true, + FEDERATION_OPTIMIZE_NO_SHARED: true, + }); + }); +}); diff --git a/packages/rspack/src/ModuleFederationPlugin.ts b/packages/rspack/src/ModuleFederationPlugin.ts index f19e036b5f7..4fe78266666 100644 --- a/packages/rspack/src/ModuleFederationPlugin.ts +++ b/packages/rspack/src/ModuleFederationPlugin.ts @@ -37,6 +37,17 @@ type RuntimeEntrySpec = { cjs: string; }; +function hasExposes( + exposes: moduleFederationPlugin.ModuleFederationPluginOptions['exposes'], +): boolean { + return Boolean( + exposes && + (Array.isArray(exposes) + ? exposes.length > 0 + : Object.keys(exposes).length > 0), + ); +} + function resolveRuntimeEntry( spec: RuntimeEntrySpec, implementation: string | undefined, @@ -99,7 +110,7 @@ export class ModuleFederationPlugin implements RspackPluginInstance { } private _patchBundlerConfig(compiler: Compiler): void { - const { name, experiments } = this._options; + const { name, experiments, exposes } = this._options; const definePluginOptions: Record = {}; if (name) { definePluginOptions['FEDERATION_BUILD_IDENTIFIER'] = JSON.stringify( @@ -110,6 +121,11 @@ export class ModuleFederationPlugin implements RspackPluginInstance { const disableSnapshot = experiments?.optimization?.disableSnapshot ?? false; definePluginOptions['FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN'] = disableSnapshot; + definePluginOptions['FEDERATION_OPTIMIZE_NO_REMOTE'] = + experiments?.optimization?.disableRemote ?? false; + definePluginOptions['FEDERATION_OPTIMIZE_NO_SHARED'] = + experiments?.optimization?.disableShared ?? false; + definePluginOptions['FEDERATION_HAS_EXPOSES'] = hasExposes(exposes); // Determine ENV_TARGET: only if manually specified in experiments.optimization.target if ( diff --git a/packages/runtime-core/src/core.ts b/packages/runtime-core/src/core.ts index df09129a9a0..7887eec0832 100644 --- a/packages/runtime-core/src/core.ts +++ b/packages/runtime-core/src/core.ts @@ -26,7 +26,7 @@ import { RUNTIME_010, runtimeDescMap, } from '@module-federation/error-codes'; -import { Module, type RemoteModuleFactory } from './module'; +import type { Module, RemoteModuleFactory } from './module'; import { AsyncHook, AsyncWaterfallHook, @@ -36,21 +36,33 @@ import { } from './utils/hooks'; import { generatePreloadAssetsPlugin } from './plugins/generate-preload-assets'; import { snapshotPlugin } from './plugins/snapshot'; -import { getRemoteInfo } from './utils/load'; import { DEFAULT_SCOPE } from './constant'; import { SnapshotHandler } from './plugins/snapshot/SnapshotHandler'; +import { DisabledSnapshotHandler } from './plugins/snapshot/disabled'; import { SharedHandler } from './shared'; +import { DisabledSharedHandler } from './shared/disabled'; import { RemoteHandler } from './remote'; +import { DisabledRemoteHandler } from './remote/disabled'; import { formatShareConfigs } from './utils/share'; // Declare the global constant that will be defined by DefinePlugin // Default to true if not defined (e.g., when runtime-core is used outside of webpack) // so that snapshot functionality is included by default. declare const FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN: boolean; +declare const FEDERATION_OPTIMIZE_NO_REMOTE: boolean; +declare const FEDERATION_OPTIMIZE_NO_SHARED: boolean; const USE_SNAPSHOT = typeof FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN === 'boolean' ? !FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN : true; // Default to true (use snapshot) when not explicitly defined +const USE_REMOTE = + typeof FEDERATION_OPTIMIZE_NO_REMOTE === 'boolean' + ? !FEDERATION_OPTIMIZE_NO_REMOTE + : true; +const USE_SHARED = + typeof FEDERATION_OPTIMIZE_NO_SHARED === 'boolean' + ? !FEDERATION_OPTIMIZE_NO_SHARED + : true; export class ModuleFederation { options: Options; @@ -284,9 +296,10 @@ export class ModuleFederation { moduleInfo?: GlobalModuleInfo[string]; constructor(userOptions: UserOptions) { - const plugins = USE_SNAPSHOT - ? [snapshotPlugin(), generatePreloadAssetsPlugin()] - : []; + const plugins = + USE_REMOTE && USE_SNAPSHOT + ? [snapshotPlugin(), generatePreloadAssetsPlugin()] + : []; // TODO: Validate the details of the options // Initialize options with default values const defaultOptions: Options = { @@ -300,9 +313,15 @@ export class ModuleFederation { this.name = userOptions.name; this.options = defaultOptions; - this.snapshotHandler = new SnapshotHandler(this); - this.sharedHandler = new SharedHandler(this); - this.remoteHandler = new RemoteHandler(this); + this.snapshotHandler = ( + USE_REMOTE ? new SnapshotHandler(this) : new DisabledSnapshotHandler() + ) as SnapshotHandler; + this.sharedHandler = ( + USE_SHARED ? new SharedHandler(this) : new DisabledSharedHandler() + ) as SharedHandler; + this.remoteHandler = ( + USE_REMOTE ? new RemoteHandler(this) : new DisabledRemoteHandler() + ) as RemoteHandler; this.shareScopeMap = this.sharedHandler.shareScopeMap; this.registerPlugins([ ...defaultOptions.plugins, @@ -364,13 +383,7 @@ export class ModuleFederation { url: string, container: RemoteEntryExports, ): Module { - const remoteInfo = getRemoteInfo({ name, entry: url }); - const module = new Module({ host: this, remoteInfo }); - - module.remoteEntryExports = container; - this.moduleCache.set(name, module); - - return module; + return this.remoteHandler.initRawContainer(name, url, container); } // eslint-disable-next-line max-lines-per-function @@ -396,10 +409,9 @@ export class ModuleFederation { } formatOptions(globalOptions: Options, userOptions: UserOptions): Options { - const { allShareInfos: shared } = formatShareConfigs( - globalOptions, - userOptions, - ); + const shared = USE_SHARED + ? formatShareConfigs(globalOptions, userOptions).allShareInfos + : {}; const { userOptions: userOptionsRes, options: globalOptionsRes } = this.hooks.lifecycle.beforeInit.emit({ origin: this, diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 5efa2c6fb47..e561a0abd55 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -1,6 +1,16 @@ import helpersDefault, { type IGlobalUtils, type IShareUtils } from './helpers'; +import { Module as RemoteModule } from './module'; +import { UnavailableRemoteModule } from './remote/disabled'; + +declare const FEDERATION_OPTIMIZE_NO_REMOTE: boolean; const helpers = helpersDefault; +const Module = ( + typeof FEDERATION_OPTIMIZE_NO_REMOTE === 'boolean' && + FEDERATION_OPTIMIZE_NO_REMOTE + ? UnavailableRemoteModule + : RemoteModule +) as typeof RemoteModule; export { ModuleFederation } from './core'; export { @@ -27,7 +37,7 @@ export { } from './utils'; export { getRegisteredShare } from '../src/utils/share'; export { loadScript, loadScriptNode } from '@module-federation/sdk'; -export { Module } from './module'; +export { Module }; export * as types from './type'; export { helpers }; export { satisfy } from '../src/utils/semver'; diff --git a/packages/runtime-core/src/plugins/snapshot/disabled.ts b/packages/runtime-core/src/plugins/snapshot/disabled.ts new file mode 100644 index 00000000000..87c2748fd25 --- /dev/null +++ b/packages/runtime-core/src/plugins/snapshot/disabled.ts @@ -0,0 +1,5 @@ +import { PluginSystem } from '../../utils/hooks'; + +export class DisabledSnapshotHandler { + hooks = new PluginSystem({}); +} diff --git a/packages/runtime-core/src/remote/disabled.ts b/packages/runtime-core/src/remote/disabled.ts new file mode 100644 index 00000000000..73d19b776d8 --- /dev/null +++ b/packages/runtime-core/src/remote/disabled.ts @@ -0,0 +1,38 @@ +import { PluginSystem } from '../utils/hooks'; + +const REMOTE_DISABLED_MESSAGE = + 'Remote loading is disabled by experiments.optimization.disableRemote.'; + +export class UnavailableRemoteModule { + constructor() { + throw new Error(REMOTE_DISABLED_MESSAGE); + } +} + +export class DisabledRemoteHandler { + hooks = new PluginSystem({}); + + formatAndRegisterRemote() { + return []; + } + + loadRemote(): never { + throw new Error(REMOTE_DISABLED_MESSAGE); + } + + preloadRemote(): never { + throw new Error(REMOTE_DISABLED_MESSAGE); + } + + registerRemotes(): never { + throw new Error(REMOTE_DISABLED_MESSAGE); + } + + getRemoteModuleAndOptions(): never { + throw new Error(REMOTE_DISABLED_MESSAGE); + } + + initRawContainer(): never { + throw new Error(REMOTE_DISABLED_MESSAGE); + } +} diff --git a/packages/runtime-core/src/remote/index.ts b/packages/runtime-core/src/remote/index.ts index 1704e41d5f7..3ce06056593 100644 --- a/packages/runtime-core/src/remote/index.ts +++ b/packages/runtime-core/src/remote/index.ts @@ -509,6 +509,21 @@ export class RemoteHandler { }); } + initRawContainer( + name: string, + url: string, + container: RemoteEntryExports, + ): Module { + const { host } = this; + const remoteInfo = getRemoteInfo({ name, entry: url }); + const module = new Module({ host, remoteInfo }); + + module.remoteEntryExports = container; + host.moduleCache.set(name, module); + + return module; + } + async getRemoteModuleAndOptions(options: { id: string }): Promise<{ module: Module; moduleOptions: ModuleOptions; diff --git a/packages/runtime-core/src/shared/disabled.ts b/packages/runtime-core/src/shared/disabled.ts new file mode 100644 index 00000000000..fb775abd056 --- /dev/null +++ b/packages/runtime-core/src/shared/disabled.ts @@ -0,0 +1,40 @@ +import type { LoadRemoteMatch } from '../remote'; +import type { ShareScopeMap } from '../type'; +import { AsyncWaterfallHook, PluginSystem } from '../utils/hooks'; + +export class DisabledSharedHandler { + shareScopeMap: ShareScopeMap = {}; + hooks = new PluginSystem({ + afterResolve: new AsyncWaterfallHook('afterResolve'), + }); + + registerShared() { + return { + newShareInfos: {}, + allShareInfos: {}, + }; + } + + loadShare(): never { + throw new Error( + 'Shared dependency loading is disabled by experiments.optimization.disableShared.', + ); + } + + loadShareSync(): never { + throw new Error( + 'Shared dependency loading is disabled by experiments.optimization.disableShared.', + ); + } + + initializeSharing(): [] { + return []; + } + + initShareScopeMap( + scopeName: string, + shareScope: ShareScopeMap[string], + ): void { + this.shareScopeMap[scopeName] = shareScope; + } +} diff --git a/packages/runtime-core/src/shared/index.ts b/packages/runtime-core/src/shared/index.ts index 07ca4d05942..81a01847e41 100644 --- a/packages/runtime-core/src/shared/index.ts +++ b/packages/runtime-core/src/shared/index.ts @@ -42,7 +42,7 @@ import { warn, } from '../utils'; import { DEFAULT_SCOPE } from '../constant'; -import { LoadRemoteMatch } from '../remote'; +import type { LoadRemoteMatch } from '../remote'; import { createRemoteEntryInitOptions } from '../module'; export class SharedHandler { diff --git a/packages/runtime-core/src/type/plugin.ts b/packages/runtime-core/src/type/plugin.ts index c25a74ae30f..743ab29a782 100644 --- a/packages/runtime-core/src/type/plugin.ts +++ b/packages/runtime-core/src/type/plugin.ts @@ -1,8 +1,8 @@ -import { ModuleFederation } from '../core'; -import { Module } from '../module'; -import { SnapshotHandler } from '../plugins/snapshot/SnapshotHandler'; -import { SharedHandler } from '../shared'; -import { RemoteHandler } from '../remote'; +import type { ModuleFederation } from '../core'; +import type { Module } from '../module'; +import type { SnapshotHandler } from '../plugins/snapshot/SnapshotHandler'; +import type { SharedHandler } from '../shared'; +import type { RemoteHandler } from '../remote'; type CoreLifeCycle = ModuleFederation['hooks']['lifecycle']; type CoreLifeCyclePartial = Partial<{ diff --git a/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts b/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts index ffe50596921..c129a8db928 100644 --- a/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts +++ b/packages/sdk/src/types/plugins/ModuleFederationPlugin.ts @@ -495,6 +495,14 @@ export interface ModuleFederationPluginOptions { * Enable optimization to skip snapshot plugin */ disableSnapshot?: boolean; + /** + * Disable remote loading code in runtime-core. + */ + disableRemote?: boolean; + /** + * Disable shared dependency code in runtime-core. + */ + disableShared?: boolean; /** * Target environment for the build */ diff --git a/packages/webpack-bundler-runtime/src/index.ts b/packages/webpack-bundler-runtime/src/index.ts index dc9b130f0eb..ff7bf9130dc 100644 --- a/packages/webpack-bundler-runtime/src/index.ts +++ b/packages/webpack-bundler-runtime/src/index.ts @@ -9,22 +9,39 @@ import { initContainerEntry } from './initContainerEntry'; import { init } from './init'; import { getSharedFallbackGetter } from './getSharedFallbackGetter'; +declare const FEDERATION_OPTIMIZE_NO_REMOTE: boolean; +declare const FEDERATION_OPTIMIZE_NO_SHARED: boolean; +declare const FEDERATION_HAS_EXPOSES: boolean; + export * from './types'; +const USE_REMOTE = + typeof FEDERATION_OPTIMIZE_NO_REMOTE === 'boolean' + ? !FEDERATION_OPTIMIZE_NO_REMOTE + : true; +const USE_SHARED = + typeof FEDERATION_OPTIMIZE_NO_SHARED === 'boolean' + ? !FEDERATION_OPTIMIZE_NO_SHARED + : true; +const USE_EXPOSES = + typeof FEDERATION_HAS_EXPOSES === 'boolean' ? FEDERATION_HAS_EXPOSES : true; + +const bundlerRuntime = { + remotes: USE_REMOTE ? remotes : undefined, + consumes: USE_SHARED ? consumes : undefined, + I: USE_SHARED ? initializeSharing : undefined, + S: {}, + installInitialConsumes: USE_SHARED ? installInitialConsumes : undefined, + initContainerEntry: USE_EXPOSES ? initContainerEntry : undefined, + init, + getSharedFallbackGetter: USE_SHARED ? getSharedFallbackGetter : undefined, +} as NonNullable; + const federation: Federation = { runtime, instance: undefined, initOptions: undefined, - bundlerRuntime: { - remotes, - consumes, - I: initializeSharing, - S: {}, - installInitialConsumes, - initContainerEntry, - init, - getSharedFallbackGetter, - }, + bundlerRuntime, attachShareScopeMap, bundlerRuntimeOptions: {}, }; @@ -33,7 +50,7 @@ const federation: Federation = { export { runtime, attachShareScopeMap }; export const instance = federation.instance; export const initOptions = federation.initOptions; -export const bundlerRuntime = federation.bundlerRuntime; +export { bundlerRuntime }; export const bundlerRuntimeOptions = federation.bundlerRuntimeOptions; export default federation; diff --git a/packages/webpack-bundler-runtime/src/init.ts b/packages/webpack-bundler-runtime/src/init.ts index fc2e8260a5a..d8a7e9e2d7c 100644 --- a/packages/webpack-bundler-runtime/src/init.ts +++ b/packages/webpack-bundler-runtime/src/init.ts @@ -6,6 +6,13 @@ import { import { ShareArgs } from '@module-federation/runtime/types'; import helpers from '@module-federation/runtime/helpers'; +declare const FEDERATION_OPTIMIZE_NO_SHARED: boolean; + +const USE_SHARED = + typeof FEDERATION_OPTIMIZE_NO_SHARED === 'boolean' + ? !FEDERATION_OPTIMIZE_NO_SHARED + : true; + export function init({ webpackRequire }: { webpackRequire: WebpackRequire }) { const { initOptions, runtime, sharedFallback, bundlerRuntime, libraryType } = webpackRequire.federation; @@ -14,117 +21,119 @@ export function init({ webpackRequire }: { webpackRequire: WebpackRequire }) { throw new Error('initOptions is required!'); } - const treeShakingSharePlugin: () => ModuleFederationRuntimePlugin = - function () { - return { - name: 'tree-shake-plugin', - beforeInit(args) { - const { userOptions, origin, options: registeredOptions } = args; - const version = userOptions.version || registeredOptions.version; - if (!sharedFallback) { - return args; - } + if (USE_SHARED) { + const treeShakingSharePlugin: () => ModuleFederationRuntimePlugin = + function () { + return { + name: 'tree-shake-plugin', + beforeInit(args) { + const { userOptions, origin, options: registeredOptions } = args; + const version = userOptions.version || registeredOptions.version; + if (!sharedFallback) { + return args; + } - const currentShared = userOptions.shared || {}; - const shared: Array<[pkgName: string, ShareArgs]> = []; + const currentShared = userOptions.shared || {}; + const shared: Array<[pkgName: string, ShareArgs]> = []; - Object.keys(currentShared).forEach((sharedName) => { - const sharedArgs = Array.isArray(currentShared[sharedName]) - ? currentShared[sharedName] - : [currentShared[sharedName]]; - sharedArgs.forEach((sharedArg) => { - shared.push([sharedName, sharedArg]); - if ('get' in sharedArg) { - sharedArg.treeShaking ||= {}; - sharedArg.treeShaking.get = sharedArg.get; - sharedArg.get = bundlerRuntime!.getSharedFallbackGetter({ - shareKey: sharedName, - factory: sharedArg.get, - webpackRequire, - libraryType, - version: sharedArg.version, - }); - } + Object.keys(currentShared).forEach((sharedName) => { + const sharedArgs = Array.isArray(currentShared[sharedName]) + ? currentShared[sharedName] + : [currentShared[sharedName]]; + sharedArgs.forEach((sharedArg) => { + shared.push([sharedName, sharedArg]); + if ('get' in sharedArg) { + sharedArg.treeShaking ||= {}; + sharedArg.treeShaking.get = sharedArg.get; + sharedArg.get = bundlerRuntime!.getSharedFallbackGetter({ + shareKey: sharedName, + factory: sharedArg.get, + webpackRequire, + libraryType, + version: sharedArg.version, + }); + } + }); }); - }); - // read snapshot to override re-shake getter - const hostGlobalSnapshot = - helpers.global.getGlobalSnapshotInfoByModuleInfo({ - name: origin.name, - version: version, - }); - if (!hostGlobalSnapshot || !('shared' in hostGlobalSnapshot)) { - return args; - } + // read snapshot to override re-shake getter + const hostGlobalSnapshot = + helpers.global.getGlobalSnapshotInfoByModuleInfo({ + name: origin.name, + version: version, + }); + if (!hostGlobalSnapshot || !('shared' in hostGlobalSnapshot)) { + return args; + } - Object.keys(registeredOptions.shared || {}).forEach((pkgName) => { - const sharedInfo = registeredOptions.shared[pkgName]; - sharedInfo.forEach((sharedArg) => { - shared.push([pkgName, sharedArg]); + Object.keys(registeredOptions.shared || {}).forEach((pkgName) => { + const sharedInfo = registeredOptions.shared[pkgName]; + sharedInfo.forEach((sharedArg) => { + shared.push([pkgName, sharedArg]); + }); }); - }); - const patchShared = (pkgName: string, shared: ShareArgs) => { - const shareSnapshot = hostGlobalSnapshot.shared.find( - (item) => item.sharedName === pkgName, - ); - if (!shareSnapshot) { - return; - } - const { treeShaking } = shared; - if (!treeShaking) { - return; - } - const { - secondarySharedTreeShakingName, - secondarySharedTreeShakingEntry, - treeShakingStatus, - } = shareSnapshot; - if (treeShaking.status === treeShakingStatus) { - return; - } - treeShaking.status = treeShakingStatus; - if ( - secondarySharedTreeShakingEntry && - libraryType && - secondarySharedTreeShakingName - ) { - treeShaking.get = async () => { - const shareEntry = await getRemoteEntry({ - origin, - remoteInfo: { - name: secondarySharedTreeShakingName, - entry: secondarySharedTreeShakingEntry, - type: libraryType, - entryGlobalName: secondarySharedTreeShakingName, - // current not used - shareScope: 'default', - }, - }); - // TODO: add errorLoad hook ? - // @ts-ignore - await shareEntry.init( - origin, + const patchShared = (pkgName: string, shared: ShareArgs) => { + const shareSnapshot = hostGlobalSnapshot.shared.find( + (item) => item.sharedName === pkgName, + ); + if (!shareSnapshot) { + return; + } + const { treeShaking } = shared; + if (!treeShaking) { + return; + } + const { + secondarySharedTreeShakingName, + secondarySharedTreeShakingEntry, + treeShakingStatus, + } = shareSnapshot; + if (treeShaking.status === treeShakingStatus) { + return; + } + treeShaking.status = treeShakingStatus; + if ( + secondarySharedTreeShakingEntry && + libraryType && + secondarySharedTreeShakingName + ) { + treeShaking.get = async () => { + const shareEntry = await getRemoteEntry({ + origin, + remoteInfo: { + name: secondarySharedTreeShakingName, + entry: secondarySharedTreeShakingEntry, + type: libraryType, + entryGlobalName: secondarySharedTreeShakingName, + // current not used + shareScope: 'default', + }, + }); + // TODO: add errorLoad hook ? // @ts-ignore - __webpack_require__.federation.bundlerRuntime, - ); - // @ts-ignore - const getter = shareEntry.get(); - return getter; - }; - } - }; - shared.forEach(([pkgName, sharedArg]) => { - patchShared(pkgName, sharedArg); - }); + await shareEntry.init( + origin, + // @ts-ignore + __webpack_require__.federation.bundlerRuntime, + ); + // @ts-ignore + const getter = shareEntry.get(); + return getter; + }; + } + }; + shared.forEach(([pkgName, sharedArg]) => { + patchShared(pkgName, sharedArg); + }); - return args; - }, + return args; + }, + }; }; - }; - initOptions.plugins ||= []; - initOptions.plugins.push(treeShakingSharePlugin()); + initOptions.plugins ||= []; + initOptions.plugins.push(treeShakingSharePlugin()); + } return runtime!.init(initOptions); } From f9f661a6d6c401aab287de1570196138999b60eb Mon Sep 17 00:00:00 2001 From: Hanric Date: Wed, 15 Jul 2026 17:59:03 +0800 Subject: [PATCH 26/37] Release v2.8.0 (#4905) --- .changeset/bump-rock-metro-examples.md | 5 ---- .changeset/calm-windows-metro-paths.md | 5 ---- .changeset/clean-dodos-federate.md | 6 ----- .../fix-rsbuild-plugin-ssr-library-type.md | 5 ---- .changeset/metro-typescript-7.md | 5 ---- .changeset/quiet-runtime-capabilities.md | 9 ------- .changeset/short-eyes-punch.md | 6 ----- .changeset/slim-cache-path-dependencies.md | 12 ---------- .changeset/soft-rings-serve.md | 10 -------- .changeset/tidy-cats-optimize.md | 7 ------ .changeset/tidy-rspack-identifiers.md | 6 ----- .github/workflows/build-and-test.yml | 3 +++ .../CHANGELOG.md | 6 +++++ .../package.json | 2 +- apps/node-dynamic-remote/CHANGELOG.md | 6 +++++ apps/node-dynamic-remote/package.json | 2 +- .../router-remote5-2005/CHANGELOG.md | 9 +++++++ .../router-remote5-2005/package.json | 2 +- .../router-remote6-2006/CHANGELOG.md | 9 +++++++ .../router-remote6-2006/package.json | 2 +- .../no-server/host/CHANGELOG.md | 9 +++++++ .../no-server/host/package.json | 2 +- .../no-server/provider/CHANGELOG.md | 9 +++++++ .../no-server/provider/package.json | 2 +- .../with-server/host/CHANGELOG.md | 10 ++++++++ .../with-server/host/package.json | 2 +- .../with-server/provider/CHANGELOG.md | 10 ++++++++ .../with-server/provider/package.json | 2 +- apps/website-new/CHANGELOG.md | 8 +++++++ apps/website-new/package.json | 2 +- .../bridge-react-webpack-plugin/CHANGELOG.md | 8 +++++++ .../bridge-react-webpack-plugin/package.json | 2 +- packages/bridge/bridge-react/CHANGELOG.md | 8 +++++++ packages/bridge/bridge-react/package.json | 2 +- packages/bridge/bridge-shared/CHANGELOG.md | 2 ++ packages/bridge/bridge-shared/package.json | 2 +- packages/bridge/vue3-bridge/CHANGELOG.md | 9 +++++++ packages/bridge/vue3-bridge/package.json | 2 +- packages/chrome-devtools/CHANGELOG.md | 8 +++++++ packages/chrome-devtools/package.json | 2 +- packages/cli/CHANGELOG.md | 10 ++++++++ packages/cli/package.json | 2 +- .../create-module-federation/CHANGELOG.md | 2 ++ .../create-module-federation/package.json | 2 +- packages/dts-plugin/CHANGELOG.md | 16 +++++++++++++ packages/dts-plugin/package.json | 2 +- packages/enhanced/CHANGELOG.md | 24 +++++++++++++++++++ packages/enhanced/package.json | 2 +- packages/error-codes/CHANGELOG.md | 2 ++ packages/error-codes/package.json | 2 +- packages/esbuild/CHANGELOG.md | 9 +++++++ packages/esbuild/package.json | 2 +- packages/managers/CHANGELOG.md | 8 +++++++ packages/managers/package.json | 2 +- packages/manifest/CHANGELOG.md | 14 +++++++++++ packages/manifest/package.json | 2 +- packages/metro-core/CHANGELOG.md | 14 +++++++++++ packages/metro-core/package.json | 2 +- packages/metro-plugin-rnc-cli/CHANGELOG.md | 9 +++++++ packages/metro-plugin-rnc-cli/package.json | 2 +- packages/metro-plugin-rnef/CHANGELOG.md | 9 +++++++ packages/metro-plugin-rnef/package.json | 2 +- packages/metro-plugin-rock/CHANGELOG.md | 9 +++++++ packages/metro-plugin-rock/package.json | 2 +- packages/modernjs-v3/CHANGELOG.md | 21 ++++++++++++++++ packages/modernjs-v3/package.json | 2 +- packages/modernjs/CHANGELOG.md | 21 ++++++++++++++++ packages/modernjs/package.json | 2 +- packages/nextjs-mf/CHANGELOG.md | 14 +++++++++++ packages/nextjs-mf/package.json | 2 +- packages/node/CHANGELOG.md | 11 +++++++++ packages/node/package.json | 2 +- packages/observability-plugin/CHANGELOG.md | 7 ++++++ packages/observability-plugin/package.json | 2 +- packages/playground/CHANGELOG.md | 9 +++++++ packages/playground/package.json | 2 +- packages/retry-plugin/CHANGELOG.md | 8 +++++++ packages/retry-plugin/package.json | 2 +- packages/rsbuild-plugin/CHANGELOG.md | 12 ++++++++++ packages/rsbuild-plugin/package.json | 2 +- packages/rspack/CHANGELOG.md | 19 +++++++++++++++ packages/rspack/package.json | 2 +- packages/rspress-plugin/CHANGELOG.md | 13 ++++++++++ packages/rspress-plugin/package.json | 2 +- packages/runtime-core/CHANGELOG.md | 9 +++++++ packages/runtime-core/package.json | 2 +- .../CHANGELOG.md | 6 +++++ .../package.json | 2 +- packages/runtime-tools/CHANGELOG.md | 8 +++++++ packages/runtime-tools/package.json | 2 +- packages/runtime/CHANGELOG.md | 9 +++++++ packages/runtime/package.json | 2 +- packages/sdk/CHANGELOG.md | 6 +++++ packages/sdk/package.json | 2 +- packages/storybook-addon/CHANGELOG.md | 10 ++++++++ packages/storybook-addon/package.json | 4 ++-- .../third-party-dts-extractor/CHANGELOG.md | 6 +++++ .../third-party-dts-extractor/package.json | 2 +- packages/treeshake-frontend/CHANGELOG.md | 2 ++ packages/treeshake-frontend/package.json | 2 +- packages/treeshake-server/CHANGELOG.md | 2 ++ packages/treeshake-server/package.json | 2 +- packages/utilities/CHANGELOG.md | 8 +++++++ packages/utilities/package.json | 2 +- packages/webpack-bundler-runtime/CHANGELOG.md | 10 ++++++++ packages/webpack-bundler-runtime/package.json | 2 +- 106 files changed, 499 insertions(+), 124 deletions(-) delete mode 100644 .changeset/bump-rock-metro-examples.md delete mode 100644 .changeset/calm-windows-metro-paths.md delete mode 100644 .changeset/clean-dodos-federate.md delete mode 100644 .changeset/fix-rsbuild-plugin-ssr-library-type.md delete mode 100644 .changeset/metro-typescript-7.md delete mode 100644 .changeset/quiet-runtime-capabilities.md delete mode 100644 .changeset/short-eyes-punch.md delete mode 100644 .changeset/slim-cache-path-dependencies.md delete mode 100644 .changeset/soft-rings-serve.md delete mode 100644 .changeset/tidy-cats-optimize.md delete mode 100644 .changeset/tidy-rspack-identifiers.md diff --git a/.changeset/bump-rock-metro-examples.md b/.changeset/bump-rock-metro-examples.md deleted file mode 100644 index 54bd2ecb72b..00000000000 --- a/.changeset/bump-rock-metro-examples.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@module-federation/metro": patch ---- - -chore: bump Rock dependencies to 0.14.1 diff --git a/.changeset/calm-windows-metro-paths.md b/.changeset/calm-windows-metro-paths.md deleted file mode 100644 index d233e6055e3..00000000000 --- a/.changeset/calm-windows-metro-paths.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@module-federation/metro": patch ---- - -fix: normalize Metro paths on Windows diff --git a/.changeset/clean-dodos-federate.md b/.changeset/clean-dodos-federate.md deleted file mode 100644 index 13cc2b348d6..00000000000 --- a/.changeset/clean-dodos-federate.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@module-federation/manifest': patch ---- - -Preserve the configured Module Federation library type when reconciling -Rspack-pre-emitted stats and manifests, including ESM `module` remote entries. diff --git a/.changeset/fix-rsbuild-plugin-ssr-library-type.md b/.changeset/fix-rsbuild-plugin-ssr-library-type.md deleted file mode 100644 index 5887d4e5183..00000000000 --- a/.changeset/fix-rsbuild-plugin-ssr-library-type.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@module-federation/rsbuild-plugin': patch ---- - -fix(rsbuild-plugin): force `output.library.type` to `commonjs-module` in `patchNodeConfig` so the `mf-ssr` bundle stops emitting module-scope `export {}` and passes rspack 2.1.x minification. diff --git a/.changeset/metro-typescript-7.md b/.changeset/metro-typescript-7.md deleted file mode 100644 index 31e7b3a9d52..00000000000 --- a/.changeset/metro-typescript-7.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@module-federation/metro": patch ---- - -Support TypeScript 7 in Metro projects. diff --git a/.changeset/quiet-runtime-capabilities.md b/.changeset/quiet-runtime-capabilities.md deleted file mode 100644 index d981c50ffbf..00000000000 --- a/.changeset/quiet-runtime-capabilities.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@module-federation/enhanced': patch -'@module-federation/rspack': patch -'@module-federation/runtime-core': patch -'@module-federation/sdk': patch -'@module-federation/webpack-bundler-runtime': patch ---- - -Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. diff --git a/.changeset/short-eyes-punch.md b/.changeset/short-eyes-punch.md deleted file mode 100644 index 4fd85220bf8..00000000000 --- a/.changeset/short-eyes-punch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@module-federation/modern-js-v3': patch -'@module-federation/modern-js': patch ---- - -fix(modernjs-v3): set optimization.usedExports to "global" to prevent tree shaking issues in micro frontend mode diff --git a/.changeset/slim-cache-path-dependencies.md b/.changeset/slim-cache-path-dependencies.md deleted file mode 100644 index 436595efe6f..00000000000 --- a/.changeset/slim-cache-path-dependencies.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@module-federation/bridge-react': patch -'@module-federation/modern-js': patch -'@module-federation/modern-js-v3': patch -'@module-federation/enhanced': patch -'@module-federation/bridge-react-webpack-plugin': patch -'@module-federation/dts-plugin': patch -'@module-federation/managers': patch -'@module-federation/third-party-dts-extractor': patch ---- - -Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. diff --git a/.changeset/soft-rings-serve.md b/.changeset/soft-rings-serve.md deleted file mode 100644 index ac53dd69fd1..00000000000 --- a/.changeset/soft-rings-serve.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@module-federation/dts-plugin": minor -"@module-federation/enhanced": patch -"@module-federation/modern-js": patch -"@module-federation/modern-js-v3": patch -"@module-federation/playground": patch -"@module-federation/rspack": patch ---- - -feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported diff --git a/.changeset/tidy-cats-optimize.md b/.changeset/tidy-cats-optimize.md deleted file mode 100644 index 76ecb26da1c..00000000000 --- a/.changeset/tidy-cats-optimize.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@module-federation/modern-js": patch -"@module-federation/modern-js-v3": patch ---- - -Automatically select federation optimization targets for Modern.js browser and -SSR builds, with an option to disable this behavior. diff --git a/.changeset/tidy-rspack-identifiers.md b/.changeset/tidy-rspack-identifiers.md deleted file mode 100644 index ce5aa80b06f..00000000000 --- a/.changeset/tidy-rspack-identifiers.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@module-federation/manifest': patch -'@module-federation/utilities': patch ---- - -Support Rspack container reference identifiers when collecting remote and delegate modules. diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 1f1be3681e8..cc3fd4d5a23 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -86,9 +86,11 @@ jobs: run: node tools/scripts/run-affected-package-tests.mjs - name: Pack Node.js 20 compatibility artifacts + if: ${{ !startsWith(github.head_ref, 'release-v') }} run: node tools/scripts/prepare-node20-compat-packages.mjs - name: Upload Node.js 20 compatibility artifacts + if: ${{ !startsWith(github.head_ref, 'release-v') }} uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: node20-compat-packages @@ -109,6 +111,7 @@ jobs: secrets: inherit node20-compat: + if: ${{ !startsWith(github.head_ref, 'release-v') }} needs: checkout-install runs-on: ubuntu-latest timeout-minutes: 15 diff --git a/apps/node-dynamic-remote-new-version/CHANGELOG.md b/apps/node-dynamic-remote-new-version/CHANGELOG.md index 7af9cca77fa..01bf18105f2 100644 --- a/apps/node-dynamic-remote-new-version/CHANGELOG.md +++ b/apps/node-dynamic-remote-new-version/CHANGELOG.md @@ -1,5 +1,11 @@ # node-dynamic-remote-new-version +## 1.0.14 + +### Patch Changes + +- @module-federation/node@2.7.47 + ## 1.0.13 ### Patch Changes diff --git a/apps/node-dynamic-remote-new-version/package.json b/apps/node-dynamic-remote-new-version/package.json index e11ad12b5af..c7bad659bda 100644 --- a/apps/node-dynamic-remote-new-version/package.json +++ b/apps/node-dynamic-remote-new-version/package.json @@ -6,7 +6,7 @@ "@module-federation/node": "workspace:*", "lodash": "4.18.1" }, - "version": "1.0.13", + "version": "1.0.14", "scripts": { "build": "NODE_OPTIONS=--max_old_space_size=4096 pnpm exec webpack-cli --config webpack.config.js --output-path dist --mode production", "build:development": "NODE_OPTIONS=--max_old_space_size=4096 pnpm exec webpack-cli --config webpack.config.js --output-path dist --mode development", diff --git a/apps/node-dynamic-remote/CHANGELOG.md b/apps/node-dynamic-remote/CHANGELOG.md index 1b56e7a4447..bef50dfb6aa 100644 --- a/apps/node-dynamic-remote/CHANGELOG.md +++ b/apps/node-dynamic-remote/CHANGELOG.md @@ -1,5 +1,11 @@ # node-dynamic-remote +## 1.0.14 + +### Patch Changes + +- @module-federation/node@2.7.47 + ## 1.0.13 ### Patch Changes diff --git a/apps/node-dynamic-remote/package.json b/apps/node-dynamic-remote/package.json index e046a9b06fc..3116fa9278a 100644 --- a/apps/node-dynamic-remote/package.json +++ b/apps/node-dynamic-remote/package.json @@ -6,7 +6,7 @@ "@module-federation/node": "workspace:*", "lodash": "4.18.1" }, - "version": "1.0.13", + "version": "1.0.14", "scripts": { "build": "NODE_OPTIONS=--max_old_space_size=4096 pnpm exec webpack-cli --config webpack.config.js --output-path dist --mode production", "build:development": "NODE_OPTIONS=--max_old_space_size=4096 pnpm exec webpack-cli --config webpack.config.js --output-path dist --mode development", diff --git a/apps/router-demo/router-remote5-2005/CHANGELOG.md b/apps/router-demo/router-remote5-2005/CHANGELOG.md index 13f4382a186..647ac8e61c4 100644 --- a/apps/router-demo/router-remote5-2005/CHANGELOG.md +++ b/apps/router-demo/router-remote5-2005/CHANGELOG.md @@ -1,5 +1,14 @@ # remote5 +## 2.0.16 + +### Patch Changes + +- Updated dependencies [cef63f9] +- Updated dependencies [6ee67dc] + - @module-federation/rsbuild-plugin@2.8.0 + - @module-federation/bridge-react@2.8.0 + ## 2.0.15 ### Patch Changes diff --git a/apps/router-demo/router-remote5-2005/package.json b/apps/router-demo/router-remote5-2005/package.json index 9cf27bc915c..3e84252bf00 100644 --- a/apps/router-demo/router-remote5-2005/package.json +++ b/apps/router-demo/router-remote5-2005/package.json @@ -1,7 +1,7 @@ { "name": "remote5", "private": true, - "version": "2.0.15", + "version": "2.0.16", "scripts": { "dev": "rsbuild dev", "build": "rsbuild build", diff --git a/apps/router-demo/router-remote6-2006/CHANGELOG.md b/apps/router-demo/router-remote6-2006/CHANGELOG.md index 0871b1acda7..29b94f64dc4 100644 --- a/apps/router-demo/router-remote6-2006/CHANGELOG.md +++ b/apps/router-demo/router-remote6-2006/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 2.0.16 + +### Patch Changes + +- Updated dependencies [cef63f9] +- Updated dependencies [6ee67dc] + - @module-federation/rsbuild-plugin@2.8.0 + - @module-federation/bridge-react@2.8.0 + ## 2.0.15 ### Patch Changes diff --git a/apps/router-demo/router-remote6-2006/package.json b/apps/router-demo/router-remote6-2006/package.json index 140ec7f5c2f..bd67f4f0080 100644 --- a/apps/router-demo/router-remote6-2006/package.json +++ b/apps/router-demo/router-remote6-2006/package.json @@ -1,7 +1,7 @@ { "name": "remote6", "private": true, - "version": "2.0.15", + "version": "2.0.16", "scripts": { "dev": "rsbuild dev", "build": "rsbuild build", diff --git a/apps/shared-tree-shaking/no-server/host/CHANGELOG.md b/apps/shared-tree-shaking/no-server/host/CHANGELOG.md index 4eb4fa2c70b..1f4dcd5c7da 100644 --- a/apps/shared-tree-shaking/no-server/host/CHANGELOG.md +++ b/apps/shared-tree-shaking/no-server/host/CHANGELOG.md @@ -1,5 +1,14 @@ # modernjs-ssr-nested-remote +## 1.0.16 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + ## 1.0.15 ### Patch Changes diff --git a/apps/shared-tree-shaking/no-server/host/package.json b/apps/shared-tree-shaking/no-server/host/package.json index 25d8ce17a15..603cf217af0 100644 --- a/apps/shared-tree-shaking/no-server/host/package.json +++ b/apps/shared-tree-shaking/no-server/host/package.json @@ -1,7 +1,7 @@ { "name": "shared-tree-shaking-no-server-host", "private": true, - "version": "1.0.15", + "version": "1.0.16", "scripts": { "reset": "npx rimraf ./**/node_modules", "dev": "TS_NODE_COMPILER=typescript-compiler modern dev", diff --git a/apps/shared-tree-shaking/no-server/provider/CHANGELOG.md b/apps/shared-tree-shaking/no-server/provider/CHANGELOG.md index 4eb4fa2c70b..1f4dcd5c7da 100644 --- a/apps/shared-tree-shaking/no-server/provider/CHANGELOG.md +++ b/apps/shared-tree-shaking/no-server/provider/CHANGELOG.md @@ -1,5 +1,14 @@ # modernjs-ssr-nested-remote +## 1.0.16 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + ## 1.0.15 ### Patch Changes diff --git a/apps/shared-tree-shaking/no-server/provider/package.json b/apps/shared-tree-shaking/no-server/provider/package.json index 1b6dde9f196..22e7aa03827 100644 --- a/apps/shared-tree-shaking/no-server/provider/package.json +++ b/apps/shared-tree-shaking/no-server/provider/package.json @@ -1,7 +1,7 @@ { "name": "shared-tree-shaking-no-server-provider", "private": true, - "version": "1.0.15", + "version": "1.0.16", "scripts": { "reset": "npx rimraf ./**/node_modules", "dev": "TS_NODE_COMPILER=typescript-compiler modern dev", diff --git a/apps/shared-tree-shaking/with-server/host/CHANGELOG.md b/apps/shared-tree-shaking/with-server/host/CHANGELOG.md index 3e4bc780ead..4c2fe623752 100644 --- a/apps/shared-tree-shaking/with-server/host/CHANGELOG.md +++ b/apps/shared-tree-shaking/with-server/host/CHANGELOG.md @@ -1,5 +1,15 @@ # modernjs-ssr-nested-remote +## 1.0.16 + +### Patch Changes + +- Updated dependencies [dcc96d1] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] +- Updated dependencies [f796458] + - @module-federation/modern-js-v3@2.8.0 + ## 1.0.15 ### Patch Changes diff --git a/apps/shared-tree-shaking/with-server/host/package.json b/apps/shared-tree-shaking/with-server/host/package.json index 918c9e9f58a..8b49d4b6ea2 100644 --- a/apps/shared-tree-shaking/with-server/host/package.json +++ b/apps/shared-tree-shaking/with-server/host/package.json @@ -1,7 +1,7 @@ { "name": "shared-tree-shaking-with-server-host", "private": true, - "version": "1.0.15", + "version": "1.0.16", "scripts": { "reset": "npx rimraf ./**/node_modules", "dev": "TS_NODE_COMPILER=typescript-compiler modern dev", diff --git a/apps/shared-tree-shaking/with-server/provider/CHANGELOG.md b/apps/shared-tree-shaking/with-server/provider/CHANGELOG.md index 3e4bc780ead..4c2fe623752 100644 --- a/apps/shared-tree-shaking/with-server/provider/CHANGELOG.md +++ b/apps/shared-tree-shaking/with-server/provider/CHANGELOG.md @@ -1,5 +1,15 @@ # modernjs-ssr-nested-remote +## 1.0.16 + +### Patch Changes + +- Updated dependencies [dcc96d1] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] +- Updated dependencies [f796458] + - @module-federation/modern-js-v3@2.8.0 + ## 1.0.15 ### Patch Changes diff --git a/apps/shared-tree-shaking/with-server/provider/package.json b/apps/shared-tree-shaking/with-server/provider/package.json index 419f0ff511c..4233610b981 100644 --- a/apps/shared-tree-shaking/with-server/provider/package.json +++ b/apps/shared-tree-shaking/with-server/provider/package.json @@ -1,7 +1,7 @@ { "name": "shared-tree-shaking-with-server-provider", "private": true, - "version": "1.0.15", + "version": "1.0.16", "scripts": { "reset": "npx rimraf ./**/node_modules", "dev": "TS_NODE_COMPILER=typescript-compiler modern dev", diff --git a/apps/website-new/CHANGELOG.md b/apps/website-new/CHANGELOG.md index 3d9abebd2ff..c22d8227b27 100644 --- a/apps/website-new/CHANGELOG.md +++ b/apps/website-new/CHANGELOG.md @@ -1,5 +1,13 @@ # website-new +## 1.3.28 + +### Patch Changes + +- @module-federation/rspress-plugin@2.8.0 +- @module-federation/runtime@2.8.0 +- @module-federation/error-codes@2.8.0 + ## 1.3.27 ### Patch Changes diff --git a/apps/website-new/package.json b/apps/website-new/package.json index c7786aa1bd1..96d10bf68ac 100644 --- a/apps/website-new/package.json +++ b/apps/website-new/package.json @@ -1,6 +1,6 @@ { "name": "website-new", - "version": "1.3.27", + "version": "1.3.28", "private": true, "description": "Federation example for website-new", "scripts": { diff --git a/packages/bridge/bridge-react-webpack-plugin/CHANGELOG.md b/packages/bridge/bridge-react-webpack-plugin/CHANGELOG.md index 847ea97f173..3dbf2692527 100644 --- a/packages/bridge/bridge-react-webpack-plugin/CHANGELOG.md +++ b/packages/bridge/bridge-react-webpack-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/bridge-react-webpack-plugin +## 2.8.0 + +### Patch Changes + +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/bridge/bridge-react-webpack-plugin/package.json b/packages/bridge/bridge-react-webpack-plugin/package.json index 2eb6e6f9ba5..df43da5080d 100644 --- a/packages/bridge/bridge-react-webpack-plugin/package.json +++ b/packages/bridge/bridge-react-webpack-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/bridge-react-webpack-plugin", - "version": "2.7.0", + "version": "2.8.0", "publishConfig": { "access": "public" }, diff --git a/packages/bridge/bridge-react/CHANGELOG.md b/packages/bridge/bridge-react/CHANGELOG.md index ab09557b452..8edb4ad660f 100644 --- a/packages/bridge/bridge-react/CHANGELOG.md +++ b/packages/bridge/bridge-react/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/bridge-react +## 2.8.0 + +### Patch Changes + +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/bridge/bridge-react/package.json b/packages/bridge/bridge-react/package.json index ae4ebadfdb8..72f234abd30 100644 --- a/packages/bridge/bridge-react/package.json +++ b/packages/bridge/bridge-react/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/bridge-react", - "version": "2.7.0", + "version": "2.8.0", "sideEffects": false, "publishConfig": { "access": "public" diff --git a/packages/bridge/bridge-shared/CHANGELOG.md b/packages/bridge/bridge-shared/CHANGELOG.md index 240dfd5af2c..ea70562d52e 100644 --- a/packages/bridge/bridge-shared/CHANGELOG.md +++ b/packages/bridge/bridge-shared/CHANGELOG.md @@ -1,5 +1,7 @@ # @module-federation/bridge-shared +## 2.8.0 + ## 2.7.0 ## 2.6.0 diff --git a/packages/bridge/bridge-shared/package.json b/packages/bridge/bridge-shared/package.json index fe6d3fb9572..9c59ec8e9c5 100644 --- a/packages/bridge/bridge-shared/package.json +++ b/packages/bridge/bridge-shared/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/bridge-shared", - "version": "2.7.0", + "version": "2.8.0", "publishConfig": { "access": "public" }, diff --git a/packages/bridge/vue3-bridge/CHANGELOG.md b/packages/bridge/vue3-bridge/CHANGELOG.md index 2991754608b..5941e1a388c 100644 --- a/packages/bridge/vue3-bridge/CHANGELOG.md +++ b/packages/bridge/vue3-bridge/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/bridge-vue3 +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/runtime@2.8.0 + - @module-federation/bridge-shared@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/bridge/vue3-bridge/package.json b/packages/bridge/vue3-bridge/package.json index c8d6b18eb27..05ba58f5357 100644 --- a/packages/bridge/vue3-bridge/package.json +++ b/packages/bridge/vue3-bridge/package.json @@ -7,7 +7,7 @@ "url": "git+https://github.com/module-federation/core.git", "directory": "packages/bridge/vue3-bridge" }, - "version": "2.7.0", + "version": "2.8.0", "publishConfig": { "access": "public" }, diff --git a/packages/chrome-devtools/CHANGELOG.md b/packages/chrome-devtools/CHANGELOG.md index 0b9c1b47d19..2fb156c5fba 100644 --- a/packages/chrome-devtools/CHANGELOG.md +++ b/packages/chrome-devtools/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/devtools +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/observability-plugin@2.5.4 + ## 2.7.0 ### Patch Changes diff --git a/packages/chrome-devtools/package.json b/packages/chrome-devtools/package.json index fc9c4da2a8e..203f46074aa 100644 --- a/packages/chrome-devtools/package.json +++ b/packages/chrome-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/devtools", - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "repository": { "type": "git", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 1bd4f0074ec..1c3a2455cbc 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,15 @@ # @module-federation/cli +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/sdk@2.8.0 + - @module-federation/dts-plugin@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 280c0660043..05bfe0b03b6 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/cli", - "version": "2.7.0", + "version": "2.8.0", "type": "commonjs", "description": "Module Federation CLI", "homepage": "https://module-federation.io", diff --git a/packages/create-module-federation/CHANGELOG.md b/packages/create-module-federation/CHANGELOG.md index c0280e8b75a..4d0ed0f805f 100644 --- a/packages/create-module-federation/CHANGELOG.md +++ b/packages/create-module-federation/CHANGELOG.md @@ -1,5 +1,7 @@ # create-module-federation +## 2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/create-module-federation/package.json b/packages/create-module-federation/package.json index f370c63d9cb..44a0fa6c646 100644 --- a/packages/create-module-federation/package.json +++ b/packages/create-module-federation/package.json @@ -3,7 +3,7 @@ "description": "Create a new Module Federation project", "public": true, "sideEffects": false, - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "repository": { "type": "git", diff --git a/packages/dts-plugin/CHANGELOG.md b/packages/dts-plugin/CHANGELOG.md index eccbea99d7a..e90a34c9c07 100644 --- a/packages/dts-plugin/CHANGELOG.md +++ b/packages/dts-plugin/CHANGELOG.md @@ -1,5 +1,21 @@ # @module-federation/dts-plugin +## 2.8.0 + +### Minor Changes + +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported + +### Patch Changes + +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] + - @module-federation/sdk@2.8.0 + - @module-federation/managers@2.8.0 + - @module-federation/third-party-dts-extractor@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/dts-plugin/package.json b/packages/dts-plugin/package.json index 6c662bcb24d..cc718e6d681 100644 --- a/packages/dts-plugin/package.json +++ b/packages/dts-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/dts-plugin", - "version": "2.7.0", + "version": "2.8.0", "author": "hanric ", "main": "./dist/index.js", "module": "./dist/esm/index.mjs", diff --git a/packages/enhanced/CHANGELOG.md b/packages/enhanced/CHANGELOG.md index 89a5060ae6e..89a61b66117 100644 --- a/packages/enhanced/CHANGELOG.md +++ b/packages/enhanced/CHANGELOG.md @@ -1,5 +1,29 @@ # @module-federation/enhanced +## 2.8.0 + +### Patch Changes + +- ea490ae: Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported +- Updated dependencies [d6a76d8] +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] +- Updated dependencies [a5633f8] + - @module-federation/manifest@2.8.0 + - @module-federation/rspack@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/webpack-bundler-runtime@2.8.0 + - @module-federation/bridge-react-webpack-plugin@2.8.0 + - @module-federation/dts-plugin@2.8.0 + - @module-federation/managers@2.8.0 + - @module-federation/cli@2.8.0 + - @module-federation/runtime-tools@2.8.0 + - @module-federation/inject-external-runtime-core-plugin@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/enhanced/package.json b/packages/enhanced/package.json index 975cf4aeb5d..803aa1dc3d2 100644 --- a/packages/enhanced/package.json +++ b/packages/enhanced/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/enhanced", - "version": "2.7.0", + "version": "2.8.0", "main": "./dist/src/index.js", "types": "./dist/src/index.d.ts", "repository": { diff --git a/packages/error-codes/CHANGELOG.md b/packages/error-codes/CHANGELOG.md index 50547979aa6..56ba0461fbf 100644 --- a/packages/error-codes/CHANGELOG.md +++ b/packages/error-codes/CHANGELOG.md @@ -1,5 +1,7 @@ # @module-federation/error-codes +## 2.8.0 + ## 2.7.0 ## 2.6.0 diff --git a/packages/error-codes/package.json b/packages/error-codes/package.json index 2c018ef4d50..563ee2efdcd 100644 --- a/packages/error-codes/package.json +++ b/packages/error-codes/package.json @@ -4,7 +4,7 @@ "author": "zhanghang ", "public": true, "sideEffects": false, - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "repository": { "type": "git", diff --git a/packages/esbuild/CHANGELOG.md b/packages/esbuild/CHANGELOG.md index 33704711fc5..af1ad4dc918 100644 --- a/packages/esbuild/CHANGELOG.md +++ b/packages/esbuild/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/esbuild +## 0.0.111 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/webpack-bundler-runtime@2.8.0 + - @module-federation/runtime@2.8.0 + ## 0.0.110 ### Patch Changes diff --git a/packages/esbuild/package.json b/packages/esbuild/package.json index 9d42de4054e..c97e6ead5a9 100644 --- a/packages/esbuild/package.json +++ b/packages/esbuild/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/esbuild", - "version": "0.0.110", + "version": "0.0.111", "author": "Zack Jackson (@ScriptedAlchemy)", "main": "./dist/index.js", "module": "./dist/index.mjs", diff --git a/packages/managers/CHANGELOG.md b/packages/managers/CHANGELOG.md index c3430b66719..8b13079a40f 100644 --- a/packages/managers/CHANGELOG.md +++ b/packages/managers/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/managers +## 2.8.0 + +### Patch Changes + +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/managers/package.json b/packages/managers/package.json index d56d0937e27..8a383529bf1 100644 --- a/packages/managers/package.json +++ b/packages/managers/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/managers", - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "description": "Provide managers for helping handle mf data .", "keywords": [ diff --git a/packages/manifest/CHANGELOG.md b/packages/manifest/CHANGELOG.md index 23ba71b9b96..e2980c32293 100644 --- a/packages/manifest/CHANGELOG.md +++ b/packages/manifest/CHANGELOG.md @@ -1,5 +1,19 @@ # @module-federation/manifest +## 2.8.0 + +### Patch Changes + +- d6a76d8: Preserve the configured Module Federation library type when reconciling + Rspack-pre-emitted stats and manifests, including ESM `module` remote entries. +- a5633f8: Support Rspack container reference identifiers when collecting remote and delegate modules. +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/sdk@2.8.0 + - @module-federation/dts-plugin@2.8.0 + - @module-federation/managers@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/manifest/package.json b/packages/manifest/package.json index 679ef57f4e9..63015bae16d 100644 --- a/packages/manifest/package.json +++ b/packages/manifest/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/manifest", - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "description": "Provide manifest/stats for webpack/rspack MF project .", "keywords": [ diff --git a/packages/metro-core/CHANGELOG.md b/packages/metro-core/CHANGELOG.md index 996d6c55fb2..2d6a6a49c02 100644 --- a/packages/metro-core/CHANGELOG.md +++ b/packages/metro-core/CHANGELOG.md @@ -1,5 +1,19 @@ # @module-federation/metro +## 2.8.0 + +### Patch Changes + +- 2dc9a40: chore: bump Rock dependencies to 0.14.1 +- d4da7fb: fix: normalize Metro paths on Windows +- 7c4ac9f: Support TypeScript 7 in Metro projects. +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/sdk@2.8.0 + - @module-federation/dts-plugin@2.8.0 + - @module-federation/runtime@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/metro-core/package.json b/packages/metro-core/package.json index 54ceca15779..a1b63c6c8a3 100644 --- a/packages/metro-core/package.json +++ b/packages/metro-core/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/metro", - "version": "2.7.0", + "version": "2.8.0", "description": "Module Federation for Metro bundler", "keywords": [ "module-federation", diff --git a/packages/metro-plugin-rnc-cli/CHANGELOG.md b/packages/metro-plugin-rnc-cli/CHANGELOG.md index d5b02f50916..1a15cecb7db 100644 --- a/packages/metro-plugin-rnc-cli/CHANGELOG.md +++ b/packages/metro-plugin-rnc-cli/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/metro-plugin-rnc-cli +## 2.8.0 + +### Patch Changes + +- Updated dependencies [2dc9a40] +- Updated dependencies [d4da7fb] +- Updated dependencies [7c4ac9f] + - @module-federation/metro@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/metro-plugin-rnc-cli/package.json b/packages/metro-plugin-rnc-cli/package.json index 2817dca210d..51b9c4bce45 100644 --- a/packages/metro-plugin-rnc-cli/package.json +++ b/packages/metro-plugin-rnc-cli/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/metro-plugin-rnc-cli", - "version": "2.7.0", + "version": "2.8.0", "description": "Metro Module Federation plugin for React Native Enterprise Framework (RNEF)", "keywords": [ "rnc", diff --git a/packages/metro-plugin-rnef/CHANGELOG.md b/packages/metro-plugin-rnef/CHANGELOG.md index d3e8a32434c..c238f6f66ba 100644 --- a/packages/metro-plugin-rnef/CHANGELOG.md +++ b/packages/metro-plugin-rnef/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/metro-plugin-rnef +## 2.8.0 + +### Patch Changes + +- Updated dependencies [2dc9a40] +- Updated dependencies [d4da7fb] +- Updated dependencies [7c4ac9f] + - @module-federation/metro@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/metro-plugin-rnef/package.json b/packages/metro-plugin-rnef/package.json index 471bae45619..67b0131bf7b 100644 --- a/packages/metro-plugin-rnef/package.json +++ b/packages/metro-plugin-rnef/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/metro-plugin-rnef", - "version": "2.7.0", + "version": "2.8.0", "description": "Metro Module Federation plugin for React Native Enterprise Framework (RNEF). Deprecated: use @module-federation/metro-plugin-rock instead.", "keywords": [ "rnef", diff --git a/packages/metro-plugin-rock/CHANGELOG.md b/packages/metro-plugin-rock/CHANGELOG.md index 693577f4bd3..c472edf1916 100644 --- a/packages/metro-plugin-rock/CHANGELOG.md +++ b/packages/metro-plugin-rock/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/metro-plugin-rock +## 2.8.0 + +### Patch Changes + +- Updated dependencies [2dc9a40] +- Updated dependencies [d4da7fb] +- Updated dependencies [7c4ac9f] + - @module-federation/metro@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/metro-plugin-rock/package.json b/packages/metro-plugin-rock/package.json index bd7513039ef..90eee5151f2 100644 --- a/packages/metro-plugin-rock/package.json +++ b/packages/metro-plugin-rock/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/metro-plugin-rock", - "version": "2.7.0", + "version": "2.8.0", "description": "Metro Module Federation plugin for Rock", "keywords": [ "rock", diff --git a/packages/modernjs-v3/CHANGELOG.md b/packages/modernjs-v3/CHANGELOG.md index a6ab95bcde5..b4c5af671bf 100644 --- a/packages/modernjs-v3/CHANGELOG.md +++ b/packages/modernjs-v3/CHANGELOG.md @@ -1,5 +1,26 @@ # @module-federation/modern-js-v3 +## 2.8.0 + +### Patch Changes + +- dcc96d1: fix(modernjs-v3): set optimization.usedExports to "global" to prevent tree shaking issues in micro frontend mode +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported +- f796458: Automatically select federation optimization targets for Modern.js browser and + SSR builds, with an option to disable this behavior. +- Updated dependencies [cef63f9] +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/rsbuild-plugin@2.8.0 + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/bridge-react@2.8.0 + - @module-federation/node@2.7.47 + - @module-federation/runtime@2.8.0 + - @module-federation/cli@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/modernjs-v3/package.json b/packages/modernjs-v3/package.json index f85a0f39c59..1254892d02a 100644 --- a/packages/modernjs-v3/package.json +++ b/packages/modernjs-v3/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/modern-js-v3", - "version": "2.7.0", + "version": "2.8.0", "files": [ "dist/", "types.d.ts", diff --git a/packages/modernjs/CHANGELOG.md b/packages/modernjs/CHANGELOG.md index 2aa3fcf7cf4..f38afcb2900 100644 --- a/packages/modernjs/CHANGELOG.md +++ b/packages/modernjs/CHANGELOG.md @@ -1,5 +1,26 @@ # @module-federation/modern-js +## 2.8.0 + +### Patch Changes + +- dcc96d1: fix(modernjs-v3): set optimization.usedExports to "global" to prevent tree shaking issues in micro frontend mode +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported +- f796458: Automatically select federation optimization targets for Modern.js browser and + SSR builds, with an option to disable this behavior. +- Updated dependencies [cef63f9] +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/rsbuild-plugin@2.8.0 + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/bridge-react@2.8.0 + - @module-federation/node@2.7.47 + - @module-federation/runtime@2.8.0 + - @module-federation/cli@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/modernjs/package.json b/packages/modernjs/package.json index cf404331f03..11ef9de5dee 100644 --- a/packages/modernjs/package.json +++ b/packages/modernjs/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/modern-js", - "version": "2.7.0", + "version": "2.8.0", "files": [ "dist/", "types.d.ts", diff --git a/packages/nextjs-mf/CHANGELOG.md b/packages/nextjs-mf/CHANGELOG.md index e36ab946211..850e8f7c69a 100644 --- a/packages/nextjs-mf/CHANGELOG.md +++ b/packages/nextjs-mf/CHANGELOG.md @@ -1,5 +1,19 @@ # @module-federation/nextjs-mf +## 8.8.71 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + - @module-federation/runtime-core@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/webpack-bundler-runtime@2.8.0 + - @module-federation/node@2.7.47 + - @module-federation/runtime@2.8.0 + ## 8.8.70 ### Patch Changes diff --git a/packages/nextjs-mf/package.json b/packages/nextjs-mf/package.json index 81cddc13f81..f2edbf48dcc 100644 --- a/packages/nextjs-mf/package.json +++ b/packages/nextjs-mf/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/nextjs-mf", - "version": "8.8.70", + "version": "8.8.71", "license": "MIT", "main": "dist/src/index.js", "module": "dist/src/index.mjs", diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index 95d38b97b8a..57fabfc9f82 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -1,5 +1,16 @@ # @module-federation/node +## 2.7.47 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/runtime@2.8.0 + ## 2.7.46 ### Patch Changes diff --git a/packages/node/package.json b/packages/node/package.json index 1b1e2fb9ecd..dad743013bb 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,7 +1,7 @@ { "public": true, "name": "@module-federation/node", - "version": "2.7.46", + "version": "2.7.47", "type": "commonjs", "main": "./dist/src/index.js", "module": "./dist/src/index.mjs", diff --git a/packages/observability-plugin/CHANGELOG.md b/packages/observability-plugin/CHANGELOG.md index 158d72129c0..675b83cb179 100644 --- a/packages/observability-plugin/CHANGELOG.md +++ b/packages/observability-plugin/CHANGELOG.md @@ -1,5 +1,12 @@ # @module-federation/observability-plugin +## 2.5.4 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + ## 2.5.3 ### Patch Changes diff --git a/packages/observability-plugin/package.json b/packages/observability-plugin/package.json index 87246ba16bc..e80d54ae90c 100644 --- a/packages/observability-plugin/package.json +++ b/packages/observability-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/observability-plugin", - "version": "2.5.3", + "version": "2.5.4", "author": "module-federation", "main": "./dist/index.js", "module": "./dist/esm/index.js", diff --git a/packages/playground/CHANGELOG.md b/packages/playground/CHANGELOG.md index 80e9c30ac12..8bdf541986b 100644 --- a/packages/playground/CHANGELOG.md +++ b/packages/playground/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/playground +## 0.0.3 + +### Patch Changes + +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported +- Updated dependencies [6ee67dc] + - @module-federation/bridge-react@2.8.0 + - @module-federation/runtime@2.8.0 + ## 0.0.2 ### Patch Changes diff --git a/packages/playground/package.json b/packages/playground/package.json index 136cba4ed31..f1f697b3c61 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/playground", - "version": "0.0.2", + "version": "0.0.3", "description": "Module Federation Playground", "homepage": "https://module-federation.io", "repository": { diff --git a/packages/retry-plugin/CHANGELOG.md b/packages/retry-plugin/CHANGELOG.md index 4a880ffdbd5..0749ba96080 100644 --- a/packages/retry-plugin/CHANGELOG.md +++ b/packages/retry-plugin/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/retry-plugin +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/runtime@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/retry-plugin/package.json b/packages/retry-plugin/package.json index 77d202bda5d..b648ddd4dd8 100644 --- a/packages/retry-plugin/package.json +++ b/packages/retry-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/retry-plugin", - "version": "2.7.0", + "version": "2.8.0", "author": "danpeen ", "main": "./dist/index.js", "module": "./dist/esm/index.js", diff --git a/packages/rsbuild-plugin/CHANGELOG.md b/packages/rsbuild-plugin/CHANGELOG.md index 2dba2c1bb92..b78977167f4 100644 --- a/packages/rsbuild-plugin/CHANGELOG.md +++ b/packages/rsbuild-plugin/CHANGELOG.md @@ -1,5 +1,17 @@ # @module-federation/rsbuild-plugin +## 2.8.0 + +### Patch Changes + +- cef63f9: fix(rsbuild-plugin): force `output.library.type` to `commonjs-module` in `patchNodeConfig` so the `mf-ssr` bundle stops emitting module-scope `export {}` and passes rspack 2.1.x minification. +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/node@2.7.47 + ## 2.7.0 ### Patch Changes diff --git a/packages/rsbuild-plugin/package.json b/packages/rsbuild-plugin/package.json index 413b97d8879..3d6dfa29ee8 100644 --- a/packages/rsbuild-plugin/package.json +++ b/packages/rsbuild-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/rsbuild-plugin", - "version": "2.7.0", + "version": "2.8.0", "description": "Module Federation plugin for Rsbuild", "homepage": "https://module-federation.io", "bugs": { diff --git a/packages/rspack/CHANGELOG.md b/packages/rspack/CHANGELOG.md index c997cb444dc..9844aebc01c 100644 --- a/packages/rspack/CHANGELOG.md +++ b/packages/rspack/CHANGELOG.md @@ -1,5 +1,24 @@ # @module-federation/rspack +## 2.8.0 + +### Patch Changes + +- ea490ae: Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. +- 681e5d2: feat(dts-plugin): support ts 7 for federated type generation while keeping existing ts versions supported +- Updated dependencies [d6a76d8] +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] +- Updated dependencies [a5633f8] + - @module-federation/manifest@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/bridge-react-webpack-plugin@2.8.0 + - @module-federation/dts-plugin@2.8.0 + - @module-federation/managers@2.8.0 + - @module-federation/runtime-tools@2.8.0 + - @module-federation/inject-external-runtime-core-plugin@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/rspack/package.json b/packages/rspack/package.json index b2eac5ed11c..544a0f10922 100644 --- a/packages/rspack/package.json +++ b/packages/rspack/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/rspack", - "version": "2.7.0", + "version": "2.8.0", "license": "MIT", "keywords": [ "Module Federation", diff --git a/packages/rspress-plugin/CHANGELOG.md b/packages/rspress-plugin/CHANGELOG.md index 17bab83a7db..b3ba81e7ef0 100644 --- a/packages/rspress-plugin/CHANGELOG.md +++ b/packages/rspress-plugin/CHANGELOG.md @@ -1,5 +1,18 @@ # @module-federation/rspress-plugin +## 2.8.0 + +### Patch Changes + +- Updated dependencies [cef63f9] +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/rsbuild-plugin@2.8.0 + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/rspress-plugin/package.json b/packages/rspress-plugin/package.json index c7cca0d80fa..77f050a5924 100644 --- a/packages/rspress-plugin/package.json +++ b/packages/rspress-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/rspress-plugin", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "description": "Module Federation plugin for Rspress", "keywords": [ diff --git a/packages/runtime-core/CHANGELOG.md b/packages/runtime-core/CHANGELOG.md index c48efd270d5..a86e3fb77d7 100644 --- a/packages/runtime-core/CHANGELOG.md +++ b/packages/runtime-core/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/runtime +## 2.8.0 + +### Patch Changes + +- ea490ae: Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/runtime-core/package.json b/packages/runtime-core/package.json index 55150bb8c49..9d37fe23b86 100644 --- a/packages/runtime-core/package.json +++ b/packages/runtime-core/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/runtime-core", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "author": "zhouxiao ", "main": "./dist/index.cjs", diff --git a/packages/runtime-plugins/inject-external-runtime-core-plugin/CHANGELOG.md b/packages/runtime-plugins/inject-external-runtime-core-plugin/CHANGELOG.md index c5bde293d9a..1cab6a39516 100644 --- a/packages/runtime-plugins/inject-external-runtime-core-plugin/CHANGELOG.md +++ b/packages/runtime-plugins/inject-external-runtime-core-plugin/CHANGELOG.md @@ -1,5 +1,11 @@ # @module-federation/inject-external-runtime-core-plugin +## 2.8.0 + +### Patch Changes + +- @module-federation/runtime-tools@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/runtime-plugins/inject-external-runtime-core-plugin/package.json b/packages/runtime-plugins/inject-external-runtime-core-plugin/package.json index 43c3cbc0cfc..0322f861754 100644 --- a/packages/runtime-plugins/inject-external-runtime-core-plugin/package.json +++ b/packages/runtime-plugins/inject-external-runtime-core-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/inject-external-runtime-core-plugin", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "license": "MIT", "description": "A sdk for support module federation", diff --git a/packages/runtime-tools/CHANGELOG.md b/packages/runtime-tools/CHANGELOG.md index f034b9637e8..869e54657bb 100644 --- a/packages/runtime-tools/CHANGELOG.md +++ b/packages/runtime-tools/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/runtime-tools +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/webpack-bundler-runtime@2.8.0 + - @module-federation/runtime@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/runtime-tools/package.json b/packages/runtime-tools/package.json index 88d56febd94..885f08b6717 100644 --- a/packages/runtime-tools/package.json +++ b/packages/runtime-tools/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/runtime-tools", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "author": "zhanghang ", "main": "./dist/index.cjs", diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index 15855ffda5a..0794b197dfb 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -1,5 +1,14 @@ # @module-federation/runtime +## 2.8.0 + +### Patch Changes + +- Updated dependencies [ea490ae] + - @module-federation/runtime-core@2.8.0 + - @module-federation/sdk@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/runtime/package.json b/packages/runtime/package.json index a66e34d141e..4920225b84a 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/runtime", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "author": "zhouxiao ", "main": "./dist/index.cjs", diff --git a/packages/sdk/CHANGELOG.md b/packages/sdk/CHANGELOG.md index 9b4b65a72d5..3e9c1059a71 100644 --- a/packages/sdk/CHANGELOG.md +++ b/packages/sdk/CHANGELOG.md @@ -1,5 +1,11 @@ # @module-federation/sdk +## 2.8.0 + +### Patch Changes + +- ea490ae: Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. + ## 2.7.0 ### Minor Changes diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 85ca021f505..97627c8a696 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/sdk", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "license": "MIT", "description": "A sdk for support module federation", diff --git a/packages/storybook-addon/CHANGELOG.md b/packages/storybook-addon/CHANGELOG.md index 4e4e924eec0..7d7f2e8704c 100644 --- a/packages/storybook-addon/CHANGELOG.md +++ b/packages/storybook-addon/CHANGELOG.md @@ -1,5 +1,15 @@ # @module-federation/storybook-addon +## 6.0.16 + +### Patch Changes + +- Updated dependencies [ea490ae] +- Updated dependencies [6ee67dc] +- Updated dependencies [681e5d2] + - @module-federation/enhanced@2.8.0 + - @module-federation/sdk@2.8.0 + ## 6.0.15 ### Patch Changes diff --git a/packages/storybook-addon/package.json b/packages/storybook-addon/package.json index 26d0261c756..de0d32e7f5c 100644 --- a/packages/storybook-addon/package.json +++ b/packages/storybook-addon/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/storybook-addon", - "version": "6.0.15", + "version": "6.0.16", "description": "Storybook addon to consume remote module federated apps/components", "type": "module", "license": "MIT", @@ -65,7 +65,7 @@ }, "peerDependencies": { "@rsbuild/core": "^1.0.1 || ^2.0.0-0", - "@module-federation/sdk": "^2.7.0", + "@module-federation/sdk": "^2.8.0", "@nx/react": ">= 16.0.0", "@nx/webpack": ">= 16.0.0", "@nx/module-federation": ">= 16.0.0", diff --git a/packages/third-party-dts-extractor/CHANGELOG.md b/packages/third-party-dts-extractor/CHANGELOG.md index 379efb343cb..74f67eb93e0 100644 --- a/packages/third-party-dts-extractor/CHANGELOG.md +++ b/packages/third-party-dts-extractor/CHANGELOG.md @@ -1,5 +1,11 @@ # @module-federation/third-party-dts-extractor +## 2.8.0 + +### Patch Changes + +- 6ee67dc: Reduce installed and bundled size by replacing general-purpose cache, path, version, package lookup, scheduling, fetch, and error fallback dependencies with focused built-in utilities. + ## 2.7.0 ### Patch Changes diff --git a/packages/third-party-dts-extractor/package.json b/packages/third-party-dts-extractor/package.json index b9fd242dca7..51c9cb04402 100644 --- a/packages/third-party-dts-extractor/package.json +++ b/packages/third-party-dts-extractor/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/third-party-dts-extractor", - "version": "2.7.0", + "version": "2.8.0", "files": [ "dist/", "README.md" diff --git a/packages/treeshake-frontend/CHANGELOG.md b/packages/treeshake-frontend/CHANGELOG.md index ae4afb78759..16c3d99b9ef 100644 --- a/packages/treeshake-frontend/CHANGELOG.md +++ b/packages/treeshake-frontend/CHANGELOG.md @@ -1,5 +1,7 @@ # @module-federation/treeshake-frontend +## 2.8.0 + ## 2.7.0 ## 2.6.0 diff --git a/packages/treeshake-frontend/package.json b/packages/treeshake-frontend/package.json index d07610d2a73..985b92627b0 100644 --- a/packages/treeshake-frontend/package.json +++ b/packages/treeshake-frontend/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/treeshake-frontend", - "version": "2.7.0", + "version": "2.8.0", "scripts": { "dev": "rsbuild dev", "build": "rsbuild build && rslib build", diff --git a/packages/treeshake-server/CHANGELOG.md b/packages/treeshake-server/CHANGELOG.md index ba59e0de649..5fac9856179 100644 --- a/packages/treeshake-server/CHANGELOG.md +++ b/packages/treeshake-server/CHANGELOG.md @@ -1,5 +1,7 @@ # @module-federation/treeshake-server +## 2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/treeshake-server/package.json b/packages/treeshake-server/package.json index 06f9da9ce36..92289778f19 100644 --- a/packages/treeshake-server/package.json +++ b/packages/treeshake-server/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/treeshake-server", - "version": "2.7.0", + "version": "2.8.0", "description": "Build service powered by Hono that installs dependencies, builds with Rspack, and uploads artifacts.", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/packages/utilities/CHANGELOG.md b/packages/utilities/CHANGELOG.md index 2c7ac10cbc5..c46eda127fb 100644 --- a/packages/utilities/CHANGELOG.md +++ b/packages/utilities/CHANGELOG.md @@ -1,5 +1,13 @@ # @module-federation/utilities +## 3.1.99 + +### Patch Changes + +- a5633f8: Support Rspack container reference identifiers when collecting remote and delegate modules. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + ## 3.1.98 ### Patch Changes diff --git a/packages/utilities/package.json b/packages/utilities/package.json index 73999e0e539..1a8c3a0b9b5 100644 --- a/packages/utilities/package.json +++ b/packages/utilities/package.json @@ -1,6 +1,6 @@ { "name": "@module-federation/utilities", - "version": "3.1.98", + "version": "3.1.99", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.mjs", "types": "./dist/types/index.d.ts", diff --git a/packages/webpack-bundler-runtime/CHANGELOG.md b/packages/webpack-bundler-runtime/CHANGELOG.md index 9b5ca40aeea..196e45ceda9 100644 --- a/packages/webpack-bundler-runtime/CHANGELOG.md +++ b/packages/webpack-bundler-runtime/CHANGELOG.md @@ -1,5 +1,15 @@ # @module-federation/webpack-bundler-runtime +## 2.8.0 + +### Patch Changes + +- ea490ae: Allow builds to exclude unused remote consumption and shared capabilities, and automatically omit Webpack container initialization when no exposes are configured. +- Updated dependencies [ea490ae] + - @module-federation/sdk@2.8.0 + - @module-federation/runtime@2.8.0 + - @module-federation/error-codes@2.8.0 + ## 2.7.0 ### Patch Changes diff --git a/packages/webpack-bundler-runtime/package.json b/packages/webpack-bundler-runtime/package.json index b5ef2e67ff4..2b87af52c82 100644 --- a/packages/webpack-bundler-runtime/package.json +++ b/packages/webpack-bundler-runtime/package.json @@ -1,7 +1,7 @@ { "public": true, "name": "@module-federation/webpack-bundler-runtime", - "version": "2.7.0", + "version": "2.8.0", "type": "module", "license": "MIT", "description": "Module Federation Runtime for webpack", From 65cdf342b221d889795393d11d8d04a98b34ad4f Mon Sep 17 00:00:00 2001 From: "dm.choi" Date: Thu, 16 Jul 2026 03:51:23 +0900 Subject: [PATCH 27/37] fix(runtime-core): avoid executing ESM remote chunks before init (#4886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Néstor Co-authored-by: ScriptedAlchemy --- .changeset/fix-runtime-esm-preload.md | 7 + .../__tests__/preload-assets.spec.ts | 328 ++++++++++++++++++ packages/runtime-core/src/utils/load.ts | 36 +- packages/runtime-core/src/utils/preload.ts | 52 ++- 4 files changed, 380 insertions(+), 43 deletions(-) create mode 100644 .changeset/fix-runtime-esm-preload.md create mode 100644 packages/runtime-core/__tests__/preload-assets.spec.ts diff --git a/.changeset/fix-runtime-esm-preload.md b/.changeset/fix-runtime-esm-preload.md new file mode 100644 index 00000000000..3041d317f8a --- /dev/null +++ b/.changeset/fix-runtime-esm-preload.md @@ -0,0 +1,7 @@ +--- +'@module-federation/runtime-core': patch +--- + +fix(runtime): preload ESM remote chunks with `modulepreload` links instead of +executable module scripts before container initialization. Loader plugins now +observe these implicit ESM preloads through `createLink`. diff --git a/packages/runtime-core/__tests__/preload-assets.spec.ts b/packages/runtime-core/__tests__/preload-assets.spec.ts new file mode 100644 index 00000000000..7a3ffeb6a8e --- /dev/null +++ b/packages/runtime-core/__tests__/preload-assets.spec.ts @@ -0,0 +1,328 @@ +import type { ModuleInfo } from '@module-federation/sdk'; +import { describe, it, rs } from '@rstest/core'; +import { ModuleFederation } from '../src/core'; +import type { RemoteInfo } from '../src/type'; +import type { + ResourceLoadContext, + ResourceLoadInitiator, +} from '../src/type/preload'; +import type { ModuleFederationRuntimePlugin } from '../src/type/plugin'; +import { preloadAssets } from '../src/utils/preload'; + +type ResourceCall = { + url: string; + attrs: Record; + remoteInfo: RemoteInfo; + resourceContext?: ResourceLoadContext; +}; + +type ResourceCalls = { + links: ResourceCall[]; + scripts: ResourceCall[]; +}; + +function createResourceCalls(): ResourceCalls { + return { links: [], scripts: [] }; +} + +function completeLoadWhenHandlerIsAttached(element: HTMLElement): void { + let onload: GlobalEventHandlers['onload'] | null = null; + Object.defineProperty(element, 'onload', { + configurable: true, + get() { + return onload; + }, + set(handler: GlobalEventHandlers['onload'] | null) { + onload = handler; + if (handler) { + queueMicrotask(() => handler.call(element, new Event('load'))); + } + }, + }); +} + +function applyAttrs( + element: HTMLElement, + attrs: Record, +): void { + Object.entries(attrs).forEach(([name, value]) => { + element.setAttribute(name, String(value)); + }); +} + +function createResourceCapturePlugin( + calls: ResourceCalls, +): ModuleFederationRuntimePlugin { + return { + name: 'capture-preload-resources', + beforeInit(args) { + args.options.inBrowser = true; + return args; + }, + createLink({ url, attrs = {}, remoteInfo, resourceContext }) { + calls.links.push({ url, attrs, remoteInfo, resourceContext }); + const link = document.createElement('link'); + link.href = url; + applyAttrs(link, attrs); + completeLoadWhenHandlerIsAttached(link); + return link; + }, + createScript({ url, attrs = {}, remoteInfo, resourceContext }) { + calls.scripts.push({ url, attrs, remoteInfo, resourceContext }); + const script = document.createElement('script'); + script.src = url; + applyAttrs(script, attrs); + completeLoadWhenHandlerIsAttached(script); + return script; + }, + }; +} + +function createHost(calls: ResourceCalls): ModuleFederation { + return new ModuleFederation({ + name: 'preload-assets-host', + plugins: [createResourceCapturePlugin(calls)], + }); +} + +function createRemoteInfo(type: RemoteInfo['type']): RemoteInfo { + return { + name: 'preload-assets-remote', + entry: 'https://remote.test/remoteEntry.js', + type, + entryGlobalName: 'preload_assets_remote', + shareScope: 'default', + }; +} + +async function runPreload({ + type, + cssAssets = [], + jsAssetsWithoutEntry = [], + useLinkPreload = false, + initiator = 'loadRemote', +}: { + type: RemoteInfo['type']; + cssAssets?: string[]; + jsAssetsWithoutEntry?: string[]; + useLinkPreload?: boolean; + initiator?: ResourceLoadInitiator; +}): Promise { + const calls = createResourceCalls(); + const host = createHost(calls); + + await preloadAssets( + createRemoteInfo(type), + host, + { + cssAssets, + jsAssetsWithoutEntry, + entryAssets: [], + }, + useLinkPreload, + { + initiator, + id: 'preload-assets-remote/Expose', + }, + ); + + return calls; +} + +describe('preloadAssets', () => { + it.each(['module', 'esm'] as const)( + 'preloads %s chunks without executing them during loadRemote', + async (type) => { + const moduleUrl = 'https://remote.test/expose.js'; + const calls = await runPreload({ + type, + jsAssetsWithoutEntry: [moduleUrl], + }); + + expect(calls.scripts).toHaveLength(0); + expect(calls.links).toHaveLength(1); + expect(calls.links[0]).toMatchObject({ + url: moduleUrl, + attrs: { + rel: 'modulepreload', + fetchpriority: 'high', + }, + remoteInfo: { + name: 'preload-assets-remote', + type, + }, + resourceContext: { + initiator: 'loadRemote', + id: 'preload-assets-remote/Expose', + resourceType: 'js', + url: moduleUrl, + }, + }); + }, + ); + + it('keeps module chunks non-executing through loadRemote initialization', async () => { + const remoteName = 'preload-assets-integration-remote'; + const moduleUrl = 'https://remote.test/expose.js'; + const calls = createResourceCalls(); + const lifecycle: string[] = []; + const remoteSnapshot: ModuleInfo = { + version: '1.0.0', + buildVersion: '', + remoteEntry: 'https://remote.test/remoteEntry.js', + remoteEntryType: 'module', + remoteTypes: '', + remoteTypesZip: '', + globalName: remoteName, + publicPath: 'https://remote.test/', + remotesInfo: {}, + shared: [], + modules: [], + }; + + const host = new ModuleFederation({ + name: 'preload-assets-integration-host', + remotes: [ + { + name: remoteName, + entry: 'https://remote.test/mf-manifest.json', + }, + ], + plugins: [ + createResourceCapturePlugin(calls), + { + name: 'capture-container-initialization', + loadEntry() { + return { + init() { + lifecycle.push('init'); + }, + get() { + lifecycle.push('get'); + return () => Promise.resolve('loaded'); + }, + }; + }, + }, + ], + }); + + rs.spyOn(host.snapshotHandler, 'loadRemoteSnapshotInfo').mockResolvedValue({ + remoteSnapshot, + globalSnapshot: {}, + }); + rs.spyOn( + host.remoteHandler.hooks.lifecycle.generatePreloadAssets, + 'emit', + ).mockResolvedValue({ + cssAssets: [], + jsAssetsWithoutEntry: [moduleUrl], + entryAssets: [], + }); + + await expect(host.loadRemote(`${remoteName}/Expose`)).resolves.toBe( + 'loaded', + ); + + expect(lifecycle).toEqual(['init', 'get']); + expect(calls.scripts).toHaveLength(0); + expect(calls.links).toHaveLength(1); + expect(calls.links[0]).toMatchObject({ + url: moduleUrl, + attrs: { + rel: 'modulepreload', + fetchpriority: 'high', + }, + remoteInfo: { + name: remoteName, + type: 'module', + }, + resourceContext: { + initiator: 'loadRemote', + id: `${remoteName}/Expose`, + resourceType: 'js', + url: moduleUrl, + }, + }); + }); + + it('keeps executing classic chunks during loadRemote', async () => { + const scriptUrl = 'https://remote.test/expose.js'; + const calls = await runPreload({ + type: 'global', + jsAssetsWithoutEntry: [scriptUrl], + }); + + expect(calls.links).toHaveLength(0); + expect(calls.scripts).toHaveLength(1); + expect(calls.scripts[0]).toMatchObject({ + url: scriptUrl, + attrs: { + fetchpriority: 'high', + type: 'text/javascript', + }, + resourceContext: { + initiator: 'loadRemote', + id: 'preload-assets-remote/Expose', + resourceType: 'js', + url: scriptUrl, + }, + }); + }); + + it('keeps applying stylesheets during loadRemote', async () => { + const stylesheetUrl = 'https://remote.test/expose.css'; + const calls = await runPreload({ + type: 'module', + cssAssets: [stylesheetUrl], + }); + + expect(calls.scripts).toHaveLength(0); + expect(calls.links).toHaveLength(1); + expect(calls.links[0]).toMatchObject({ + url: stylesheetUrl, + attrs: { + rel: 'stylesheet', + type: 'text/css', + }, + resourceContext: { + initiator: 'loadRemote', + id: 'preload-assets-remote/Expose', + resourceType: 'css', + url: stylesheetUrl, + }, + }); + + const attachedStylesheet = Array.from( + document.head.querySelectorAll('link'), + ).find((link) => link.href === stylesheetUrl); + expect(attachedStylesheet).toBeDefined(); + attachedStylesheet?.remove(); + }); + + it('keeps explicit preloadRemote chunks as preload links', async () => { + const scriptUrl = 'https://remote.test/expose.js'; + const calls = await runPreload({ + type: 'module', + jsAssetsWithoutEntry: [scriptUrl], + useLinkPreload: true, + initiator: 'preloadRemote', + }); + + expect(calls.scripts).toHaveLength(0); + expect(calls.links).toHaveLength(1); + expect(calls.links[0]).toMatchObject({ + url: scriptUrl, + attrs: { + rel: 'preload', + as: 'script', + }, + resourceContext: { + initiator: 'preloadRemote', + id: 'preload-assets-remote/Expose', + resourceType: 'js', + url: scriptUrl, + }, + }); + }); +}); diff --git a/packages/runtime-core/src/utils/load.ts b/packages/runtime-core/src/utils/load.ts index 9452f82736e..7bcc7c3ded6 100644 --- a/packages/runtime-core/src/utils/load.ts +++ b/packages/runtime-core/src/utils/load.ts @@ -24,6 +24,10 @@ import { declare const ENV_TARGET: 'web' | 'node'; const importCallback = '.then(callbacks[0]).catch(callbacks[1])'; +export function isEsmRemoteType(type: RemoteInfo['type']): boolean { + return type === 'esm' || type === 'module'; +} + async function loadEsmEntry({ entry, remoteEntryExports, @@ -200,23 +204,23 @@ async function loadEntryDom({ resourceContext?: ResourceLoadContext; }) { const { entry, entryGlobalName: globalName, name, type } = remoteInfo; - switch (type) { - case 'esm': - case 'module': - return loadEsmEntry({ entry, remoteEntryExports }); - case 'system': - return loadSystemJsEntry({ entry, remoteEntryExports }); - default: - return loadEntryScript({ - entry, - globalName, - name, - remoteInfo, - loaderHook, - getEntryUrl, - resourceContext, - }); + if (isEsmRemoteType(type)) { + return loadEsmEntry({ entry, remoteEntryExports }); + } + + if (type === 'system') { + return loadSystemJsEntry({ entry, remoteEntryExports }); } + + return loadEntryScript({ + entry, + globalName, + name, + remoteInfo, + loaderHook, + getEntryUrl, + resourceContext, + }); } async function loadEntryNode({ diff --git a/packages/runtime-core/src/utils/preload.ts b/packages/runtime-core/src/utils/preload.ts index 9deb9810339..f7be6f117ad 100644 --- a/packages/runtime-core/src/utils/preload.ts +++ b/packages/runtime-core/src/utils/preload.ts @@ -14,7 +14,7 @@ import { import { matchRemote } from './manifest'; import { assert } from './logger'; import { ModuleFederation } from '../core'; -import { getRemoteEntry } from './load'; +import { getRemoteEntry, isEsmRemoteType } from './load'; export function defaultPreloadArgs( preloadConfig: PreloadRemoteArgs | depsPreloadArg, @@ -307,39 +307,37 @@ export function preloadAssets( }); } + let preloadJsAsset = waitForScriptPreload; + let defaultAttrs: Record = { + fetchpriority: 'high', + type: 'text/javascript', + }; + if (useLinkPreload) { - const defaultAttrs = { + preloadJsAsset = waitForLinkPreload; + defaultAttrs = { rel: 'preload', as: 'script', }; - jsAssetsWithoutEntry.forEach((jsUrl) => { - results.push( - waitForLinkPreload({ - host, - remoteInfo, - url: jsUrl, - attrs: defaultAttrs, - context: createResourceContext(baseContext, 'js'), - }), - ); - }); - } else { - const defaultAttrs = { + } else if (isEsmRemoteType(remoteInfo.type)) { + preloadJsAsset = waitForLinkPreload; + defaultAttrs = { + rel: 'modulepreload', fetchpriority: 'high', - type: remoteInfo?.type === 'module' ? 'module' : 'text/javascript', }; - jsAssetsWithoutEntry.forEach((jsUrl) => { - results.push( - waitForScriptPreload({ - host, - remoteInfo, - url: jsUrl, - attrs: defaultAttrs, - context: createResourceContext(baseContext, 'js'), - }), - ); - }); } + + jsAssetsWithoutEntry.forEach((jsUrl) => { + results.push( + preloadJsAsset({ + host, + remoteInfo, + url: jsUrl, + attrs: defaultAttrs, + context: createResourceContext(baseContext, 'js'), + }), + ); + }); } return Promise.all(results); From 727b05dbe9ef1a11c0621adffe1e77be07ebb53a Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Wed, 15 Jul 2026 23:39:17 +0000 Subject: [PATCH 28/37] ci(e2e): gate affected workflows before runner setup (#4864) Co-authored-by: ScriptedAlchemy --- .github/workflows/build-and-test.yml | 19 + .github/workflows/e2e-manifest.yml | 18 +- .github/workflows/e2e-metro.yml | 46 -- .github/workflows/e2e-modern-ssr.yml | 15 - .github/workflows/e2e-modern.yml | 17 +- .github/workflows/e2e-next-dev.yml | 15 - .github/workflows/e2e-next-prod.yml | 15 - .github/workflows/e2e-node.yml | 17 +- .github/workflows/e2e-router.yml | 17 +- .github/workflows/e2e-runtime.yml | 17 +- .github/workflows/e2e-treeshake.yml | 16 - tools/scripts/ci-e2e-affected.mjs | 241 +++++++++ tools/scripts/ci-e2e-suites.mjs | 137 ++++++ tools/scripts/ci-is-affected.mjs | 295 +++++------ tools/scripts/ci-is-affected.test.mjs | 285 +++++++++++ tools/scripts/ci-local-cli.mjs | 297 +++++++++++ tools/scripts/ci-local-e2e.mjs | 100 ++++ tools/scripts/ci-local.mjs | 682 +++++++------------------- 18 files changed, 1370 insertions(+), 879 deletions(-) create mode 100644 tools/scripts/ci-e2e-affected.mjs create mode 100644 tools/scripts/ci-e2e-suites.mjs create mode 100644 tools/scripts/ci-is-affected.test.mjs create mode 100644 tools/scripts/ci-local-cli.mjs create mode 100644 tools/scripts/ci-local-e2e.mjs diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index cc3fd4d5a23..a0793b07b2a 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -18,6 +18,8 @@ jobs: checkout-install: runs-on: ubuntu-latest timeout-minutes: 30 + outputs: + e2e_suites: ${{ steps.e2e-affected.outputs.e2e_suites }} steps: - name: Checkout Repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 @@ -37,6 +39,10 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Evaluate E2E affected suites + id: e2e-affected + run: node tools/scripts/ci-is-affected.mjs --githubOutputAll=e2e_suites + - name: Restore Turborepo cache id: turbo-cache uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 @@ -53,6 +59,9 @@ jobs: - name: Check code format run: node tools/scripts/check-format-changed.mjs + - name: Test CI affected policy + run: node --test tools/scripts/ci-is-affected.test.mjs + - name: Verify Rslib Template Publint Wiring run: node packages/create-module-federation/scripts/verify-rslib-templates.mjs @@ -107,6 +116,7 @@ jobs: e2e-modern: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).modern }} uses: ./.github/workflows/e2e-modern.yml secrets: inherit @@ -135,47 +145,56 @@ jobs: e2e-runtime: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).runtime }} uses: ./.github/workflows/e2e-runtime.yml secrets: inherit e2e-manifest: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).manifest }} uses: ./.github/workflows/e2e-manifest.yml secrets: inherit e2e-node: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).node }} uses: ./.github/workflows/e2e-node.yml secrets: inherit e2e-next-dev: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).next }} uses: ./.github/workflows/e2e-next-dev.yml secrets: inherit e2e-next-prod: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).next }} uses: ./.github/workflows/e2e-next-prod.yml secrets: inherit e2e-treeshake: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).treeshake }} uses: ./.github/workflows/e2e-treeshake.yml secrets: inherit e2e-modern-ssr: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).modernSsr }} uses: ./.github/workflows/e2e-modern-ssr.yml secrets: inherit e2e-router: needs: checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).router }} uses: ./.github/workflows/e2e-router.yml secrets: inherit e2e-metro: needs: - checkout-install + if: ${{ fromJSON(needs.checkout-install.outputs.e2e_suites).metro }} uses: ./.github/workflows/e2e-metro.yml secrets: inherit diff --git a/.github/workflows/e2e-manifest.yml b/.github/workflows/e2e-manifest.yml index ab9a3700fc1..f3796437556 100644 --- a/.github/workflows/e2e-manifest.yml +++ b/.github/workflows/e2e-manifest.yml @@ -1,4 +1,4 @@ -# .github/workflows/e2e-webpack-host.yml +# .github/workflows/e2e-manifest.yml name: E2E Test for Manifest on: @@ -45,24 +45,8 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=3008-webpack-host,3009-webpack-provider,3010-rspack-provider,3011-rspack-manifest-provider,3012-rspack-js-entry-provider || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Test for Manifest Demo (dev) - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run test:e2e --filter=3008-webpack-host - name: E2E Test for Manifest Demo (prod) - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run test:e2e:production --filter=3008-webpack-host diff --git a/.github/workflows/e2e-metro.yml b/.github/workflows/e2e-metro.yml index a9889a981c4..01b33b19692 100644 --- a/.github/workflows/e2e-metro.yml +++ b/.github/workflows/e2e-metro.yml @@ -15,51 +15,7 @@ env: METRO_APP_NAME: example-host jobs: - e2e-metro-check-affected: - runs-on: ubuntu-latest - timeout-minutes: 30 - outputs: - should_run_e2e: ${{ steps.affected.outputs.should-run-e2e }} - steps: - - name: Check out repository - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 - with: - fetch-depth: 0 - - - name: Set up pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 - - - name: Set up Node.js 24 - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 - with: - node-version: '24' - cache: 'pnpm' - cache-dependency-path: '**/pnpm-lock.yaml' - - - name: Export SKIP_DEVTOOLS_POSTINSTALL - run: echo "SKIP_DEVTOOLS_POSTINSTALL=true" >> "$GITHUB_ENV" - shell: bash - - - name: Install pnpm dependencies - run: pnpm install --frozen-lockfile - - - name: Evaluate Metro affected scope - id: affected - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=${{ env.METRO_APP_NAME }} || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "should-run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "should-run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - e2e-metro-android: - needs: e2e-metro-check-affected - if: needs.e2e-metro-check-affected.outputs.should_run_e2e == 'true' runs-on: ubuntu-latest timeout-minutes: 60 env: @@ -170,8 +126,6 @@ jobs: path: ~/.maestro/tests/ e2e-metro-ios: - needs: e2e-metro-check-affected - if: needs.e2e-metro-check-affected.outputs.should_run_e2e == 'true' # Xcode 26.5 fails to compile React Native 0.80's fmt pod for the simulator. runs-on: macos-15 timeout-minutes: 60 diff --git a/.github/workflows/e2e-modern-ssr.yml b/.github/workflows/e2e-modern-ssr.yml index fcd3f8585ff..247957a4e54 100644 --- a/.github/workflows/e2e-modern-ssr.yml +++ b/.github/workflows/e2e-modern-ssr.yml @@ -44,20 +44,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=@module-federation/modern-js,@module-federation/modern-js-v3,modernjs-ssr-host,modernjs-ssr-remote,modernjs-ssr-remote-new-version,modernjs-ssr-nested-remote,modernjs-ssr-dynamic-remote,modernjs-ssr-dynamic-remote-new-version,modernjs-ssr-dynamic-nested-remote,modernjs-ssr-data-fetch-host,modernjs-ssr-data-fetch-provider,modernjs-ssr-data-fetch-provider-csr || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: Manifest verification for ModernJS SSR - if: steps.check-ci.outputs.run-e2e == 'true' run: node tools/scripts/run-modern-e2e.mjs --mode=manifest diff --git a/.github/workflows/e2e-modern.yml b/.github/workflows/e2e-modern.yml index 7a6eb362649..b5cd1b15301 100644 --- a/.github/workflows/e2e-modern.yml +++ b/.github/workflows/e2e-modern.yml @@ -1,4 +1,4 @@ -# .github/workflows/e2e-modernjs.yml +# .github/workflows/e2e-modern.yml name: E2E Test for ModernJS on: @@ -45,20 +45,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=@module-federation/modern-js,@module-federation/modern-js-v3 || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: Run Modern package test suite - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run test --filter=@module-federation/modern-js --filter=@module-federation/modern-js-v3 --concurrency=20 diff --git a/.github/workflows/e2e-next-dev.yml b/.github/workflows/e2e-next-dev.yml index b9dfb53649e..0a2df603814 100644 --- a/.github/workflows/e2e-next-dev.yml +++ b/.github/workflows/e2e-next-dev.yml @@ -46,20 +46,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=@module-federation/3000-home,@module-federation/3001-shop,@module-federation/3002-checkout || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Test for Next.js Dev - if: steps.check-ci.outputs.run-e2e == 'true' run: node tools/scripts/run-next-e2e.mjs --mode=dev diff --git a/.github/workflows/e2e-next-prod.yml b/.github/workflows/e2e-next-prod.yml index 8a4b84df4e7..2b8f6fcdce8 100644 --- a/.github/workflows/e2e-next-prod.yml +++ b/.github/workflows/e2e-next-prod.yml @@ -44,20 +44,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=@module-federation/3000-home,@module-federation/3001-shop,@module-federation/3002-checkout || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Test for Next.js Prod - if: steps.check-ci.outputs.run-e2e == 'true' run: node tools/scripts/run-next-e2e.mjs --mode=prod diff --git a/.github/workflows/e2e-node.yml b/.github/workflows/e2e-node.yml index d297dced820..0e3843d7f09 100644 --- a/.github/workflows/e2e-node.yml +++ b/.github/workflows/e2e-node.yml @@ -1,4 +1,4 @@ -# .github/workflows/e2e-node-federation.yml +# .github/workflows/e2e-node.yml name: E2E Node Federation on: @@ -45,20 +45,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=node-host,node-local-remote,node-remote,node-dynamic-remote-new-version,node-dynamic-remote,node-host-e2e || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Node Federation - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm run e2e:node diff --git a/.github/workflows/e2e-router.yml b/.github/workflows/e2e-router.yml index 1a698daf00b..c0f22539465 100644 --- a/.github/workflows/e2e-router.yml +++ b/.github/workflows/e2e-router.yml @@ -1,4 +1,4 @@ -# .github/workflows/e2e-router-host-2000.yml +# .github/workflows/e2e-router.yml name: E2E Test for Router on: @@ -45,20 +45,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=host,host-v5,host-vue3,remote1,remote2,remote3,remote4,remote5,remote6 || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Test for Router - if: steps.check-ci.outputs.run-e2e == 'true' run: node tools/scripts/run-router-e2e.mjs --mode=dev diff --git a/.github/workflows/e2e-runtime.yml b/.github/workflows/e2e-runtime.yml index 31711737124..4bab493185d 100644 --- a/.github/workflows/e2e-runtime.yml +++ b/.github/workflows/e2e-runtime.yml @@ -1,4 +1,4 @@ -# .github/workflows/e2e-runtime-host.yml +# .github/workflows/e2e-runtime.yml name: E2E Test for Runtime on: @@ -45,20 +45,5 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=runtime-host,runtime-remote1,runtime-remote2 || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Test for Runtime Demo - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run test:e2e --filter=runtime-host diff --git a/.github/workflows/e2e-treeshake.yml b/.github/workflows/e2e-treeshake.yml index 3360fcb543f..17b3b653bc6 100644 --- a/.github/workflows/e2e-treeshake.yml +++ b/.github/workflows/e2e-treeshake.yml @@ -44,24 +44,8 @@ jobs: - name: Build shared packages run: pnpm run build:packages - - name: Check CI conditions - id: check-ci - run: | - ci_status=0 - node tools/scripts/ci-is-affected.mjs --appName=@module-federation/treeshake-server,@module-federation/treeshake-frontend || ci_status=$? - if [ "$ci_status" -eq 0 ]; then - echo "run-e2e=true" >> "$GITHUB_OUTPUT" - elif [ "$ci_status" -eq 1 ]; then - echo "run-e2e=false" >> "$GITHUB_OUTPUT" - else - echo "ci-is-affected failed with unexpected exit code: $ci_status" >&2 - exit "$ci_status" - fi - - name: E2E Treeshake Server - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run test --filter=@module-federation/treeshake-server --only - name: E2E Treeshake Frontend - if: steps.check-ci.outputs.run-e2e == 'true' run: pnpm exec turbo run e2e --filter=@module-federation/treeshake-frontend --only diff --git a/tools/scripts/ci-e2e-affected.mjs b/tools/scripts/ci-e2e-affected.mjs new file mode 100644 index 00000000000..d855b8ae710 --- /dev/null +++ b/tools/scripts/ci-e2e-affected.mjs @@ -0,0 +1,241 @@ +import { + E2E_SUITE_DEFINITIONS, + E2E_SUITES, + normalizeAppNames, +} from './ci-e2e-suites.mjs'; +import { parseJsonFromTurboOutput } from './turbo-script-utils.mjs'; + +const GLOBAL_E2E_INPUTS = new Set([ + '.github/workflows/build-and-test.yml', + 'package.json', + 'pnpm-lock.yaml', + 'pnpm-workspace.yaml', + 'turbo.json', + 'tools/scripts/ci-e2e-affected.mjs', + 'tools/scripts/ci-e2e-suites.mjs', + 'tools/scripts/ci-is-affected.mjs', + 'tools/scripts/e2e-process-utils.mjs', + 'tools/scripts/turbo-script-utils.mjs', + 'scripts/ensure-playwright.js', +]); + +export function computeE2ESuiteDecisions({ + affectedPackageNames, + changedFiles, +}) { + const runAll = changedFiles.some(isGlobalE2EInput); + const matchableAffectedNames = + createMatchablePackageNames(affectedPackageNames); + + return Object.fromEntries( + Object.entries(E2E_SUITES).map(([suiteName, appNames]) => [ + suiteName, + runAll || + changedFiles.some((file) => isE2ESuiteInput(suiteName, file)) || + normalizeAppNames(appNames).some((name) => + matchableAffectedNames.has(name), + ), + ]), + ); +} + +export function isAppNameAffected(appNames, affectedPackageNames) { + const matchableAffectedNames = + createMatchablePackageNames(affectedPackageNames); + return normalizeAppNames(appNames).some((name) => + matchableAffectedNames.has(name), + ); +} + +export function isGlobalE2EInput(relativePath) { + return GLOBAL_E2E_INPUTS.has(relativePath); +} + +export function isE2ESuiteInput(suiteName, relativePath) { + return ( + E2E_SUITE_DEFINITIONS[suiteName]?.inputs.includes(relativePath) ?? false + ); +} + +export function parseAffectedPackages(outputText) { + const payload = parseJsonFromTurboOutput(outputText); + const packageNames = new Set(); + + if (Array.isArray(payload)) { + collectPackageNamesFromList(payload, packageNames); + return packageNames; + } + + if (!payload || typeof payload !== 'object') { + throw new Error('Turbo affected output has an unsupported schema.'); + } + + let recognizedSchema = false; + + if ('items' in payload) { + if (!Array.isArray(payload.items)) { + throw new Error('Turbo affected output has an invalid items field.'); + } + recognizedSchema = true; + collectPackageNamesFromList(payload.items, packageNames); + } + + if ('packages' in payload) { + if ( + !payload.packages || + (typeof payload.packages !== 'object' && !Array.isArray(payload.packages)) + ) { + throw new Error('Turbo affected output has an invalid packages field.'); + } + recognizedSchema = true; + collectPackageNamesFromContainer(payload.packages, packageNames); + } + + if (typeof payload.name === 'string') { + recognizedSchema = true; + addPackageName(payload.name, packageNames); + } + + if (!recognizedSchema) { + throw new Error('Turbo affected output has an unsupported schema.'); + } + + return packageNames; +} + +function createMatchablePackageNames(packageNames) { + const matchableNames = new Set(); + for (const packageName of packageNames) { + matchableNames.add(packageName); + const unscoped = toUnscopedName(packageName); + if (unscoped) { + matchableNames.add(unscoped); + } + } + return matchableNames; +} + +function collectPackageNamesFromContainer(container, packageNames) { + if (!container) { + return; + } + + if (Array.isArray(container)) { + collectPackageNamesFromList(container, packageNames); + return; + } + + if (typeof container !== 'object') { + throw new Error('Turbo affected output has an invalid package container.'); + } + + let recognizedSchema = Object.keys(container).length === 0; + + if (typeof container.name === 'string') { + recognizedSchema = true; + addPackageName(container.name, packageNames); + } + + if ('items' in container) { + if (!Array.isArray(container.items)) { + throw new Error('Turbo affected output has an invalid items field.'); + } + recognizedSchema = true; + collectPackageNamesFromList(container.items, packageNames); + } + + if ('packages' in container) { + if ( + !container.packages || + (typeof container.packages !== 'object' && + !Array.isArray(container.packages)) + ) { + throw new Error('Turbo affected output has an invalid packages field.'); + } + recognizedSchema = true; + collectPackageNamesFromContainer(container.packages, packageNames); + } + + for (const [key, value] of Object.entries(container)) { + const valueLooksLikePackageEntry = + value && + typeof value === 'object' && + !Array.isArray(value) && + ('path' in value || 'name' in value || 'package' in value); + + if (valueLooksLikePackageEntry && isPackageNameCandidate(key)) { + recognizedSchema = true; + packageNames.add(key); + } + if (value && typeof value === 'object' && typeof value.name === 'string') { + recognizedSchema = true; + addPackageName(value.name, packageNames); + } + } + + if (!recognizedSchema) { + throw new Error('Turbo affected output has an unsupported package schema.'); + } +} + +function collectPackageNamesFromList(list, packageNames) { + for (const entry of list) { + if (typeof entry === 'string') { + addPackageName(entry, packageNames); + continue; + } + if (!entry || typeof entry !== 'object') { + throw new Error( + 'Turbo affected output has an unsupported package entry.', + ); + } + + if (typeof entry.name === 'string') { + addPackageName(entry.name, packageNames); + continue; + } + + if (typeof entry.package === 'string') { + addPackageName(entry.package, packageNames); + continue; + } + + if (Array.isArray(entry.items)) { + collectPackageNamesFromList(entry.items, packageNames); + continue; + } + + throw new Error('Turbo affected output has an unsupported package entry.'); + } +} + +function addPackageName(name, packageNames) { + if (!isPackageNameCandidate(name)) { + throw new Error(`Turbo affected output contains an invalid package name.`); + } + packageNames.add(name); +} + +function isPackageNameCandidate(value) { + if (typeof value !== 'string') { + return false; + } + if (!value || value === '//') { + return false; + } + if (value.includes('#') || value.includes('\\') || value.includes(' ')) { + return false; + } + if (value.startsWith('@')) { + return /^@[^/]+\/[^/]+$/.test(value); + } + return !value.includes('/'); +} + +function toUnscopedName(value) { + if (typeof value !== 'string' || !value.startsWith('@')) { + return null; + } + const [, unscoped] = value.split('/'); + return unscoped || null; +} diff --git a/tools/scripts/ci-e2e-suites.mjs b/tools/scripts/ci-e2e-suites.mjs new file mode 100644 index 00000000000..8edbe57367e --- /dev/null +++ b/tools/scripts/ci-e2e-suites.mjs @@ -0,0 +1,137 @@ +export const E2E_SUITE_DEFINITIONS = { + manifest: { + appNames: [ + '3008-webpack-host', + '3009-webpack-provider', + '3010-rspack-provider', + '3011-rspack-manifest-provider', + '3012-rspack-js-entry-provider', + ], + inputs: [ + '.github/workflows/e2e-manifest.yml', + 'tools/scripts/run-manifest-e2e.mjs', + ], + }, + metro: { + appNames: ['example-host'], + inputs: [ + '.github/workflows/e2e-metro.yml', + 'tools/scripts/run-metro-e2e.mjs', + ], + }, + modern: { + appNames: [ + '@module-federation/modern-js', + '@module-federation/modern-js-v3', + ], + inputs: ['.github/workflows/e2e-modern.yml'], + }, + modernSsr: { + appNames: [ + '@module-federation/modern-js', + '@module-federation/modern-js-v3', + 'modernjs-ssr-host', + 'modernjs-ssr-remote', + 'modernjs-ssr-remote-new-version', + 'modernjs-ssr-nested-remote', + 'modernjs-ssr-dynamic-remote', + 'modernjs-ssr-dynamic-remote-new-version', + 'modernjs-ssr-dynamic-nested-remote', + 'modernjs-ssr-data-fetch-host', + 'modernjs-ssr-data-fetch-provider', + 'modernjs-ssr-data-fetch-provider-csr', + ], + inputs: [ + '.github/workflows/e2e-modern-ssr.yml', + 'tools/scripts/run-modern-e2e.mjs', + ], + }, + next: { + appNames: [ + '@module-federation/3000-home', + '@module-federation/3001-shop', + '@module-federation/3002-checkout', + ], + inputs: [ + '.github/workflows/e2e-next-dev.yml', + '.github/workflows/e2e-next-prod.yml', + 'tools/scripts/run-next-e2e.mjs', + ], + }, + node: { + appNames: [ + 'node-host', + 'node-local-remote', + 'node-remote', + 'node-dynamic-remote-new-version', + 'node-dynamic-remote', + 'node-host-e2e', + ], + inputs: [ + '.github/workflows/e2e-node.yml', + 'tools/scripts/run-node-e2e.mjs', + ], + }, + router: { + appNames: [ + 'host', + 'host-v5', + 'host-vue3', + 'remote1', + 'remote2', + 'remote3', + 'remote4', + 'remote5', + 'remote6', + ], + inputs: [ + '.github/workflows/e2e-router.yml', + 'tools/scripts/run-router-e2e.mjs', + ], + }, + runtime: { + appNames: ['runtime-host', 'runtime-remote1', 'runtime-remote2'], + inputs: [ + '.github/workflows/e2e-runtime.yml', + 'tools/scripts/run-runtime-e2e.mjs', + ], + }, + sharedTreeShaking: { + appNames: [ + 'shared-tree-shaking-no-server-host', + 'shared-tree-shaking-no-server-provider', + 'shared-tree-shaking-with-server-host', + 'shared-tree-shaking-with-server-provider', + ], + inputs: ['.github/workflows/e2e-shared-tree-shaking.yml'], + parentWorkflow: false, + }, + treeshake: { + appNames: [ + '@module-federation/treeshake-server', + '@module-federation/treeshake-frontend', + ], + inputs: ['.github/workflows/e2e-treeshake.yml'], + }, +}; + +export const E2E_SUITES = Object.fromEntries( + Object.entries(E2E_SUITE_DEFINITIONS).map(([suiteName, definition]) => [ + suiteName, + definition.appNames, + ]), +); + +export function normalizeAppNames(appNames) { + if (Array.isArray(appNames)) { + return appNames.map((name) => name.trim()).filter(Boolean); + } + return (appNames ?? '') + .split(',') + .map((name) => name.trim()) + .filter(Boolean); +} + +export function serializeAppNames(appNames) { + return normalizeAppNames(appNames).join(','); +} diff --git a/tools/scripts/ci-is-affected.mjs b/tools/scripts/ci-is-affected.mjs index 595aa8b7a95..232ced2548d 100644 --- a/tools/scripts/ci-is-affected.mjs +++ b/tools/scripts/ci-is-affected.mjs @@ -1,32 +1,34 @@ import { spawnSync } from 'node:child_process'; +import { appendFileSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import yargs from 'yargs'; +import { hasGitRef as hasGitRefInRepo } from './turbo-script-utils.mjs'; import { - hasGitRef as hasGitRefInRepo, - parseJsonFromTurboOutput, -} from './turbo-script-utils.mjs'; + computeE2ESuiteDecisions, + isAppNameAffected, + isE2ESuiteInput, + isGlobalE2EInput, + parseAffectedPackages, +} from './ci-e2e-affected.mjs'; +import { + E2E_SUITES, + normalizeAppNames, + serializeAppNames, +} from './ci-e2e-suites.mjs'; const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)); const ROOT = resolve(SCRIPT_DIR, '../..'); -const GLOBAL_E2E_INPUT_PATTERNS = [ - 'package.json', - 'tools/scripts/ci-is-affected.mjs', - 'tools/scripts/e2e-process-utils.mjs', - 'tools/scripts/run-manifest-e2e.mjs', - 'tools/scripts/run-modern-e2e.mjs', - 'tools/scripts/run-metro-e2e.mjs', - 'tools/scripts/run-next-e2e.mjs', - 'tools/scripts/run-node-e2e.mjs', - 'tools/scripts/run-router-e2e.mjs', - 'tools/scripts/run-runtime-e2e.mjs', - 'scripts/ensure-playwright.js', -]; - const argv = yargs(process.argv.slice(2)) .option('appName', { type: 'string', - demandOption: true, + describe: + 'Comma-separated package/app names. Prefer --e2eSuite for built-in e2e suites.', + }) + .option('e2eSuite', { + type: 'string', + describe: + 'Named e2e suite from tools/scripts/ci-e2e-suites.mjs. Used to keep workflows and ci-local aligned.', }) .option('base', { type: 'string', @@ -34,17 +36,78 @@ const argv = yargs(process.argv.slice(2)) .option('head', { type: 'string', }) + .option('githubOutput', { + type: 'string', + describe: + 'Write the decision to $GITHUB_OUTPUT under this key (as true/false) and exit 0, instead of signaling via exit code.', + }) + .option('githubOutputAll', { + type: 'string', + describe: + 'Write all named suite decisions as one JSON object to $GITHUB_OUTPUT under this key.', + }) .strict(false) .parseSync(); -const appNames = argv.appName - .split(',') - .map((name) => name.trim()) - .filter(Boolean); +// Decision exits: without --githubOutput, exit 0 means "run e2e" and exit 1 +// means "skip" (consumed by ci-local.mjs and shell-translated workflow +// steps). With --githubOutput, the decision is written to $GITHUB_OUTPUT and +// the process exits 0 either way, so genuine crashes (nonzero without +// output) fail the workflow step instead of silently skipping e2e. +function decide(runE2E) { + if (argv.githubOutput) { + if (!process.env.GITHUB_OUTPUT) { + console.error('--githubOutput was passed but GITHUB_OUTPUT is not set.'); + process.exit(2); + } + appendFileSync( + process.env.GITHUB_OUTPUT, + `${argv.githubOutput}=${runE2E ? 'true' : 'false'}\n`, + ); + process.exit(0); + } + process.exit(runE2E ? 0 : 1); +} + +function decideAll(decisions) { + if (!argv.githubOutputAll) { + console.error('--githubOutputAll requires an output key.'); + process.exit(2); + } + if (!process.env.GITHUB_OUTPUT) { + console.error('--githubOutputAll was passed but GITHUB_OUTPUT is not set.'); + process.exit(2); + } + appendFileSync( + process.env.GITHUB_OUTPUT, + `${argv.githubOutputAll}=${JSON.stringify(decisions)}\n`, + ); + process.exit(0); +} + +const allSuitesMode = Boolean(argv.githubOutputAll); +if (allSuitesMode && (argv.appName || argv.e2eSuite || argv.githubOutput)) { + console.error( + '--githubOutputAll cannot be combined with --appName, --e2eSuite, or --githubOutput.', + ); + process.exit(2); +} + +const rawAppNames = allSuitesMode + ? [] + : argv.appName + ? normalizeAppNames(argv.appName) + : (E2E_SUITES[argv.e2eSuite] ?? null); +if (argv.e2eSuite && !rawAppNames) { + console.error(`Unknown e2e suite: ${argv.e2eSuite}`); + process.exit(2); +} + +const appNames = normalizeAppNames(rawAppNames); -if (appNames.length === 0) { - console.log('No valid app names were provided.'); - process.exit(1); +if (!allSuitesMode && appNames.length === 0) { + console.error('No valid app names were provided.'); + process.exit(2); } const base = resolveBase(argv.base); @@ -54,14 +117,14 @@ if (!base || !head) { console.warn( `Unable to resolve a valid base/head commit (base=${base}, head=${head}). Running e2e by default.`, ); - process.exit(0); + decideFailOpen(); } if (base === head) { console.warn( `Resolved base and head are identical (${base}). Running e2e by default.`, ); - process.exit(0); + decideFailOpen(); } const changedFiles = listChangedFiles(base, head); @@ -70,7 +133,7 @@ if (!changedFiles) { console.warn( `Unable to resolve changed files for base=${base} head=${head}. Running e2e by default.`, ); - process.exit(0); + decideFailOpen(); } const changedGlobalE2EInputs = changedFiles.filter(isGlobalE2EInput); @@ -79,7 +142,7 @@ if (changedGlobalE2EInputs.length > 0) { console.log( `Detected shared e2e harness changes (${changedGlobalE2EInputs.join(', ')}). Running e2e CI.`, ); - process.exit(0); + decideFailOpen(); } const turboResult = spawnSync( @@ -107,7 +170,7 @@ if (turboResult.status !== 0) { } else if (turboResult.stdout?.trim()) { console.warn(turboResult.stdout.trim()); } - process.exit(0); + decideFailOpen(); } let affectedPackageNames; @@ -122,32 +185,44 @@ try { console.warn( `Unable to parse Turbo affected output for base=${base} head=${head}. Running e2e by default.`, ); - process.exit(0); + decideFailOpen(); } } -const matchableAffectedNames = new Set(); -for (const packageName of affectedPackageNames) { - matchableAffectedNames.add(packageName); - const unscoped = toUnscopedName(packageName); - if (unscoped) { - matchableAffectedNames.add(unscoped); - } +if (allSuitesMode) { + const decisions = computeE2ESuiteDecisions({ + affectedPackageNames, + changedFiles, + }); + console.log(`E2E suite decisions: ${JSON.stringify(decisions)}`); + decideAll(decisions); } -const isAffected = appNames.some((name) => matchableAffectedNames.has(name)); +const isAffected = + (argv.e2eSuite && + changedFiles.some((file) => isE2ESuiteInput(argv.e2eSuite, file))) || + isAppNameAffected(appNames, affectedPackageNames); if (isAffected) { console.log( - `appNames: ${appNames.join(',')} , base=${base} head=${head}, conditions met, executing e2e CI.`, + `appNames: ${serializeAppNames(appNames)} , base=${base} head=${head}, conditions met, executing e2e CI.`, ); - process.exit(0); + decide(true); } console.log( - `appNames: ${appNames.join(',')} , base=${base} head=${head}, conditions not met, skipping e2e CI.`, + `appNames: ${serializeAppNames(appNames)} , base=${base} head=${head}, conditions not met, skipping e2e CI.`, ); -process.exit(1); +decide(false); + +function decideFailOpen() { + if (allSuitesMode) { + decideAll( + Object.fromEntries(Object.keys(E2E_SUITES).map((suite) => [suite, true])), + ); + } + decide(true); +} function hasGitRef(ref) { return hasGitRefInRepo(ROOT, ref); @@ -212,14 +287,6 @@ function listChangedFiles(baseRef, headRef) { .filter(Boolean); } -function isGlobalE2EInput(relativePath) { - return GLOBAL_E2E_INPUT_PATTERNS.some( - (pattern) => - relativePath === pattern || - (pattern.endsWith('/') && relativePath.startsWith(pattern)), - ); -} - function expandRefCandidates(ref) { if (!ref || !ref.trim()) { return []; @@ -245,129 +312,3 @@ function expandRefCandidates(ref) { return Array.from(candidates); } - -function parseAffectedPackages(outputText) { - const payload = parseJsonFromTurboOutput(outputText); - const packageNames = new Set(); - - if (Array.isArray(payload)) { - collectPackageNamesFromList(payload, packageNames); - return packageNames; - } - - if (!payload || typeof payload !== 'object') { - return packageNames; - } - - if (Array.isArray(payload.items)) { - collectPackageNamesFromList(payload.items, packageNames); - } - - if ('packages' in payload) { - collectPackageNamesFromContainer(payload.packages, packageNames); - } - - if (packageNames.size === 0 && typeof payload.name === 'string') { - addPackageName(payload.name, packageNames); - } - - return packageNames; -} - -function collectPackageNamesFromContainer(container, packageNames) { - if (!container) { - return; - } - - if (Array.isArray(container)) { - collectPackageNamesFromList(container, packageNames); - return; - } - - if (typeof container !== 'object') { - return; - } - - if (typeof container.name === 'string') { - addPackageName(container.name, packageNames); - } - - if (Array.isArray(container.items)) { - collectPackageNamesFromList(container.items, packageNames); - } - - if (Array.isArray(container.packages)) { - collectPackageNamesFromList(container.packages, packageNames); - } - - for (const [key, value] of Object.entries(container)) { - const valueLooksLikePackageEntry = - value && - typeof value === 'object' && - !Array.isArray(value) && - ('path' in value || 'name' in value || 'package' in value); - - if (valueLooksLikePackageEntry && isPackageNameCandidate(key)) { - packageNames.add(key); - } - if (value && typeof value === 'object' && typeof value.name === 'string') { - addPackageName(value.name, packageNames); - } - } -} - -function collectPackageNamesFromList(list, packageNames) { - for (const entry of list) { - if (typeof entry === 'string') { - addPackageName(entry, packageNames); - continue; - } - if (!entry || typeof entry !== 'object') { - continue; - } - - if (typeof entry.name === 'string') { - addPackageName(entry.name, packageNames); - continue; - } - - if (typeof entry.package === 'string') { - addPackageName(entry.package, packageNames); - continue; - } - - if (Array.isArray(entry.items)) { - collectPackageNamesFromList(entry.items, packageNames); - } - } -} - -function addPackageName(name, packageNames) { - if (isPackageNameCandidate(name)) { - packageNames.add(name); - } -} - -function isPackageNameCandidate(value) { - if (typeof value !== 'string') { - return false; - } - if (!value || value === '//') { - return false; - } - if (value.includes('#') || value.includes('\\') || value.includes(' ')) { - return false; - } - if (value.startsWith('@')) { - return /^@[^/]+\/[^/]+$/.test(value); - } - return !value.includes('/'); -} - -function toUnscopedName(value) { - if (typeof value !== 'string' || !value.startsWith('@')) { - return null; - } - const [, unscoped] = value.split('/'); - return unscoped || null; -} diff --git a/tools/scripts/ci-is-affected.test.mjs b/tools/scripts/ci-is-affected.test.mjs new file mode 100644 index 00000000000..699eb69b6e6 --- /dev/null +++ b/tools/scripts/ci-is-affected.test.mjs @@ -0,0 +1,285 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { mkdtempSync, readFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import test from 'node:test'; +import { + computeE2ESuiteDecisions, + isAppNameAffected, + parseAffectedPackages, +} from './ci-e2e-affected.mjs'; +import { E2E_SUITE_DEFINITIONS, E2E_SUITES } from './ci-e2e-suites.mjs'; +import { createLocalE2EHelpers } from './ci-local-e2e.mjs'; + +const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url)); +const ROOT = resolve(SCRIPT_DIR, '../..'); +const CLI_PATH = join(SCRIPT_DIR, 'ci-is-affected.mjs'); + +test('maps affected packages to their E2E suites', () => { + const decisions = computeE2ESuiteDecisions({ + affectedPackageNames: new Set([ + '@module-federation/modern-js', + 'runtime-host', + ]), + changedFiles: ['packages/runtime/src/index.ts'], + }); + + assert.equal(decisions.modern, true); + assert.equal(decisions.runtime, true); + assert.equal(decisions.router, false); +}); + +test('treats a suite workflow as input to only that suite', () => { + const decisions = computeE2ESuiteDecisions({ + affectedPackageNames: new Set(), + changedFiles: ['.github/workflows/e2e-router.yml'], + }); + + assert.deepEqual( + Object.entries(decisions) + .filter(([, shouldRun]) => shouldRun) + .map(([suiteName]) => suiteName), + ['router'], + ); +}); + +test('treats the Metro workflow as input to only the Metro suite', () => { + const decisions = computeE2ESuiteDecisions({ + affectedPackageNames: new Set(), + changedFiles: ['.github/workflows/e2e-metro.yml'], + }); + + assert.deepEqual( + Object.entries(decisions) + .filter(([, shouldRun]) => shouldRun) + .map(([suiteName]) => suiteName), + ['metro'], + ); +}); + +test('runs every suite for shared E2E policy changes', () => { + const decisions = computeE2ESuiteDecisions({ + affectedPackageNames: new Set(), + changedFiles: ['tools/scripts/ci-e2e-affected.mjs'], + }); + + assert.deepEqual( + decisions, + Object.fromEntries(Object.keys(E2E_SUITES).map((suite) => [suite, true])), + ); +}); + +test('gates every parent E2E suite in the parent workflow', () => { + const workflow = readFileSync( + join(ROOT, '.github/workflows/build-and-test.yml'), + 'utf8', + ); + + for (const [suiteName, definition] of Object.entries(E2E_SUITE_DEFINITIONS)) { + if (definition.parentWorkflow === false) { + continue; + } + assert.match( + workflow, + new RegExp(`e2e_suites\\)\\.${suiteName} \\}\\}`), + `missing parent gate for ${suiteName}`, + ); + } +}); + +test('matches scoped affected packages by unscoped app name', () => { + assert.equal( + isAppNameAffected(['modern-js'], new Set(['@module-federation/modern-js'])), + true, + ); +}); + +test('parses supported Turbo package output shapes', () => { + assert.deepEqual( + [...parseAffectedPackages('[{"name":"runtime-host"}]')], + ['runtime-host'], + ); + assert.deepEqual( + [ + ...parseAffectedPackages( + '{"packages":{"@module-federation/modern-js":{"path":"packages/modernjs"}}}', + ), + ], + ['@module-federation/modern-js'], + ); + assert.deepEqual( + [ + ...parseAffectedPackages( + '{"packageManager":"pnpm9","packages":{"count":0,"items":[]}}', + ), + ], + [], + ); +}); + +test('rejects malformed Turbo output so callers can fail open', () => { + assert.throws( + () => parseAffectedPackages('not json'), + /Unable to locate JSON payload in Turbo output/, + ); + assert.throws( + () => parseAffectedPackages('{"version":"2.9"}'), + /unsupported schema/, + ); + assert.throws( + () => parseAffectedPackages('[{"version":"2.9"}]'), + /unsupported package entry/, + ); + assert.throws( + () => parseAffectedPackages('{"items":[{"version":"2.9"}]}'), + /unsupported package entry/, + ); +}); + +test('translates local affected exit codes without hiding errors', async (t) => { + for (const { code, expected } of [ + { code: 0, expected: true }, + { code: 1, expected: false }, + ]) { + await t.test(`exit ${code}`, async () => { + const { checkAffectedStep } = createHelpersReturning({ code }); + const ctx = { env: {}, state: {} }; + + await checkAffectedStep(['runtime-host']).run(ctx); + + assert.equal(ctx.state.shouldRun, expected); + }); + } + + await t.test('unexpected exit', async () => { + const { checkAffectedStep } = createHelpersReturning({ code: 2 }); + + await assert.rejects( + checkAffectedStep(['runtime-host']).run({ env: {}, state: {} }), + /unexpected code 2/, + ); + }); +}); + +test('uses suite-aware selection for local E2E jobs', async () => { + const calls = []; + const helpers = createLocalE2EHelpers({ + formatExit: ({ code }) => `code ${code}`, + runCommand: async (command, args) => { + calls.push([command, args]); + return { code: 0 }; + }, + runPackagesBuild: async () => {}, + step: (label, run) => ({ label, run }), + }); + + const [, affectedStep] = helpers.e2eSetupSteps('router'); + await affectedStep.run({ env: {}, state: {} }); + + assert.deepEqual(calls, [ + ['node', ['tools/scripts/ci-is-affected.mjs', '--e2eSuite=router']], + ]); +}); + +test('combines a Metro suite selector with its app override', async () => { + const calls = []; + const helpers = createLocalE2EHelpers({ + formatExit: ({ code }) => `code ${code}`, + runCommand: async (command, args) => { + calls.push([command, args]); + return { code: 0 }; + }, + runPackagesBuild: async () => {}, + step: (label, run) => ({ label, run }), + }); + + await helpers + .checkAffectedStep(['custom-metro-app'], 'metro') + .run({ env: {}, state: {} }); + + assert.deepEqual(calls, [ + [ + 'node', + [ + 'tools/scripts/ci-is-affected.mjs', + '--appName=custom-metro-app', + '--e2eSuite=metro', + ], + ], + ]); +}); + +test('rejects unknown suites with an error exit', () => { + const result = runCli(['--e2eSuite=unknown']); + + assert.equal(result.status, 2); + assert.match(result.stderr, /Unknown e2e suite/); +}); + +test('requires GITHUB_OUTPUT for all-suite output mode', () => { + const env = { ...process.env }; + delete env.GITHUB_OUTPUT; + const result = runCli( + ['--githubOutputAll=e2e_suites', '--base=HEAD', '--head=HEAD'], + env, + ); + + assert.equal(result.status, 2); + assert.match(result.stderr, /GITHUB_OUTPUT is not set/); +}); + +test('writes a single fail-open decision to GITHUB_OUTPUT', () => { + const outputPath = createOutputPath(); + const result = runCli( + [ + '--e2eSuite=modern', + '--githubOutput=run_e2e', + '--base=HEAD', + '--head=HEAD', + ], + { ...process.env, GITHUB_OUTPUT: outputPath }, + ); + + assert.equal(result.status, 0); + assert.equal(readFileSync(outputPath, 'utf8'), 'run_e2e=true\n'); +}); + +test('writes all fail-open decisions as one JSON output', () => { + const outputPath = createOutputPath(); + const result = runCli( + ['--githubOutputAll=e2e_suites', '--base=HEAD', '--head=HEAD'], + { ...process.env, GITHUB_OUTPUT: outputPath }, + ); + + assert.equal(result.status, 0); + const output = readFileSync(outputPath, 'utf8').trim(); + const [name, json] = output.split('=', 2); + assert.equal(name, 'e2e_suites'); + assert.deepEqual( + JSON.parse(json), + Object.fromEntries(Object.keys(E2E_SUITES).map((suite) => [suite, true])), + ); +}); + +function runCli(args, env = process.env) { + return spawnSync(process.execPath, [CLI_PATH, ...args], { + cwd: ROOT, + encoding: 'utf8', + env, + }); +} + +function createOutputPath() { + return join(mkdtempSync(join(tmpdir(), 'ci-is-affected-')), 'output'); +} + +function createHelpersReturning(result) { + return createLocalE2EHelpers({ + formatExit: ({ code }) => `code ${code}`, + runCommand: async () => result, + runPackagesBuild: async () => {}, + step: (label, run) => ({ label, run }), + }); +} diff --git a/tools/scripts/ci-local-cli.mjs b/tools/scripts/ci-local-cli.mjs new file mode 100644 index 00000000000..794edf76e57 --- /dev/null +++ b/tools/scripts/ci-local-cli.mjs @@ -0,0 +1,297 @@ +export function parseArgs(argv) { + const onlyTokens = []; + const result = { + help: false, + list: false, + only: null, + printParity: false, + skipCache: false, + strictParity: false, + errors: [], + unknownArgs: [], + }; + for (let i = 2; i < argv.length; i += 1) { + const arg = argv[i]; + if (arg === '--list') { + result.list = true; + continue; + } + if (arg === '--help' || arg === '-h') { + result.help = true; + continue; + } + if (arg === '--only') { + const onlyValue = argv[i + 1]; + if (!onlyValue || onlyValue.startsWith('--')) { + result.errors.push('Missing value for --only.'); + continue; + } + onlyTokens.push(onlyValue); + i += 1; + continue; + } + if (arg.startsWith('--only=')) { + onlyTokens.push(arg.slice('--only='.length)); + continue; + } + if (arg === '--print-parity') { + result.printParity = true; + continue; + } + if (arg === '--skip-cache') { + result.skipCache = true; + continue; + } + if (arg === '--strict-parity') { + result.strictParity = true; + continue; + } + result.unknownArgs.push(arg); + } + if (onlyTokens.length > 0) { + result.only = onlyTokens.join(','); + } + return result; +} + +export function getOnlyJobNames(args) { + if (!args.only) { + return []; + } + return Array.from( + new Set( + args.only + .split(',') + .map((job) => job.trim()) + .filter(Boolean), + ), + ); +} + +export function getSelectableJobNames(jobList) { + const names = new Set(); + for (const job of jobList) { + names.add(job.name); + if (job.matrix?.length) { + for (const entry of job.matrix) { + names.add(formatMatrixJobName(job.name, entry)); + } + } + } + return names; +} + +export function validateArgs({ + args, + onlyJobNames, + onlyJobs, + selectableJobNames, +}) { + const issues = []; + + if (args.errors.length > 0) { + issues.push(...args.errors); + } + + if (args.unknownArgs.length > 0) { + issues.push( + `Unknown option(s): ${args.unknownArgs.join(', ')}. Use --help to see supported flags.`, + ); + } + + if (args.only !== null && onlyJobNames.length === 0) { + issues.push( + 'The --only option requires at least one job name (use --list to inspect available jobs).', + ); + } + + if (onlyJobs) { + const unknownJobNames = onlyJobNames.filter( + (jobName) => !selectableJobNames.has(jobName), + ); + if (unknownJobNames.length > 0) { + issues.push( + `Unknown job(s) in --only: ${unknownJobNames.join(', ')}. Use --list to inspect available jobs.`, + ); + } + } + + if (issues.length > 0) { + throw new Error(`[ci:local] ${issues.join(' ')}`); + } +} + +export function shouldRunJob(job, onlyJobs) { + if (!onlyJobs) { + return true; + } + if (onlyJobs.has(job.name)) { + return true; + } + if (job.matrix?.length) { + return job.matrix.some((entry) => + onlyJobs.has(formatMatrixJobName(job.name, entry)), + ); + } + return false; +} + +export function listJobs(jobList, { onlyJobs, selectableJobNames }) { + console.log('ci:local job list:'); + if (onlyJobs) { + console.log( + `[ci:local] Listing filtered jobs: ${Array.from(onlyJobs).join(', ')}`, + ); + } + let listedCount = 0; + for (const job of jobList) { + if (job.matrix?.length) { + const includeAllEntries = !onlyJobs || onlyJobs.has(job.name); + if (!includeAllEntries) { + const hasMatchingEntry = job.matrix.some((entry) => + onlyJobs.has(formatMatrixJobName(job.name, entry)), + ); + if (!hasMatchingEntry) { + continue; + } + } + for (const entry of job.matrix) { + const entryName = formatMatrixJobName(job.name, entry); + if (!includeAllEntries && onlyJobs && !onlyJobs.has(entryName)) { + continue; + } + console.log(`- ${formatJobListEntry({ name: entryName })}`); + listedCount += 1; + } + } else { + if (onlyJobs && !onlyJobs.has(job.name)) { + continue; + } + console.log(`- ${formatJobListEntry(job)}`); + listedCount += 1; + } + } + if (listedCount === 0) { + console.log('(no matching jobs)'); + } + if (onlyJobs) { + console.log( + `[ci:local] Matched ${listedCount} of ${selectableJobNames.size} selectable jobs.`, + ); + } else { + console.log(`[ci:local] Listed ${listedCount} selectable jobs.`); + } + console.log('\nUse --only=job1,job2 to run a subset.'); +} + +export function preflight({ + args, + detectPnpmVersion, + expectedNodeMajor, + expectedPnpmVersion, +}) { + const nodeMajor = Number(process.versions.node.split('.')[0]); + const parityIssues = []; + if (nodeMajor !== expectedNodeMajor) { + parityIssues.push( + `node ${process.versions.node} (expected major ${expectedNodeMajor})`, + ); + const pnpmVersionForHint = expectedPnpmVersion ?? '10.28.0'; + console.warn( + `[ci:local] Warning: running with Node ${process.versions.node}. CI runs with Node ${expectedNodeMajor}.`, + ); + console.warn( + `[ci:local] For closest parity run: source "$HOME/.nvm/nvm.sh" && nvm use ${expectedNodeMajor} && corepack enable && corepack prepare pnpm@${pnpmVersionForHint} --activate`, + ); + } + + const pnpmCheck = detectPnpmVersion(); + if (pnpmCheck.status !== 0) { + throw new Error( + '[ci:local] pnpm not found in PATH. Install/activate pnpm before running ci-local.', + ); + } + + const pnpmVersion = (pnpmCheck.stdout ?? '').trim(); + if (expectedPnpmVersion && pnpmVersion !== expectedPnpmVersion) { + parityIssues.push(`pnpm ${pnpmVersion} (expected ${expectedPnpmVersion})`); + console.warn( + `[ci:local] Warning: running with pnpm ${pnpmVersion}. CI parity target is pnpm ${expectedPnpmVersion}.`, + ); + console.warn( + `[ci:local] For closest parity run: corepack enable && corepack prepare pnpm@${expectedPnpmVersion} --activate`, + ); + } + + if (args.strictParity && parityIssues.length > 0) { + throw new Error( + `[ci:local] Strict parity check failed: ${parityIssues.join('; ')}`, + ); + } +} + +export function printParity({ + detectPnpmVersion, + expectedNodeMajor, + expectedPnpmVersion, + root, +}) { + const pnpmCheck = detectPnpmVersion(); + const currentPnpmVersion = + pnpmCheck.status === 0 ? (pnpmCheck.stdout ?? '').trim() : 'unavailable'; + + console.log('ci:local parity config:'); + console.log(`- repo root: ${root}`); + console.log(`- expected node major: ${expectedNodeMajor}`); + console.log( + `- expected pnpm version: ${expectedPnpmVersion ?? 'unconfigured'}`, + ); + console.log(`- current node: ${process.versions.node}`); + console.log(`- current pnpm: ${currentPnpmVersion}`); +} + +export function printHelp() { + console.log('Usage: node tools/scripts/ci-local.mjs [options]'); + console.log(''); + console.log('Options:'); + console.log(' --list List available jobs'); + console.log( + ' --only= Run only specific comma-separated jobs (repeatable)', + ); + console.log( + ' --print-parity Print derived node/pnpm parity settings', + ); + console.log( + ' --strict-parity Fail when node/pnpm parity is mismatched', + ); + console.log( + ' --skip-cache Bypass Turbo task caches for supported ci-local steps', + ); + console.log(' --help Show this help message'); + console.log(''); + console.log('Examples:'); + console.log(' node tools/scripts/ci-local.mjs --only=build-metro'); + console.log( + ' node tools/scripts/ci-local.mjs --only=build-metro --only=actionlint', + ); + console.log(' node tools/scripts/ci-local.mjs --list --only=build-metro'); + console.log(' node tools/scripts/ci-local.mjs --print-parity'); + console.log( + ' node tools/scripts/ci-local.mjs --strict-parity --only=build-and-test', + ); + console.log( + ' node tools/scripts/ci-local.mjs --skip-cache --only=build-and-test', + ); +} + +export function formatMatrixJobName(jobName, entry) { + const entryName = entry.name ?? entry.id ?? 'matrix'; + return `${jobName} (${entryName})`; +} + +function formatJobListEntry(job) { + if (!job.skipReason) { + return job.name; + } + return `${job.name} [skip: ${job.skipReason}]`; +} diff --git a/tools/scripts/ci-local-e2e.mjs b/tools/scripts/ci-local-e2e.mjs new file mode 100644 index 00000000000..44be0dd8003 --- /dev/null +++ b/tools/scripts/ci-local-e2e.mjs @@ -0,0 +1,100 @@ +import { serializeAppNames } from './ci-e2e-suites.mjs'; + +export function createLocalE2EHelpers({ + formatExit, + runCommand, + runPackagesBuild, + step, +}) { + function installDependenciesStep() { + return step('Install dependencies', (ctx) => + runCommand('pnpm', ['install', '--frozen-lockfile'], ctx), + ); + } + + function checkAffectedStep(appNames, suiteName) { + return step('Check CI conditions', async (ctx) => { + const resolvedAppNames = + typeof appNames === 'function' ? appNames(ctx) : appNames; + ctx.state.shouldRun = await ciIsAffected( + resolvedAppNames, + suiteName, + ctx, + ); + ctx.state.skipReason = ctx.state.shouldRun + ? null + : 'Not affected by current changes.'; + }); + } + + function setupAffectedE2E({ cypress = true } = {}) { + return step('Setup E2E dependencies and package build', async (ctx) => { + if (!ctx.state.shouldRun) { + logStepSkip(ctx, currentSkipReason(ctx)); + return; + } + if (cypress) { + await runCommand('npx', ['cypress', 'install'], ctx); + } + await runPackagesBuild(ctx); + }); + } + + function e2eSetupSteps(suiteName, options) { + return [ + installDependenciesStep(), + checkAffectedStep(null, suiteName), + setupAffectedE2E(options), + ]; + } + + async function runWhenAffected(ctx, run) { + if (!ctx.state.shouldRun) { + logStepSkip(ctx, currentSkipReason(ctx)); + return; + } + await run(); + } + + async function ciIsAffected(appNames, suiteName, ctx) { + const selectors = []; + const serializedAppNames = serializeAppNames(appNames); + if (serializedAppNames) { + selectors.push(`--appName=${serializedAppNames}`); + } + if (suiteName) { + selectors.push(`--e2eSuite=${suiteName}`); + } + const result = await runCommand( + 'node', + ['tools/scripts/ci-is-affected.mjs', ...selectors], + { ...ctx, allowFailure: true }, + ); + if (result.code === 0) { + return true; + } + if (result.code === 1) { + return false; + } + throw new Error( + `ci-is-affected failed with unexpected ${formatExit(result)}`, + ); + } + + function currentSkipReason(ctx) { + return ctx.state.skipReason ?? 'Not affected by current changes.'; + } + + return { + checkAffectedStep, + e2eSetupSteps, + installDependenciesStep, + logStepSkip, + runWhenAffected, + setupAffectedE2E, + }; +} + +function logStepSkip(ctx, reason) { + console.log(`[ci:local] ${ctx.jobName} -> Skipped: ${reason}`); +} diff --git a/tools/scripts/ci-local.mjs b/tools/scripts/ci-local.mjs index e4c0d708b88..3a39eadfd4e 100644 --- a/tools/scripts/ci-local.mjs +++ b/tools/scripts/ci-local.mjs @@ -3,6 +3,20 @@ import { spawn, spawnSync } from 'node:child_process'; import { existsSync, readFileSync } from 'node:fs'; import { dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { E2E_SUITES } from './ci-e2e-suites.mjs'; +import { createLocalE2EHelpers } from './ci-local-e2e.mjs'; +import { + formatMatrixJobName, + getOnlyJobNames, + getSelectableJobNames, + listJobs, + parseArgs, + preflight, + printHelp, + printParity, + shouldRunJob, + validateArgs, +} from './ci-local-cli.mjs'; process.env.CI = process.env.CI ?? 'true'; @@ -13,27 +27,31 @@ const DEFAULT_EXPECTED_NODE_MAJOR = 24; const ROOT_PACKAGE_JSON = readRootPackageJson(); const EXPECTED_NODE_MAJOR = resolveExpectedNodeMajor(ROOT_PACKAGE_JSON); const EXPECTED_PNPM_VERSION = resolveExpectedPnpmVersion(ROOT_PACKAGE_JSON); +const SKIP_DEVTOOLS_POSTINSTALL_ENV = { SKIP_DEVTOOLS_POSTINSTALL: 'true' }; +const METRO_APP_NAME = + process.env.CI_LOCAL_METRO_APP_NAME ?? E2E_SUITES.metro[0]; +const METRO_E2E_ENV = { + ...SKIP_DEVTOOLS_POSTINSTALL_ENV, + METRO_APP_NAME, +}; const args = parseArgs(process.argv); -const onlyJobNames = args.only - ? Array.from( - new Set( - args.only - .split(',') - .map((job) => job.trim()) - .filter(Boolean), - ), - ) - : []; +const onlyJobNames = getOnlyJobNames(args); const onlyJobs = args.only === null ? null : new Set(onlyJobNames); -function setupE2E() { - return step('Setup E2E dependencies and package build', async (ctx) => { - await runCommand('pnpm', ['install', '--frozen-lockfile'], ctx); - await runCommand('npx', ['cypress', 'install'], ctx); - await runPackagesBuild(ctx); - }); -} +const { + checkAffectedStep, + e2eSetupSteps, + installDependenciesStep, + logStepSkip, + runWhenAffected, + setupAffectedE2E, +} = createLocalE2EHelpers({ + formatExit, + runCommand, + runPackagesBuild, + step, +}); const jobs = [ { @@ -48,6 +66,13 @@ const jobs = [ step('Check code format', (ctx) => runCommand('node', ['tools/scripts/check-format-changed.mjs'], ctx), ), + step('Test CI affected policy', (ctx) => + runCommand( + 'node', + ['--test', 'tools/scripts/ci-is-affected.test.mjs'], + ctx, + ), + ), step('Verify Rslib Template Publint Wiring', (ctx) => runCommand( 'node', @@ -172,31 +197,23 @@ const jobs = [ }, { name: 'e2e-modern', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - '@module-federation/modern-js,@module-federation/modern-js-v3', - ctx, - ); - }), - step('E2E Test for ModernJS', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:modern'], ctx); - }), + ...e2eSetupSteps('modern'), + step('E2E Test for ModernJS', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:modern'], ctx), + ), + ), ], }, { name: 'e2e-runtime', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), + ...e2eSetupSteps('runtime'), step('E2E Test for Runtime Demo', (ctx) => - runIfAffected(ctx, 'runtime-host,runtime-remote1,runtime-remote2', () => + runWhenAffected(ctx, () => runCommand('pnpm', ['run', 'e2e:runtime'], ctx), ), ), @@ -204,159 +221,107 @@ const jobs = [ }, { name: 'e2e-manifest', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), + ...e2eSetupSteps('manifest'), step('E2E Test for Manifest Demo (dev)', (ctx) => - runIfAffected( - ctx, - '3008-webpack-host,3009-webpack-provider,3010-rspack-provider,3011-rspack-manifest-provider,3012-rspack-js-entry-provider', - () => runCommand('pnpm', ['run', 'e2e:manifest:dev'], ctx), + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:manifest:dev'], ctx), ), ), step('E2E Test for Manifest Demo (prod)', (ctx) => - runIfAffected( - ctx, - '3008-webpack-host,3009-webpack-provider,3010-rspack-provider,3011-rspack-manifest-provider,3012-rspack-js-entry-provider', - () => runCommand('pnpm', ['run', 'e2e:manifest:prod'], ctx), + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:manifest:prod'], ctx), ), ), ], }, { name: 'e2e-node', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - 'node-host,node-local-remote,node-remote,node-dynamic-remote-new-version,node-dynamic-remote,node-host-e2e', - ctx, - ); - }), - step('E2E Node Federation', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:node'], ctx); - }), + ...e2eSetupSteps('node'), + step('E2E Node Federation', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:node'], ctx), + ), + ), ], }, { name: 'e2e-next-dev', env: { - SKIP_DEVTOOLS_POSTINSTALL: 'true', + ...SKIP_DEVTOOLS_POSTINSTALL_ENV, NEXT_PRIVATE_LOCAL_WEBPACK: 'true', }, steps: [ - setupE2E(), + ...e2eSetupSteps('next'), step('E2E Test for Next.js Dev', (ctx) => - runIfAffected( - ctx, - '@module-federation/3000-home,@module-federation/3001-shop,@module-federation/3002-checkout', - () => runCommand('pnpm', ['run', 'e2e:next:dev'], ctx), + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:next:dev'], ctx), ), ), ], }, { name: 'e2e-next-prod', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), + ...e2eSetupSteps('next'), step('E2E Test for Next.js Prod', (ctx) => - runIfAffected( - ctx, - '@module-federation/3000-home,@module-federation/3001-shop,@module-federation/3002-checkout', - () => runCommand('pnpm', ['run', 'e2e:next:prod'], ctx), + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:next:prod'], ctx), ), ), ], }, { name: 'e2e-treeshake', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - step('Install dependencies', (ctx) => - runCommand('pnpm', ['install', '--frozen-lockfile'], ctx), + ...e2eSetupSteps('treeshake', { cypress: false }), + step('E2E Treeshake Server', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:treeshake:server'], ctx), + ), + ), + step('E2E Treeshake Frontend', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:treeshake:frontend'], ctx), + ), ), - step('Build packages', (ctx) => runPackagesBuild(ctx)), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - '@module-federation/treeshake-server,@module-federation/treeshake-frontend', - ctx, - ); - }), - step('E2E Treeshake Server', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:treeshake:server'], ctx); - }), - step('E2E Treeshake Frontend', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:treeshake:frontend'], ctx); - }), ], }, { name: 'e2e-modern-ssr', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - '@module-federation/modern-js,@module-federation/modern-js-v3,modernjs-ssr-host,modernjs-ssr-remote,modernjs-ssr-remote-new-version,modernjs-ssr-nested-remote,modernjs-ssr-dynamic-remote,modernjs-ssr-dynamic-remote-new-version,modernjs-ssr-dynamic-nested-remote,modernjs-ssr-data-fetch-host,modernjs-ssr-data-fetch-provider,modernjs-ssr-data-fetch-provider-csr', - ctx, - ); - }), - step('E2E Test for ModernJS SSR', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:modern:ssr'], ctx); - }), + ...e2eSetupSteps('modernSsr'), + step('E2E Test for ModernJS SSR', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:modern:ssr'], ctx), + ), + ), ], }, { name: 'e2e-router', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - 'host,host-v5,host-vue3,remote1,remote2,remote3,remote4,remote5,remote6', - ctx, - ); - }), - step('E2E Test for Router', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand('pnpm', ['run', 'e2e:router'], ctx); - }), + ...e2eSetupSteps('router'), + step('E2E Test for Router', (ctx) => + runWhenAffected(ctx, () => + runCommand('pnpm', ['run', 'e2e:router'], ctx), + ), + ), ], }, { name: 'metro-affected-check', - env: { - SKIP_DEVTOOLS_POSTINSTALL: 'true', - METRO_APP_NAME: process.env.CI_LOCAL_METRO_APP_NAME ?? 'example-host', - }, + env: METRO_E2E_ENV, steps: [ - step('Install dependencies', (ctx) => - runCommand('pnpm', ['install', '--frozen-lockfile'], ctx), - ), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected(ctx.env.METRO_APP_NAME, ctx); - }), + installDependenciesStep(), + checkAffectedStep((ctx) => ctx.env.METRO_APP_NAME, 'metro'), step('Print Metro affected result', (ctx) => { if (ctx.state.shouldRun) { console.log( @@ -373,32 +338,23 @@ const jobs = [ }, { name: 'metro-android-e2e', - env: { - SKIP_DEVTOOLS_POSTINSTALL: 'true', - METRO_APP_NAME: process.env.CI_LOCAL_METRO_APP_NAME ?? 'example-host', - }, + env: METRO_E2E_ENV, steps: [ - step('Install dependencies', (ctx) => - runCommand('pnpm', ['install', '--frozen-lockfile'], ctx), - ), - step('Build shared packages', (ctx) => runPackagesBuild(ctx)), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected(ctx.env.METRO_APP_NAME, ctx); - }), + installDependenciesStep(), + checkAffectedStep((ctx) => ctx.env.METRO_APP_NAME, 'metro'), + setupAffectedE2E({ cypress: false }), step('Run Metro Android E2E tests', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand( - 'node', - [ - 'tools/scripts/run-metro-e2e.mjs', - '--platform=android', - `--appName=${ctx.env.METRO_APP_NAME}`, - '--skip-on-missing-prereqs', - ], - ctx, + await runWhenAffected(ctx, () => + runCommand( + 'node', + [ + 'tools/scripts/run-metro-e2e.mjs', + '--platform=android', + `--appName=${ctx.env.METRO_APP_NAME}`, + '--skip-on-missing-prereqs', + ], + ctx, + ), ); }), ], @@ -411,18 +367,10 @@ const jobs = [ }, { name: 'metro-ios-e2e', - env: { - SKIP_DEVTOOLS_POSTINSTALL: 'true', - METRO_APP_NAME: process.env.CI_LOCAL_METRO_APP_NAME ?? 'example-host', - }, + env: METRO_E2E_ENV, steps: [ - step('Install dependencies', (ctx) => - runCommand('pnpm', ['install', '--frozen-lockfile'], ctx), - ), - step('Build shared packages', (ctx) => runPackagesBuild(ctx)), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected(ctx.env.METRO_APP_NAME, ctx); - }), + installDependenciesStep(), + checkAffectedStep((ctx) => ctx.env.METRO_APP_NAME, 'metro'), step('Check Metro iOS compatibility', (ctx) => { if (!ctx.state.shouldRun) { logStepSkip(ctx, 'Not affected by current changes.'); @@ -430,23 +378,23 @@ const jobs = [ } if (process.platform !== 'darwin') { ctx.state.shouldRun = false; - logStepSkip(ctx, 'Requires macOS to run iOS simulator tests.'); + ctx.state.skipReason = 'Requires macOS to run iOS simulator tests.'; + logStepSkip(ctx, ctx.state.skipReason); } }), + setupAffectedE2E({ cypress: false }), step('Run Metro iOS E2E tests', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand( - 'node', - [ - 'tools/scripts/run-metro-e2e.mjs', - '--platform=ios', - `--appName=${ctx.env.METRO_APP_NAME}`, - '--skip-on-missing-prereqs', - ], - ctx, + await runWhenAffected(ctx, () => + runCommand( + 'node', + [ + 'tools/scripts/run-metro-e2e.mjs', + '--platform=ios', + `--appName=${ctx.env.METRO_APP_NAME}`, + '--skip-on-missing-prereqs', + ], + ctx, + ), ); }), ], @@ -459,37 +407,27 @@ const jobs = [ }, { name: 'e2e-shared-tree-shaking', - env: { SKIP_DEVTOOLS_POSTINSTALL: 'true' }, + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, steps: [ - setupE2E(), - step('Check CI conditions', async (ctx) => { - ctx.state.shouldRun = await ciIsAffected( - 'shared-tree-shaking-no-server-host,shared-tree-shaking-no-server-provider,shared-tree-shaking-with-server-host,shared-tree-shaking-with-server-provider', - ctx, - ); - }), - step('E2E Shared Tree Shaking (runtime-infer)', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand( - 'pnpm', - ['run', 'e2e:shared-tree-shaking:runtime-infer'], - ctx, - ); - }), - step('E2E Shared Tree Shaking (server-calc)', async (ctx) => { - if (!ctx.state.shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await runCommand( - 'pnpm', - ['run', 'e2e:shared-tree-shaking:server-calc'], - ctx, - ); - }), + ...e2eSetupSteps('sharedTreeShaking'), + step('E2E Shared Tree Shaking (runtime-infer)', (ctx) => + runWhenAffected(ctx, () => + runCommand( + 'pnpm', + ['run', 'e2e:shared-tree-shaking:runtime-infer'], + ctx, + ), + ), + ), + step('E2E Shared Tree Shaking (server-calc)', (ctx) => + runWhenAffected(ctx, () => + runCommand( + 'pnpm', + ['run', 'e2e:shared-tree-shaking:server-calc'], + ctx, + ), + ), + ), ], }, { @@ -627,17 +565,27 @@ async function main() { printHelp(); return; } - validateArgs(); + validateArgs({ args, onlyJobNames, onlyJobs, selectableJobNames }); if (args.list) { - listJobs(jobs); + listJobs(jobs, { onlyJobs, selectableJobNames }); return; } - preflight(); + preflight({ + args, + detectPnpmVersion, + expectedNodeMajor: EXPECTED_NODE_MAJOR, + expectedPnpmVersion: EXPECTED_PNPM_VERSION, + }); if (args.skipCache) { console.log('[ci:local] Task cache bypass enabled (--skip-cache).'); } if (args.printParity) { - printParity(); + printParity({ + detectPnpmVersion, + expectedNodeMajor: EXPECTED_NODE_MAJOR, + expectedPnpmVersion: EXPECTED_PNPM_VERSION, + root: ROOT, + }); return; } for (const job of jobs) { @@ -697,49 +645,6 @@ async function runPackagesBuildAtPath(targetPath, ctx) { ); } -function preflight() { - const nodeMajor = Number(process.versions.node.split('.')[0]); - const parityIssues = []; - if (nodeMajor !== EXPECTED_NODE_MAJOR) { - parityIssues.push( - `node ${process.versions.node} (expected major ${EXPECTED_NODE_MAJOR})`, - ); - const pnpmVersionForHint = EXPECTED_PNPM_VERSION ?? '10.28.0'; - console.warn( - `[ci:local] Warning: running with Node ${process.versions.node}. CI runs with Node ${EXPECTED_NODE_MAJOR}.`, - ); - console.warn( - `[ci:local] For closest parity run: source "$HOME/.nvm/nvm.sh" && nvm use ${EXPECTED_NODE_MAJOR} && corepack enable && corepack prepare pnpm@${pnpmVersionForHint} --activate`, - ); - } - - const pnpmCheck = detectPnpmVersion(); - if (pnpmCheck.status !== 0) { - throw new Error( - '[ci:local] pnpm not found in PATH. Install/activate pnpm before running ci-local.', - ); - } - - const pnpmVersion = (pnpmCheck.stdout ?? '').trim(); - if (EXPECTED_PNPM_VERSION && pnpmVersion !== EXPECTED_PNPM_VERSION) { - parityIssues.push( - `pnpm ${pnpmVersion} (expected ${EXPECTED_PNPM_VERSION})`, - ); - console.warn( - `[ci:local] Warning: running with pnpm ${pnpmVersion}. CI parity target is pnpm ${EXPECTED_PNPM_VERSION}.`, - ); - console.warn( - `[ci:local] For closest parity run: corepack enable && corepack prepare pnpm@${EXPECTED_PNPM_VERSION} --activate`, - ); - } - - if (args.strictParity && parityIssues.length > 0) { - throw new Error( - `[ci:local] Strict parity check failed: ${parityIssues.join('; ')}`, - ); - } -} - async function runJob(job, parentCtx = {}) { const skipFilter = parentCtx.skipFilter === true; const inheritedCtx = { ...parentCtx }; @@ -749,7 +654,7 @@ async function runJob(job, parentCtx = {}) { console.log(`[ci:local] Skipping job "${job.name}": ${job.skipReason}`); return; } - if (!skipFilter && !shouldRunJob(job)) { + if (!skipFilter && !shouldRunJob(job, onlyJobs)) { console.log(`[ci:local] Skipping job "${job.name}" (filtered).`); return; } @@ -805,244 +710,6 @@ function step(label, run) { return { label, run }; } -function shouldRunJob(job) { - if (!onlyJobs) { - return true; - } - if (onlyJobs.has(job.name)) { - return true; - } - if (job.matrix?.length) { - return job.matrix.some((entry) => - onlyJobs.has(formatMatrixJobName(job.name, entry)), - ); - } - return false; -} - -function listJobs(jobList) { - console.log('ci:local job list:'); - if (onlyJobs) { - console.log( - `[ci:local] Listing filtered jobs: ${Array.from(onlyJobs).join(', ')}`, - ); - } - let listedCount = 0; - for (const job of jobList) { - if (job.matrix?.length) { - const includeAllEntries = !onlyJobs || onlyJobs.has(job.name); - if (!includeAllEntries) { - const hasMatchingEntry = job.matrix.some((entry) => - onlyJobs.has(formatMatrixJobName(job.name, entry)), - ); - if (!hasMatchingEntry) { - continue; - } - } - for (const entry of job.matrix) { - const entryName = formatMatrixJobName(job.name, entry); - if (!includeAllEntries && onlyJobs && !onlyJobs.has(entryName)) { - continue; - } - console.log(`- ${formatJobListEntry({ name: entryName })}`); - listedCount += 1; - } - } else { - if (onlyJobs && !onlyJobs.has(job.name)) { - continue; - } - console.log(`- ${formatJobListEntry(job)}`); - listedCount += 1; - } - } - if (listedCount === 0) { - console.log('(no matching jobs)'); - } - if (onlyJobs) { - console.log( - `[ci:local] Matched ${listedCount} of ${selectableJobNames.size} selectable jobs.`, - ); - } else { - console.log(`[ci:local] Listed ${listedCount} selectable jobs.`); - } - console.log('\nUse --only=job1,job2 to run a subset.'); -} - -function printParity() { - const pnpmCheck = detectPnpmVersion(); - const currentPnpmVersion = - pnpmCheck.status === 0 ? (pnpmCheck.stdout ?? '').trim() : 'unavailable'; - - console.log('ci:local parity config:'); - console.log(`- repo root: ${ROOT}`); - console.log(`- expected node major: ${EXPECTED_NODE_MAJOR}`); - console.log( - `- expected pnpm version: ${EXPECTED_PNPM_VERSION ?? 'unconfigured'}`, - ); - console.log(`- current node: ${process.versions.node}`); - console.log(`- current pnpm: ${currentPnpmVersion}`); -} - -function printHelp() { - console.log('Usage: node tools/scripts/ci-local.mjs [options]'); - console.log(''); - console.log('Options:'); - console.log(' --list List available jobs'); - console.log( - ' --only= Run only specific comma-separated jobs (repeatable)', - ); - console.log( - ' --print-parity Print derived node/pnpm parity settings', - ); - console.log( - ' --strict-parity Fail when node/pnpm parity is mismatched', - ); - console.log( - ' --skip-cache Bypass Turbo task caches for supported ci-local steps', - ); - console.log(' --help Show this help message'); - console.log(''); - console.log('Examples:'); - console.log(' node tools/scripts/ci-local.mjs --only=build-metro'); - console.log( - ' node tools/scripts/ci-local.mjs --only=build-metro --only=actionlint', - ); - console.log(' node tools/scripts/ci-local.mjs --list --only=build-metro'); - console.log(' node tools/scripts/ci-local.mjs --print-parity'); - console.log( - ' node tools/scripts/ci-local.mjs --strict-parity --only=build-and-test', - ); - console.log( - ' node tools/scripts/ci-local.mjs --skip-cache --only=build-and-test', - ); -} - -function parseArgs(argv) { - const result = { - help: false, - list: false, - only: null, - onlyTokens: [], - printParity: false, - skipCache: false, - strictParity: false, - errors: [], - unknownArgs: [], - }; - for (let i = 2; i < argv.length; i += 1) { - const arg = argv[i]; - if (arg === '--list') { - result.list = true; - continue; - } - if (arg === '--help' || arg === '-h') { - result.help = true; - continue; - } - if (arg === '--only') { - const onlyValue = argv[i + 1]; - if (!onlyValue || onlyValue.startsWith('--')) { - result.errors.push('Missing value for --only.'); - continue; - } - result.onlyTokens.push(onlyValue); - i += 1; - continue; - } - if (arg.startsWith('--only=')) { - result.onlyTokens.push(arg.slice('--only='.length)); - continue; - } - if (arg === '--print-parity') { - result.printParity = true; - continue; - } - if (arg === '--skip-cache') { - result.skipCache = true; - continue; - } - if (arg === '--strict-parity') { - result.strictParity = true; - continue; - } - result.unknownArgs.push(arg); - } - if (result.onlyTokens.length > 0) { - result.only = result.onlyTokens.join(','); - } - delete result.onlyTokens; - return result; -} - -function validateArgs() { - const issues = []; - - if (args.errors.length > 0) { - issues.push(...args.errors); - } - - if (args.unknownArgs.length > 0) { - issues.push( - `Unknown option(s): ${args.unknownArgs.join(', ')}. Use --help to see supported flags.`, - ); - } - - if (args.only !== null && onlyJobNames.length === 0) { - issues.push( - 'The --only option requires at least one job name (use --list to inspect available jobs).', - ); - } - - if (onlyJobs) { - const unknownJobNames = onlyJobNames.filter( - (jobName) => !selectableJobNames.has(jobName), - ); - if (unknownJobNames.length > 0) { - issues.push( - `Unknown job(s) in --only: ${unknownJobNames.join(', ')}. Use --list to inspect available jobs.`, - ); - } - } - - if (issues.length > 0) { - throw new Error(`[ci:local] ${issues.join(' ')}`); - } -} - -function formatMatrixJobName(jobName, entry) { - const entryName = entry.name ?? entry.id ?? 'matrix'; - return `${jobName} (${entryName})`; -} - -function formatJobListEntry(job) { - if (!job.skipReason) { - return job.name; - } - return `${job.name} [skip: ${job.skipReason}]`; -} - -function getSelectableJobNames(jobList) { - const names = new Set(); - for (const job of jobList) { - names.add(job.name); - if (job.matrix?.length) { - for (const entry of job.matrix) { - names.add(formatMatrixJobName(job.name, entry)); - } - } - } - return names; -} - -async function runIfAffected(ctx, affectedAppName, run) { - const shouldRun = await ciIsAffected(affectedAppName, ctx); - if (!shouldRun) { - logStepSkip(ctx, 'Not affected by current changes.'); - return; - } - await run(); -} - async function runChangedPackageTests(ctx) { const commandArgs = ['tools/scripts/run-affected-package-tests.mjs']; if (args.skipCache) { @@ -1210,19 +877,6 @@ function resolveExpectedPnpmVersion(packageJson) { return null; } -async function ciIsAffected(appName, ctx) { - const result = await runCommand( - 'node', - ['tools/scripts/ci-is-affected.mjs', `--appName=${appName}`], - { ...ctx, allowFailure: true }, - ); - return result.code === 0; -} - -function logStepSkip(ctx, reason) { - console.log(`[ci:local] ${ctx.jobName} -> Skipped: ${reason}`); -} - function formatExit({ code, signal }) { const parts = []; if (code !== null && code !== undefined) { From cbc5170870a33653d673a4fa08fc8ba216670ed3 Mon Sep 17 00:00:00 2001 From: Shashank Upadhyay <94886172+shashank-u03@users.noreply.github.com> Date: Fri, 17 Jul 2026 05:13:48 +0530 Subject: [PATCH 29/37] feat(nextjs-mf): add skipFederatedStats option (#4732) Co-authored-by: Shashank Upadhyay Co-authored-by: ScriptedAlchemy --- .changeset/cyan-badgers-wave.md | 6 ++ .../integrations/framework/nextjs/index.mdx | 2 + .../integrations/framework/nextjs/index.mdx | 2 + .../apply-client-plugins.test.ts | 79 +++++++++++++++++++ .../apply-client-plugins.ts | 14 ++-- .../NextFederationPlugin/next-fragments.ts | 1 + .../NextFederationPlugin/set-options.test.ts | 21 +++++ .../NextFederationPlugin/set-options.ts | 19 ++--- packages/utilities/src/types/index.ts | 1 + 9 files changed, 125 insertions(+), 20 deletions(-) create mode 100644 .changeset/cyan-badgers-wave.md create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts diff --git a/.changeset/cyan-badgers-wave.md b/.changeset/cyan-badgers-wave.md new file mode 100644 index 00000000000..fffef768f94 --- /dev/null +++ b/.changeset/cyan-badgers-wave.md @@ -0,0 +1,6 @@ +--- +'@module-federation/nextjs-mf': minor +'@module-federation/utilities': minor +--- + +Add a `skipFederatedStats` option for CSR-only Next.js builds whose downstream consumers do not use `federated-stats.json`. diff --git a/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx b/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx index 8c093af3c8d..8d4107af42a 100644 --- a/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx +++ b/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx @@ -70,6 +70,7 @@ new NextFederationPlugin({ enableImageLoaderFix: boolean, // `false` by default enableUrlLoaderFix: boolean, // `false` by default skipSharingNextInternals: boolean, // `false` by default + skipFederatedStats: boolean // `false` by default }, }); ``` @@ -79,6 +80,7 @@ new NextFederationPlugin({ - `enableImageLoaderFix` – adds public hostname to all assets bundled by `nextjs-image-loader`. So if you serve remoteEntry from `http://example.com` then all bundled assets will get this hostname in runtime. It's something like Base URL in HTML but for federated modules. - `enableUrlLoaderFix` – adds public hostname to all assets bundled by `url-loader`. - `skipSharingNextInternals` – disables sharing of next internals. You can use it if you want to share next internals yourself or want to use this plugin on non next applications +- `skipFederatedStats` – skips generation of `federated-stats.json` to reduce build time. Enable it only for CSR-only applications when neither `flushChunks()` nor any downstream host or custom tooling consumes that asset. ## Demo diff --git a/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx b/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx index df2e574eaf0..ae7de36d121 100644 --- a/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx +++ b/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx @@ -154,6 +154,7 @@ new NextFederationPlugin({ enableImageLoaderFix: boolean, // `false` by default enableUrlLoaderFix: boolean, // `false` by default skipSharingNextInternals: boolean, // `false` by default + skipFederatedStats: boolean // `false` by default }, }); ``` @@ -163,6 +164,7 @@ new NextFederationPlugin({ - `enableImageLoaderFix` – 给所有由 `nextjs-image-loader` 打包的资产添加公共主机名。例如,如果你从 `http://example.com` 提供 remoteEntry,则所有打包资产将在运行时获取此主机名。这类似于 HTML 中的 Base URL,但用于联合模块。 - `enableUrlLoaderFix` – 给所有由 `url-loader` 打包的资产添加公共主机名。 - `skipSharingNextInternals` – 禁用共享 Next 内部。如果你想自己共享 Next 内部或在非 next 应用中使用此插件,则可以使用它。 +- `skipFederatedStats` – 跳过 `federated-stats.json` 的生成以减少构建时间。仅当纯 CSR 应用本身、下游宿主和自定义工具都不使用 `flushChunks()` 或读取该资源时才启用此选项。 ## 演示 diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts new file mode 100644 index 00000000000..456beaf2ef2 --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts @@ -0,0 +1,79 @@ +import type { moduleFederationPlugin } from '@module-federation/sdk'; +import { ChunkCorrelationPlugin } from '@module-federation/node'; +import type { Compiler } from 'webpack'; +import InvertedContainerPlugin from '../container/InvertedContainerPlugin'; +import { applyClientPlugins } from './apply-client-plugins'; +import type { NextFederationPluginExtraOptions } from './next-fragments'; + +jest.mock( + '@module-federation/node', + () => ({ + ChunkCorrelationPlugin: jest.fn().mockImplementation(() => ({ + apply: jest.fn(), + })), + }), + { virtual: true }, +); + +jest.mock('../container/InvertedContainerPlugin', () => ({ + __esModule: true, + default: jest.fn().mockImplementation(() => ({ + apply: jest.fn(), + })), +})); + +jest.mock('../../logger', () => ({ + __esModule: true, + default: { + error: jest.fn(), + warn: jest.fn(), + }, +})); + +const options: moduleFederationPlugin.ModuleFederationPluginOptions = { + name: 'host', +}; + +const createCompiler = () => + ({ + options: { + output: { + publicPath: '/_next/', + }, + }, + }) as Compiler; + +describe('applyClientPlugins', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it.each([undefined, false])( + 'applies chunk correlation when skipFederatedStats is %s', + (skipFederatedStats) => { + const compiler = createCompiler(); + const extraOptions: NextFederationPluginExtraOptions = { + skipFederatedStats, + }; + + applyClientPlugins(compiler, { ...options }, extraOptions); + + expect(ChunkCorrelationPlugin).toHaveBeenCalledWith({ + filename: [ + 'static/chunks/federated-stats.json', + 'server/federated-stats.json', + ], + }); + expect(InvertedContainerPlugin).toHaveBeenCalledTimes(1); + }, + ); + + it('omits chunk correlation without affecting other client plugins', () => { + const compiler = createCompiler(); + + applyClientPlugins(compiler, { ...options }, { skipFederatedStats: true }); + + expect(ChunkCorrelationPlugin).not.toHaveBeenCalled(); + expect(InvertedContainerPlugin).toHaveBeenCalledTimes(1); + }); +}); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts index 1a3a53e76a6..f841585210d 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts @@ -53,12 +53,14 @@ export function applyClientPlugins( }; // Apply the ChunkCorrelationPlugin to collect metadata on chunks - new ChunkCorrelationPlugin({ - filename: [ - 'static/chunks/federated-stats.json', - 'server/federated-stats.json', - ], - }).apply(compiler); + if (!extraOptions.skipFederatedStats) { + new ChunkCorrelationPlugin({ + filename: [ + 'static/chunks/federated-stats.json', + 'server/federated-stats.json', + ], + }).apply(compiler); + } // Apply the InvertedContainerPlugin to add custom runtime modules to the container runtime new InvertedContainerPlugin().apply(compiler); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts index 642443fe5fc..97fa2a49be7 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts @@ -137,6 +137,7 @@ export interface NextFederationPluginExtraOptions { skipSharingNextInternals?: boolean; automaticPageStitching?: boolean; debug?: boolean; + skipFederatedStats?: boolean; } export interface NextFederationPluginOptions diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts new file mode 100644 index 00000000000..9540c8f2e29 --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts @@ -0,0 +1,21 @@ +import { setOptions } from './set-options'; + +describe('setOptions', () => { + it('generates federated stats by default', () => { + const { extraOptions } = setOptions({ + name: 'host', + extraOptions: {}, + }); + + expect(extraOptions.skipFederatedStats).toBe(false); + }); + + it('preserves an explicit federated stats opt-out', () => { + const { extraOptions } = setOptions({ + name: 'host', + extraOptions: { skipFederatedStats: true }, + }); + + expect(extraOptions.skipFederatedStats).toBe(true); + }); +}); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts index bae02d0b794..27f22d5518f 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts @@ -1,18 +1,8 @@ import type { moduleFederationPlugin } from '@module-federation/sdk'; - -export interface NextFederationPluginExtraOptions { - enableImageLoaderFix?: boolean; - enableUrlLoaderFix?: boolean; - exposePages?: boolean; - skipSharingNextInternals?: boolean; - automaticPageStitching?: boolean; - debug?: boolean; -} - -export interface NextFederationPluginOptions - extends moduleFederationPlugin.ModuleFederationPluginOptions { - extraOptions: NextFederationPluginExtraOptions; -} +import type { + NextFederationPluginExtraOptions, + NextFederationPluginOptions, +} from './next-fragments'; export function setOptions(options: NextFederationPluginOptions): { mainOptions: moduleFederationPlugin.ModuleFederationPluginOptions; @@ -30,6 +20,7 @@ export function setOptions(options: NextFederationPluginOptions): { enableUrlLoaderFix: false, skipSharingNextInternals: false, debug: false, + skipFederatedStats: false, }; return { diff --git a/packages/utilities/src/types/index.ts b/packages/utilities/src/types/index.ts index aaa5f788c80..ddf3124020b 100644 --- a/packages/utilities/src/types/index.ts +++ b/packages/utilities/src/types/index.ts @@ -42,6 +42,7 @@ export interface NextFederationPluginExtraOptions { skipSharingNextInternals?: boolean; automaticPageStitching?: boolean; debug?: boolean; + skipFederatedStats?: boolean; } export interface NextFederationPluginOptions extends ModuleFederationPluginOptions { From d901e2c10fe946c8003c76f2b56829e3285a321a Mon Sep 17 00:00:00 2001 From: Zack Jackson <25274700+ScriptedAlchemy@users.noreply.github.com> Date: Fri, 17 Jul 2026 23:38:20 +0000 Subject: [PATCH 30/37] perf(nextjs-mf): derive federated stats from manifest (#4909) --- .changeset/cyan-badgers-wave.md | 6 - .changeset/fast-manifests-flush.md | 7 + .../integrations/framework/nextjs/index.mdx | 6 +- .../integrations/framework/nextjs/index.mdx | 14 +- .../FederatedStatsCompatibilityPlugin.test.ts | 169 +++++++++ .../FederatedStatsCompatibilityPlugin.ts | 87 +++++ .../apply-client-plugins.test.ts | 58 +-- .../apply-client-plugins.ts | 25 +- .../src/plugins/NextFederationPlugin/index.ts | 12 +- .../manifest-options.test.ts | 14 + .../NextFederationPlugin/manifest-options.ts | 16 + .../NextFederationPlugin/next-fragments.ts | 1 - .../NextFederationPlugin/set-options.test.ts | 21 -- .../NextFederationPlugin/set-options.ts | 1 - .../node/src/__tests__/flush-chunks.test.ts | 327 ++++++++++++++++ packages/node/src/utils/flush-chunks.ts | 357 ++++++++++-------- packages/sdk/src/utils.ts | 13 +- packages/utilities/src/types/index.ts | 1 - 18 files changed, 905 insertions(+), 230 deletions(-) delete mode 100644 .changeset/cyan-badgers-wave.md create mode 100644 .changeset/fast-manifests-flush.md create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.test.ts create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.ts create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.test.ts create mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.ts delete mode 100644 packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts create mode 100644 packages/node/src/__tests__/flush-chunks.test.ts diff --git a/.changeset/cyan-badgers-wave.md b/.changeset/cyan-badgers-wave.md deleted file mode 100644 index fffef768f94..00000000000 --- a/.changeset/cyan-badgers-wave.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@module-federation/nextjs-mf': minor -'@module-federation/utilities': minor ---- - -Add a `skipFederatedStats` option for CSR-only Next.js builds whose downstream consumers do not use `federated-stats.json`. diff --git a/.changeset/fast-manifests-flush.md b/.changeset/fast-manifests-flush.md new file mode 100644 index 00000000000..605ba312bfe --- /dev/null +++ b/.changeset/fast-manifests-flush.md @@ -0,0 +1,7 @@ +--- +'@module-federation/nextjs-mf': patch +'@module-federation/node': patch +'@module-federation/sdk': patch +--- + +Use manifest expose assets for Next.js chunk flushing, including aliased remotes, and derive legacy federated stats compatibility assets without an extra Webpack stats traversal. diff --git a/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx b/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx index 8d4107af42a..1904ea07677 100644 --- a/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx +++ b/apps/website-new/docs/en/integrations/framework/nextjs/index.mdx @@ -69,8 +69,7 @@ new NextFederationPlugin({ exposePages: boolean, // `false` by default enableImageLoaderFix: boolean, // `false` by default enableUrlLoaderFix: boolean, // `false` by default - skipSharingNextInternals: boolean, // `false` by default - skipFederatedStats: boolean // `false` by default + skipSharingNextInternals: boolean // `false` by default }, }); ``` @@ -80,7 +79,8 @@ new NextFederationPlugin({ - `enableImageLoaderFix` – adds public hostname to all assets bundled by `nextjs-image-loader`. So if you serve remoteEntry from `http://example.com` then all bundled assets will get this hostname in runtime. It's something like Base URL in HTML but for federated modules. - `enableUrlLoaderFix` – adds public hostname to all assets bundled by `url-loader`. - `skipSharingNextInternals` – disables sharing of next internals. You can use it if you want to share next internals yourself or want to use this plugin on non next applications -- `skipFederatedStats` – skips generation of `federated-stats.json` to reduce build time. Enable it only for CSR-only applications when neither `flushChunks()` nor any downstream host or custom tooling consumes that asset. + +Next.js derives the expose asset fields used by legacy `flushChunks()` from `mf-manifest.json` without an additional Webpack stats traversal, so applications on older versions continue to work during rolling upgrades. Custom tooling that reads other legacy stats fields should migrate to `mf-manifest.json`; setting `manifest: false` retains the complete legacy output. ## Demo diff --git a/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx b/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx index ae7de36d121..dfafa0219cd 100644 --- a/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx +++ b/apps/website-new/docs/zh/integrations/framework/nextjs/index.mdx @@ -149,12 +149,11 @@ new NextFederationPlugin({ exposes: {}, shared: {}, extraOptions: { - debug: boolean, // `false` by default - exposePages: boolean, // `false` by default - enableImageLoaderFix: boolean, // `false` by default - enableUrlLoaderFix: boolean, // `false` by default - skipSharingNextInternals: boolean, // `false` by default - skipFederatedStats: boolean // `false` by default + debug: boolean, // 默认为 `false` + exposePages: boolean, // 默认为 `false` + enableImageLoaderFix: boolean, // 默认为 `false` + enableUrlLoaderFix: boolean, // 默认为 `false` + skipSharingNextInternals: boolean // 默认为 `false` }, }); ``` @@ -164,7 +163,8 @@ new NextFederationPlugin({ - `enableImageLoaderFix` – 给所有由 `nextjs-image-loader` 打包的资产添加公共主机名。例如,如果你从 `http://example.com` 提供 remoteEntry,则所有打包资产将在运行时获取此主机名。这类似于 HTML 中的 Base URL,但用于联合模块。 - `enableUrlLoaderFix` – 给所有由 `url-loader` 打包的资产添加公共主机名。 - `skipSharingNextInternals` – 禁用共享 Next 内部。如果你想自己共享 Next 内部或在非 next 应用中使用此插件,则可以使用它。 -- `skipFederatedStats` – 跳过 `federated-stats.json` 的生成以减少构建时间。仅当纯 CSR 应用本身、下游宿主和自定义工具都不使用 `flushChunks()` 或读取该资源时才启用此选项。 + +Next.js 会直接从 `mf-manifest.json` 派生旧版 `flushChunks()` 使用的 expose 资源字段,无需额外遍历 Webpack stats,因此滚动升级期间旧版本应用仍可继续工作。读取其他旧版 stats 字段的自定义工具应迁移到 `mf-manifest.json`;设置 `manifest: false` 可保留完整的旧版输出。 ## 演示 diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.test.ts new file mode 100644 index 00000000000..9e2622abff3 --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.test.ts @@ -0,0 +1,169 @@ +import type { Compiler } from 'webpack'; +import type { Manifest } from '@module-federation/sdk'; +import { + createFederatedStats, + FederatedStatsCompatibilityPlugin, +} from './FederatedStatsCompatibilityPlugin'; + +const manifest = { + id: 'shop', + name: 'shop', + metaData: { + name: 'shop', + type: 'app', + buildInfo: { buildVersion: '1.0.0', buildName: 'shop' }, + globalName: 'shop', + publicPath: 'auto', + remoteEntry: { + path: 'static/chunks', + name: 'remoteEntry.js', + type: 'window', + }, + types: { path: '', name: '', zip: '', api: '' }, + }, + shared: [], + remotes: [], + exposes: [ + { + id: 'shop:Button', + name: 'Button', + path: './Button', + assets: { + js: { sync: ['static/chunks/button.js'], async: ['lazy.js'] }, + css: { sync: ['static/css/button.css'], async: ['lazy.css'] }, + }, + }, + ], +} satisfies Manifest; + +describe('FederatedStatsCompatibilityPlugin', () => { + it('creates the expose fields consumed by legacy flushChunks', () => { + expect(createFederatedStats(manifest)).toEqual({ + sharedModules: [], + federatedModules: [ + { + remote: 'shop', + entry: 'static/chunks/remoteEntry.js', + sharedModules: [], + exposes: { + './Button': ['static/chunks/button.js', 'static/css/button.css'], + }, + remoteModules: {}, + }, + ], + }); + }); + + it('reads a custom manifest asset and emits both legacy filenames', () => { + let compilationHandler: ((compilation: any) => void) | undefined; + let assetsHandler: (() => void) | undefined; + let processAssetsOptions: Record | undefined; + const emitted = new Map string }>(); + const rawManifest = JSON.stringify(manifest); + emitted.set('server/federated-stats.json', { + source: () => 'stale', + }); + const compilation = { + hooks: { + processAssets: { + tap: (options: Record, handler: () => void) => { + processAssetsOptions = options; + assetsHandler = handler; + }, + }, + }, + getAsset: jest.fn((filename: string) => { + if (filename === 'meta/custom.json') { + return { source: { source: () => rawManifest } }; + } + return emitted.get(filename); + }), + emitAsset: jest.fn((filename: string, source: { source: () => string }) => + emitted.set(filename, source), + ), + updateAsset: jest.fn( + (filename: string, source: { source: () => string }) => + emitted.set(filename, source), + ), + }; + const compiler = { + hooks: { + thisCompilation: { + tap: (_name: string, handler: (compilation: any) => void) => { + compilationHandler = handler; + }, + }, + }, + webpack: { + Compilation: { PROCESS_ASSETS_STAGE_REPORT: 5000 }, + sources: { + RawSource: class { + constructor(private readonly value: string) {} + source() { + return this.value; + } + }, + }, + }, + } as unknown as Compiler; + + new FederatedStatsCompatibilityPlugin({ + filenames: [ + 'static/chunks/federated-stats.json', + 'server/federated-stats.json', + ], + manifest: { filePath: 'meta', fileName: 'custom' }, + }).apply(compiler); + compilationHandler?.(compilation); + assetsHandler?.(); + + expect(processAssetsOptions).toEqual({ + name: 'FederatedStatsCompatibilityPlugin', + stage: 5000, + }); + expect(compilation.getAsset).toHaveBeenCalledWith('meta/custom.json'); + expect(compilation.emitAsset).toHaveBeenCalledTimes(1); + expect(compilation.updateAsset).toHaveBeenCalledTimes(1); + expect(Array.from(emitted)).toHaveLength(2); + expect( + JSON.parse(emitted.get('server/federated-stats.json')!.source()), + ).toEqual(createFederatedStats(manifest)); + }); + + it('fails the build instead of omitting the compatibility asset', () => { + let compilationHandler: ((compilation: any) => void) | undefined; + let assetsHandler: (() => void) | undefined; + const compilation = { + hooks: { + processAssets: { + tap: (_options: unknown, handler: () => void) => { + assetsHandler = handler; + }, + }, + }, + getAsset: jest.fn(), + }; + const compiler = { + hooks: { + thisCompilation: { + tap: (_name: string, handler: (compilation: any) => void) => { + compilationHandler = handler; + }, + }, + }, + webpack: { + Compilation: { PROCESS_ASSETS_STAGE_REPORT: 5000 }, + }, + } as unknown as Compiler; + + new FederatedStatsCompatibilityPlugin({ + filenames: ['federated-stats.json'], + manifest: true, + }).apply(compiler); + compilationHandler?.(compilation); + + expect(assetsHandler).toThrow( + 'Cannot emit federated-stats.json because mf-manifest.json was not generated', + ); + }); +}); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.ts new file mode 100644 index 00000000000..67e55704a4f --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/FederatedStatsCompatibilityPlugin.ts @@ -0,0 +1,87 @@ +import type { Compiler, WebpackPluginInstance } from 'webpack'; +import { + getManifestFileName, + simpleJoinRemoteEntry, + type Manifest, + type moduleFederationPlugin, +} from '@module-federation/sdk'; + +type FederatedStatsCompatibilityPluginOptions = { + filenames: string[]; + manifest: moduleFederationPlugin.ModuleFederationPluginOptions['manifest']; +}; + +export const createFederatedStats = (manifest: Manifest) => { + const exposes: Record = {}; + + for (const expose of manifest.exposes) { + exposes[expose.path || `./${expose.name}`] = [ + ...expose.assets.js.sync, + ...expose.assets.css.sync, + ]; + } + + return { + sharedModules: [], + federatedModules: [ + { + remote: manifest.name, + entry: simpleJoinRemoteEntry( + manifest.metaData.remoteEntry.path, + manifest.metaData.remoteEntry.name, + ), + sharedModules: [], + exposes, + remoteModules: {}, + }, + ], + }; +}; + +export class FederatedStatsCompatibilityPlugin implements WebpackPluginInstance { + private readonly options: FederatedStatsCompatibilityPluginOptions; + + constructor(options: FederatedStatsCompatibilityPluginOptions) { + this.options = options; + } + + apply(compiler: Compiler): void { + compiler.hooks.thisCompilation.tap( + 'FederatedStatsCompatibilityPlugin', + (compilation) => { + compilation.hooks.processAssets.tap( + { + name: 'FederatedStatsCompatibilityPlugin', + stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT, + }, + () => { + const manifestFilename = getManifestFileName( + this.options.manifest, + ).manifestFileName; + const manifestAsset = compilation.getAsset(manifestFilename); + if (!manifestAsset) { + throw new Error( + `Cannot emit federated-stats.json because ${manifestFilename} was not generated`, + ); + } + + const manifest = JSON.parse( + manifestAsset.source.source().toString(), + ) as Manifest; + const source = new compiler.webpack.sources.RawSource( + JSON.stringify(createFederatedStats(manifest)), + ); + + for (const filename of this.options.filenames) { + if (compilation.getAsset(filename)) { + compilation.updateAsset(filename, source); + } else { + compilation.emitAsset(filename, source); + } + } + }, + ); + }, + ); + } +} diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts index 456beaf2ef2..c39a291c141 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.test.ts @@ -1,9 +1,5 @@ import type { moduleFederationPlugin } from '@module-federation/sdk'; -import { ChunkCorrelationPlugin } from '@module-federation/node'; import type { Compiler } from 'webpack'; -import InvertedContainerPlugin from '../container/InvertedContainerPlugin'; -import { applyClientPlugins } from './apply-client-plugins'; -import type { NextFederationPluginExtraOptions } from './next-fragments'; jest.mock( '@module-federation/node', @@ -22,6 +18,12 @@ jest.mock('../container/InvertedContainerPlugin', () => ({ })), })); +jest.mock('./FederatedStatsCompatibilityPlugin', () => ({ + FederatedStatsCompatibilityPlugin: jest.fn().mockImplementation(() => ({ + apply: jest.fn(), + })), +})); + jest.mock('../../logger', () => ({ __esModule: true, default: { @@ -30,6 +32,16 @@ jest.mock('../../logger', () => ({ }, })); +const { ChunkCorrelationPlugin } = jest.requireMock('@module-federation/node'); +const InvertedContainerPlugin = jest.requireMock( + '../container/InvertedContainerPlugin', +).default; +const { FederatedStatsCompatibilityPlugin } = jest.requireMock( + './FederatedStatsCompatibilityPlugin', +); +const { applyClientPlugins } = + require('./apply-client-plugins') as typeof import('./apply-client-plugins'); + const options: moduleFederationPlugin.ModuleFederationPluginOptions = { name: 'host', }; @@ -48,15 +60,28 @@ describe('applyClientPlugins', () => { jest.clearAllMocks(); }); - it.each([undefined, false])( - 'applies chunk correlation when skipFederatedStats is %s', - (skipFederatedStats) => { + it('emits compatibility stats from the manifest', () => { + const compiler = createCompiler(); + + applyClientPlugins(compiler, { ...options }, {}); + + expect(FederatedStatsCompatibilityPlugin).toHaveBeenCalledWith({ + filenames: [ + 'static/chunks/federated-stats.json', + 'server/federated-stats.json', + ], + manifest: undefined, + }); + expect(ChunkCorrelationPlugin).not.toHaveBeenCalled(); + expect(InvertedContainerPlugin).toHaveBeenCalledTimes(1); + }); + + it.each([{ manifest: false }, { manifest: { disableAssetsAnalyze: true } }])( + 'uses full chunk correlation for $manifest', + (manifestOptions) => { const compiler = createCompiler(); - const extraOptions: NextFederationPluginExtraOptions = { - skipFederatedStats, - }; - applyClientPlugins(compiler, { ...options }, extraOptions); + applyClientPlugins(compiler, { ...options, ...manifestOptions }, {}); expect(ChunkCorrelationPlugin).toHaveBeenCalledWith({ filename: [ @@ -64,16 +89,7 @@ describe('applyClientPlugins', () => { 'server/federated-stats.json', ], }); - expect(InvertedContainerPlugin).toHaveBeenCalledTimes(1); + expect(FederatedStatsCompatibilityPlugin).not.toHaveBeenCalled(); }, ); - - it('omits chunk correlation without affecting other client plugins', () => { - const compiler = createCompiler(); - - applyClientPlugins(compiler, { ...options }, { skipFederatedStats: true }); - - expect(ChunkCorrelationPlugin).not.toHaveBeenCalled(); - expect(InvertedContainerPlugin).toHaveBeenCalledTimes(1); - }); }); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts index f841585210d..817319f6ae2 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/apply-client-plugins.ts @@ -4,6 +4,12 @@ import InvertedContainerPlugin from '../container/InvertedContainerPlugin'; import type { moduleFederationPlugin } from '@module-federation/sdk'; import type { NextFederationPluginExtraOptions } from './next-fragments'; import logger from '../../logger'; +import { FederatedStatsCompatibilityPlugin } from './FederatedStatsCompatibilityPlugin'; + +const FEDERATED_STATS_FILENAMES = [ + 'static/chunks/federated-stats.json', + 'server/federated-stats.json', +]; /** * Applies client-specific plugins. @@ -52,13 +58,20 @@ export function applyClientPlugins( name, }; - // Apply the ChunkCorrelationPlugin to collect metadata on chunks - if (!extraOptions.skipFederatedStats) { + // Preserve the legacy asset for hosts that have not migrated to manifests. + const manifestHasAssets = + options.manifest !== false && + (typeof options.manifest !== 'object' || + !options.manifest.disableAssetsAnalyze); + + if (!manifestHasAssets) { new ChunkCorrelationPlugin({ - filename: [ - 'static/chunks/federated-stats.json', - 'server/federated-stats.json', - ], + filename: FEDERATED_STATS_FILENAMES, + }).apply(compiler); + } else { + new FederatedStatsCompatibilityPlugin({ + filenames: FEDERATED_STATS_FILENAMES, + manifest: options.manifest, }).apply(compiler); } diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts index 912c352af48..c3a8be58bf9 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts @@ -31,6 +31,7 @@ import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack'; import { bindLoggerToCompiler } from '@module-federation/sdk'; import type { moduleFederationPlugin } from '@module-federation/sdk'; import logger from '../../logger'; +import { normalizeManifestOptions } from './manifest-options'; const resolveRuntimePluginPath = (): string => process.env.IS_ESM_BUILD === 'true' @@ -219,12 +220,6 @@ export class NextFederationPlugin { const defaultShared = this._extraOptions.skipSharingNextInternals ? {} : retrieveDefaultShared(isServer); - const manifestOptions = - typeof this._options.manifest === 'object' && - this._options.manifest !== null - ? this._options.manifest - : {}; - return { ...this._options, runtime: false, @@ -248,10 +243,7 @@ export class NextFederationPlugin { ...defaultShared, ...(this._options.shared as Record), }, - manifest: { - ...manifestOptions, - filePath: isServer ? '' : '/static/chunks', - }, + manifest: normalizeManifestOptions(this._options.manifest, isServer), // nextjs project needs to add config.watchOptions = ['**/node_modules/**', '**/@mf-types/**'] to prevent loop types update dts: this._options.dts ?? false, shareStrategy: this._options.shareStrategy ?? 'loaded-first', diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.test.ts new file mode 100644 index 00000000000..7add5bb9022 --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.test.ts @@ -0,0 +1,14 @@ +import { normalizeManifestOptions } from './manifest-options'; + +describe('normalizeManifestOptions', () => { + it('preserves manifest: false for client plugin selection', () => { + expect(normalizeManifestOptions(false, false)).toBe(false); + }); + + it('retains custom options while setting the compiler-specific path', () => { + expect( + normalizeManifestOptions({ fileName: 'custom', filePath: 'old' }, false), + ).toEqual({ fileName: 'custom', filePath: '/static/chunks' }); + expect(normalizeManifestOptions(true, true)).toEqual({ filePath: '' }); + }); +}); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.ts new file mode 100644 index 00000000000..bcc162eaf85 --- /dev/null +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/manifest-options.ts @@ -0,0 +1,16 @@ +import type { moduleFederationPlugin } from '@module-federation/sdk'; + +type ManifestOptions = + moduleFederationPlugin.ModuleFederationPluginOptions['manifest']; + +export const normalizeManifestOptions = ( + manifest: ManifestOptions, + isServer: boolean, +): ManifestOptions => { + if (manifest === false) return false; + + return { + ...(typeof manifest === 'object' && manifest !== null ? manifest : {}), + filePath: isServer ? '' : '/static/chunks', + }; +}; diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts index 97fa2a49be7..642443fe5fc 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/next-fragments.ts @@ -137,7 +137,6 @@ export interface NextFederationPluginExtraOptions { skipSharingNextInternals?: boolean; automaticPageStitching?: boolean; debug?: boolean; - skipFederatedStats?: boolean; } export interface NextFederationPluginOptions diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts deleted file mode 100644 index 9540c8f2e29..00000000000 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { setOptions } from './set-options'; - -describe('setOptions', () => { - it('generates federated stats by default', () => { - const { extraOptions } = setOptions({ - name: 'host', - extraOptions: {}, - }); - - expect(extraOptions.skipFederatedStats).toBe(false); - }); - - it('preserves an explicit federated stats opt-out', () => { - const { extraOptions } = setOptions({ - name: 'host', - extraOptions: { skipFederatedStats: true }, - }); - - expect(extraOptions.skipFederatedStats).toBe(true); - }); -}); diff --git a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts index 27f22d5518f..924b04bb090 100644 --- a/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts +++ b/packages/nextjs-mf/src/plugins/NextFederationPlugin/set-options.ts @@ -20,7 +20,6 @@ export function setOptions(options: NextFederationPluginOptions): { enableUrlLoaderFix: false, skipSharingNextInternals: false, debug: false, - skipFederatedStats: false, }; return { diff --git a/packages/node/src/__tests__/flush-chunks.test.ts b/packages/node/src/__tests__/flush-chunks.test.ts new file mode 100644 index 00000000000..221910fc277 --- /dev/null +++ b/packages/node/src/__tests__/flush-chunks.test.ts @@ -0,0 +1,327 @@ +import { flushChunks, usedChunks } from '../utils/flush-chunks'; + +const remoteEntry = + 'https://cdn.example.com/_next/static/ssr/remoteEntry.js?token=test'; + +const setKnownRemote = ( + remoteInfo: Record = {}, + configuredEntry = remoteEntry, +) => { + (globalThis as any).__FEDERATION__ = { + __INSTANCES__: [ + { + moduleCache: new Map([ + [ + 'shop', + { + remoteInfo: { + name: 'shop', + entry: remoteEntry, + ...remoteInfo, + }, + }, + ], + ]), + options: { + remotes: [ + { + name: 'shop', + alias: remoteInfo.alias, + entry: configuredEntry, + }, + ], + }, + }, + ], + }; +}; + +const jsonResponse = (body: unknown) => ({ + ok: true, + status: 200, + json: jest.fn().mockResolvedValue(body), +}); + +describe('flushChunks', () => { + beforeEach(() => { + usedChunks.clear(); + setKnownRemote(); + global.fetch = jest.fn(); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('loads manifest assets once per remote', async () => { + (global.fetch as jest.Mock).mockResolvedValue( + jsonResponse({ + metaData: { publicPath: 'auto' }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { + sync: ['static/chunks/shared.js', 'static/chunks/button.js'], + async: ['static/chunks/lazy.js'], + }, + css: { + sync: ['static/css/button.css'], + async: ['static/css/lazy.css'], + }, + }, + }, + { + name: 'Card', + path: './Card', + assets: { + js: { + sync: ['static/chunks/shared.js', 'static/chunks/card.js'], + async: [], + }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + usedChunks.add('shop/Card'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://cdn.example.com/_next/static/chunks/shared.js', + 'https://cdn.example.com/_next/static/chunks/button.js', + 'https://cdn.example.com/_next/static/css/button.css', + 'https://cdn.example.com/_next/static/chunks/card.js', + ]); + expect(global.fetch).toHaveBeenCalledTimes(1); + expect(global.fetch).toHaveBeenCalledWith( + 'https://cdn.example.com/_next/static/chunks/mf-manifest.json?token=test', + ); + expect(usedChunks.size).toBe(0); + }); + + it('honors an absolute manifest public path', async () => { + (global.fetch as jest.Mock).mockResolvedValue( + jsonResponse({ + metaData: { publicPath: 'https://assets.example.com/app/' }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: ['button.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ); + usedChunks.add('shop->Button'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://assets.example.com/app/button.js', + ]); + }); + + it('uses the server public path during SSR', async () => { + (global.fetch as jest.Mock).mockResolvedValue( + jsonResponse({ + metaData: { + publicPath: 'auto', + ssrPublicPath: 'https://server.example.com', + }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: ['button.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://server.example.com/button.js', + ]); + }); + + it('uses the configured manifest URL retained by the runtime', async () => { + const manifestUrl = + 'https://cdn.example.com/custom/remote-metadata.json?token=test'; + setKnownRemote({}, manifestUrl); + (global.fetch as jest.Mock).mockResolvedValue( + jsonResponse({ + metaData: { + getPublicPath: "function () { return 'https://assets.example.com'; }", + }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: ['button.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://assets.example.com/button.js', + ]); + expect(global.fetch).toHaveBeenCalledWith(manifestUrl); + }); + + it('groups canonical and nested alias requests for the same remote', async () => { + setKnownRemote({ alias: 'store/catalog' }); + (global.fetch as jest.Mock).mockResolvedValue( + jsonResponse({ + metaData: { publicPath: 'auto' }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: ['static/chunks/button.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + { + name: 'Card', + path: './Card', + assets: { + js: { sync: ['static/chunks/card.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ); + usedChunks.add('store/catalog/Button'); + usedChunks.add('shop/Card'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://cdn.example.com/_next/static/chunks/button.js', + 'https://cdn.example.com/_next/static/chunks/card.js', + ]); + expect(global.fetch).toHaveBeenCalledTimes(1); + }); + + it('uses legacy stats for requests missing from the manifest', async () => { + (global.fetch as jest.Mock) + .mockResolvedValueOnce( + jsonResponse({ + metaData: { publicPath: 'auto' }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: ['static/chunks/button.js'], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ) + .mockResolvedValueOnce( + jsonResponse({ + federatedModules: [ + { + exposes: { + './Card': ['static/chunks/card.js'], + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + usedChunks.add('shop/Card'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://cdn.example.com/_next/static/chunks/button.js', + 'https://cdn.example.com/_next/static/chunks/card.js', + ]); + expect(global.fetch).toHaveBeenCalledTimes(2); + }); + + it('uses legacy stats when a manifest expose has no analyzed assets', async () => { + (global.fetch as jest.Mock) + .mockResolvedValueOnce( + jsonResponse({ + metaData: { publicPath: 'auto' }, + exposes: [ + { + name: 'Button', + path: './Button', + assets: { + js: { sync: [], async: [] }, + css: { sync: [], async: [] }, + }, + }, + ], + }), + ) + .mockResolvedValueOnce( + jsonResponse({ + federatedModules: [ + { + exposes: { + './Button': ['static/chunks/button.js'], + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://cdn.example.com/_next/static/chunks/button.js', + ]); + expect(global.fetch).toHaveBeenCalledTimes(2); + }); + + it('falls back to federated stats for older remotes', async () => { + (global.fetch as jest.Mock) + .mockResolvedValueOnce({ ok: false, status: 404 }) + .mockResolvedValueOnce( + jsonResponse({ + federatedModules: [ + { + exposes: { + './Button': ['static/chunks/button.js'], + }, + }, + ], + }), + ); + usedChunks.add('shop/Button'); + + await expect(flushChunks()).resolves.toEqual([ + 'https://cdn.example.com/_next/static/chunks/button.js', + ]); + expect(global.fetch).toHaveBeenNthCalledWith( + 2, + 'https://cdn.example.com/_next/static/chunks/federated-stats.json?token=test', + ); + }); + + it('reports unknown remotes without fetching metadata', async () => { + const error = jest.spyOn(console, 'error').mockImplementation(); + usedChunks.add('missing/Button'); + + await expect(flushChunks()).resolves.toEqual([]); + expect(global.fetch).not.toHaveBeenCalled(); + expect(error).toHaveBeenCalledWith( + 'flush chunks: Remote missing is not defined in the global config', + ); + }); +}); diff --git a/packages/node/src/utils/flush-chunks.ts b/packages/node/src/utils/flush-chunks.ts index 49729e17dc6..f03b839ddab 100644 --- a/packages/node/src/utils/flush-chunks.ts +++ b/packages/node/src/utils/flush-chunks.ts @@ -1,5 +1,20 @@ /* eslint-disable no-undef */ +import { getResourceUrl, type Manifest } from '@module-federation/sdk'; +import type { RemoteInfo } from '@module-federation/runtime/types'; + +type LegacyFederatedStats = { + federatedModules?: Array<{ + exposes?: Record; + }>; +}; + +type RemoteRequests = { + remoteInfo: RemoteInfo; + manifestUrl?: string; + requests: Set; +}; + // @ts-ignore if (!globalThis.usedChunks) { // @ts-ignore @@ -11,176 +26,194 @@ if (!globalThis.usedChunks) { */ // @ts-ignore export const { usedChunks } = globalThis; -/** - * Load hostStats from the JSON file. - * @returns {object} hostStats - An object containing host stats data. - */ -const loadHostStats = () => { - try { - //@ts-ignore - return __non_webpack_require__('../federated-stats.json'); - } catch (e) { - return {}; - } -}; +const getFederationController = () => + new Function('return globalThis')().__FEDERATION__; -export const getAllKnownRemotes = function () { - // Attempt to access the global federation controller safely - const federationController = new Function('return globalThis')() - .__FEDERATION__; +export const getAllKnownRemotes = function (): Record { + const federationController = getFederationController(); if (!federationController || !federationController.__INSTANCES__) { - // If the federation controller or instances are not defined, return an empty object return {}; } - var collected = {}; - // Use a for...of loop to iterate over all federation instances + const collected: Record = {}; for (const instance of federationController.__INSTANCES__) { - // Use another for...of loop to iterate over the module cache Map entries - for (const [key, cacheModule] of instance.moduleCache) { - // Check if the cacheModule has remoteInfo and use it to collect remote names + for (const [, cacheModule] of instance.moduleCache) { if (cacheModule.remoteInfo) { - //@ts-ignore - collected[cacheModule.remoteInfo.name] = cacheModule.remoteInfo; + const remoteInfo = cacheModule.remoteInfo as RemoteInfo; + collected[remoteInfo.name] = remoteInfo; + if (remoteInfo.alias) collected[remoteInfo.alias] = remoteInfo; } } } return collected; }; -/** - * Create a shareMap based on the loaded modules. - * @returns {object} shareMap - An object containing the shareMap data. - */ -const createShareMap = () => { - // Check if __webpack_share_scopes__ is defined and has a default property - // @ts-ignore - if (__webpack_share_scopes__?.default) { - // Reduce the keys of the default property to create the share map - // @ts-ignore - return Object.keys(__webpack_share_scopes__.default).reduce((acc, key) => { - // @ts-ignore - const shareMap = __webpack_share_scopes__.default[key]; - // shareScope may equal undefined or null if it has unexpected value - if (!shareMap || typeof shareMap !== 'object') { - return acc; +const getConfiguredManifestUrls = (): Map => { + const manifestUrls = new Map(); + const federationController = getFederationController(); + + for (const instance of federationController?.__INSTANCES__ || []) { + for (const configuredRemote of instance.options?.remotes || []) { + if (!('entry' in configuredRemote)) continue; + try { + if (!new URL(configuredRemote.entry).pathname.endsWith('.json')) { + continue; + } + } catch { + continue; } - // Get the loaded modules for the current key - const loadedModules = Object.values(shareMap) - // Filter out the modules that are not loaded - // @ts-ignore - .filter((sharedModule) => sharedModule.loaded) - // Map the filtered modules to their 'from' properties - // @ts-ignore - .map((sharedModule) => sharedModule.from); - - // If there are any loaded modules, add them to the accumulator object - if (loadedModules.length > 0) { - // @ts-ignore - acc[key] = loadedModules; + manifestUrls.set(configuredRemote.name, configuredRemote.entry); + if (configuredRemote.alias) { + manifestUrls.set(configuredRemote.alias, configuredRemote.entry); } - // Return the accumulator object for the next iteration - return acc; - }, {}); + } } - // If __webpack_share_scopes__ is not defined or doesn't have a default property, return an empty object - return {}; + + return manifestUrls; }; -/** - * Process a single chunk and return an array of updated chunks. - * @param {string} chunk - A chunk string containing remote and request data. - * @param {object} shareMap - An object containing the shareMap data. - * @param {object} hostStats - An object containing host stats data. - * @returns {Promise} A promise that resolves to an array of updated chunks. - */ -// @ts-ignore -const processChunk = async (chunk, shareMap, hostStats) => { - const chunks = new Set(); - const normalizedChunk = chunk.includes('->') - ? chunk.replace('->', '/') - : chunk; - const remoteSeparatorIndex = normalizedChunk.indexOf('/'); +const parseUsedChunk = ( + chunk: string, + remoteNames: string[], +): [remote: string, request: string] => { + const normalizedChunk = chunk.replace('->', '/'); const remote = - remoteSeparatorIndex === -1 - ? normalizedChunk - : normalizedChunk.slice(0, remoteSeparatorIndex); - const req = - remoteSeparatorIndex === -1 - ? '' - : normalizedChunk.slice(remoteSeparatorIndex + 1); - const request = req?.startsWith('./') ? req : './' + req; - const knownRemotes = getAllKnownRemotes(); - //@ts-ignore - if (!knownRemotes[remote]) { - console.error( - `flush chunks: Remote ${remote} is not defined in the global config`, - ); - return; - } + remoteNames.find( + (name) => + normalizedChunk === name || normalizedChunk.startsWith(`${name}/`), + ) || normalizedChunk.split('/', 1)[0]; + const request = normalizedChunk.slice(remote.length).replace(/^\//, ''); + return [remote, request.startsWith('./') ? request : `./${request}`]; +}; - try { - //@ts-ignore - const remoteName = new URL(knownRemotes[remote].entry).pathname - .split('/') - .pop(); - //@ts-ignore - - const statsFile = knownRemotes[remote].entry - .replace(remoteName, 'federated-stats.json') - .replace('ssr', 'chunks'); - let stats = {}; - - try { - stats = await fetch(statsFile).then((res) => res.json()); - } catch (e) { - console.error('flush error', e); - } - //@ts-ignore +const getMetadataUrl = (entry: string, filename: string): string => { + const url = new URL(entry); + url.pathname = `${url.pathname.slice(0, url.pathname.lastIndexOf('/') + 1)}${filename}`; + url.pathname = url.pathname.replace('/ssr/', '/chunks/'); + return url.href; +}; - const [prefix] = knownRemotes[remote].entry.split('static/'); - //@ts-ignore +const getManifestUrl = ( + remoteInfo: RemoteInfo, + configuredManifestUrl?: string, +): string => { + if (configuredManifestUrl) return configuredManifestUrl; + return getMetadataUrl(remoteInfo.entry, 'mf-manifest.json'); +}; - if (stats.federatedModules) { - //@ts-ignore +const getAssetBaseUrl = (metadataUrl: string): URL => { + const baseUrl = new URL(metadataUrl); + const staticPathIndex = baseUrl.pathname.indexOf('/static/'); + baseUrl.pathname = + staticPathIndex === -1 + ? baseUrl.pathname.slice(0, baseUrl.pathname.lastIndexOf('/') + 1) + : baseUrl.pathname.slice(0, staticPathIndex + 1); + baseUrl.search = ''; + baseUrl.hash = ''; + return baseUrl; +}; - stats.federatedModules.forEach((modules) => { - if (modules.exposes?.[request]) { - //@ts-ignore +const fetchJson = async (url: string): Promise => { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Request failed with status ${response.status}`); + } + return response.json() as Promise; +}; - modules.exposes[request].forEach((chunk) => { - chunks.add([prefix, chunk].join('')); +const collectManifestAssets = ( + manifest: Manifest, + manifestUrl: string, + requests: Set, +): { chunks: string[]; missingRequests: Set } => { + const chunks = new Set(); + const missingRequests = new Set(requests); + let assetBaseUrl = getAssetBaseUrl(manifestUrl); + const resourceBasePath = getResourceUrl(manifest.metaData, ''); - Object.values(chunk).forEach((chunk) => { - //@ts-ignore + if (resourceBasePath !== 'auto') { + const normalizedBasePath = + resourceBasePath && !resourceBasePath.endsWith('/') + ? `${resourceBasePath}/` + : resourceBasePath || './'; + assetBaseUrl = new URL(normalizedBasePath, manifestUrl); + } - if (chunk.files) { - //@ts-ignore + const resolveAssetUrl = (file: string) => new URL(file, assetBaseUrl).href; - chunk.files.forEach((file) => { - chunks.add(prefix + file); - }); - } - //@ts-ignore + for (const expose of manifest.exposes) { + const request = expose.path || `./${expose.name}`; + if (!requests.has(request)) continue; - if (chunk.requiredModules) { - //@ts-ignore + const hasSyncAssets = + expose.assets.js.sync.length > 0 || expose.assets.css.sync.length > 0; + if (hasSyncAssets) missingRequests.delete(request); - chunk.requiredModules.forEach((module) => { - if (shareMap[module]) { - // If the module is from the host, log the host stats - } - }); - } - }); - }); - } - }); + for (const file of expose.assets.js.sync) { + chunks.add(resolveAssetUrl(file)); + } + for (const file of expose.assets.css.sync) { + chunks.add(resolveAssetUrl(file)); } + } + + return { chunks: Array.from(chunks), missingRequests }; +}; + +const collectLegacyAssets = ( + stats: LegacyFederatedStats, + statsUrl: string, + requests: Set, +): string[] => { + const chunks = new Set(); + const assetBaseUrl = getAssetBaseUrl(statsUrl); + + for (const federatedModule of stats.federatedModules || []) { + for (const request of requests) { + for (const file of federatedModule.exposes?.[request] || []) { + chunks.add(new URL(file, assetBaseUrl).href); + } + } + } + + return Array.from(chunks); +}; + +const processRemote = async ( + remoteInfo: RemoteInfo, + requests: Set, + configuredManifestUrl?: string, +): Promise => { + const manifestUrl = getManifestUrl(remoteInfo, configuredManifestUrl); + let manifestChunks: string[] = []; + let legacyRequests = requests; - return Array.from(chunks); - } catch (e) { - console.error('flush error:', e); + try { + const manifest = await fetchJson(manifestUrl); + const { chunks, missingRequests } = collectManifestAssets( + manifest, + manifestUrl, + requests, + ); + manifestChunks = chunks; + if (!missingRequests.size) return chunks; + legacyRequests = missingRequests; + } catch { + // Older remotes may only expose federated-stats.json. + } + + const statsUrl = getMetadataUrl(remoteInfo.entry, 'federated-stats.json'); + try { + const stats = await fetchJson(statsUrl); + return Array.from( + new Set([ + ...manifestChunks, + ...collectLegacyAssets(stats, statsUrl, legacyRequests), + ]), + ); + } catch (error) { + if (!manifestChunks.length) console.error('flush error:', error); + return manifestChunks; } }; @@ -188,21 +221,43 @@ const processChunk = async (chunk, shareMap, hostStats) => { * Flush the chunks and return a deduplicated array of chunks. * @returns {Promise} A promise that resolves to an array of deduplicated chunks. */ -export const flushChunks = async () => { - const hostStats = loadHostStats(); - const shareMap = createShareMap(); +export const flushChunks = async (): Promise => { + const knownRemotes = getAllKnownRemotes(); + const configuredManifestUrls = getConfiguredManifestUrls(); + const remoteNames = Object.keys(knownRemotes).sort( + (left, right) => right.length - left.length, + ); + const requestsByRemote = new Map(); + + for (const chunk of usedChunks) { + const [remote, request] = parseUsedChunk(chunk, remoteNames); + const remoteInfo = knownRemotes[remote]; + if (!remoteInfo) { + console.error( + `flush chunks: Remote ${remote} is not defined in the global config`, + ); + continue; + } + + const remoteRequests = requestsByRemote.get(remoteInfo.name) || { + remoteInfo, + manifestUrl: + configuredManifestUrls.get(remote) || + configuredManifestUrls.get(remoteInfo.name), + requests: new Set(), + }; + remoteRequests.requests.add(request); + requestsByRemote.set(remoteInfo.name, remoteRequests); + } + usedChunks.clear(); const allFlushed = await Promise.all( - Array.from(usedChunks).map(async (chunk) => - processChunk(chunk, shareMap, hostStats), + Array.from( + requestsByRemote.values(), + ({ remoteInfo, requests, manifestUrl }) => + processRemote(remoteInfo, requests, manifestUrl), ), ); - // Deduplicate the chunks array - const dedupe = Array.from(new Set([...allFlushed.flat()])); - - // Clear usedChunks - usedChunks.clear(); - // Filter out any undefined or null values - return dedupe.filter(Boolean); + return Array.from(new Set(allFlushed.flat())); }; diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index eb49198b819..495f87bbd24 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -177,7 +177,16 @@ const generateShareFilename = (pkgName: string, withExt: boolean): string => { return encodeName(pkgName, '__federation_shared_', withExt); }; -const getResourceUrl = (module: ModuleInfo, sourceUrl: string): string => { +type ResourceUrlInfo = + | { getPublicPath: string } + | { publicPath: string; ssrPublicPath?: string }; + +function getResourceUrl(module: ModuleInfo, sourceUrl: string): string; +function getResourceUrl(module: ResourceUrlInfo, sourceUrl: string): string; +function getResourceUrl( + module: ModuleInfo | ResourceUrlInfo, + sourceUrl: string, +): string { if ('getPublicPath' in module) { let publicPath; @@ -206,7 +215,7 @@ const getResourceUrl = (module: ModuleInfo, sourceUrl: string): string => { ); return ''; } -}; +} // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types const assert = (condition: any, msg: string): asserts condition => { diff --git a/packages/utilities/src/types/index.ts b/packages/utilities/src/types/index.ts index ddf3124020b..aaa5f788c80 100644 --- a/packages/utilities/src/types/index.ts +++ b/packages/utilities/src/types/index.ts @@ -42,7 +42,6 @@ export interface NextFederationPluginExtraOptions { skipSharingNextInternals?: boolean; automaticPageStitching?: boolean; debug?: boolean; - skipFederatedStats?: boolean; } export interface NextFederationPluginOptions extends ModuleFederationPluginOptions { From c203d59417278354a5869aea101543639d4ac63d Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Sat, 18 Jul 2026 15:09:10 +0200 Subject: [PATCH 31/37] feat(bridge): add server-rendered bridge islands --- .changeset/bridge-ssr-v1.md | 7 + .github/workflows/e2e-bridge-ssr.yml | 45 + .prettierignore | 3 + apps/bridge-ssr-demo/.gitignore | 3 + apps/bridge-ssr-demo/README.md | 22 + apps/bridge-ssr-demo/host-vue/package.json | 31 + .../host-vue/playwright.config.ts | 25 + .../host-vue/rsbuild.config.ts | 49 + apps/bridge-ssr-demo/host-vue/server.mjs | 11 + apps/bridge-ssr-demo/host-vue/src/App.vue | 65 + .../host-vue/src/entry.client.ts | 13 + .../host-vue/src/entry.server.ts | 29 + apps/bridge-ssr-demo/host-vue/src/env.d.ts | 4 + apps/bridge-ssr-demo/host-vue/src/index.html | 11 + .../host-vue/src/prepareSSRContext.ts | 51 + .../host-vue/src/remoteApps.ts | 5 + .../host-vue/src/ssrContext.ts | 19 + apps/bridge-ssr-demo/host-vue/tsconfig.json | 12 + .../host/e2e/bridge-ssr-browser.spec.ts | 97 ++ .../host/e2e/bridge-ssr-nojs.spec.ts | 19 + apps/bridge-ssr-demo/host/e2e/fixtures.ts | 24 + apps/bridge-ssr-demo/host/package.json | 35 + .../bridge-ssr-demo/host/playwright.config.ts | 25 + apps/bridge-ssr-demo/host/public/.gitkeep | 0 apps/bridge-ssr-demo/host/rsbuild.config.ts | 109 ++ apps/bridge-ssr-demo/host/server.mjs | 11 + apps/bridge-ssr-demo/host/src/App.tsx | 75 ++ apps/bridge-ssr-demo/host/src/bootstrap.tsx | 13 + .../bridge-ssr-demo/host/src/entry.client.tsx | 22 + .../bridge-ssr-demo/host/src/entry.server.tsx | 33 + apps/bridge-ssr-demo/host/src/env.d.ts | 23 + apps/bridge-ssr-demo/host/src/index.html | 11 + apps/bridge-ssr-demo/host/src/index.tsx | 1 + .../host/src/lib/hostSsrContext.ts | 21 + .../host/src/lib/normalizeRequestUrl.d.mts | 4 + .../host/src/lib/normalizeRequestUrl.mjs | 30 + .../host/src/lib/prepareSSRContext.ts | 35 + .../host/src/lib/remoteApps.tsx | 11 + .../host/src/lib/remoteRoutes.ts | 31 + .../host/src/lib/ssrContext.ts | 6 + .../host/src/lib/useHostSsrContext.ts | 39 + apps/bridge-ssr-demo/host/tsconfig.json | 15 + .../bridge-ssr-demo/remote-react/package.json | 26 + .../remote-react/rsbuild.config.ts | 124 ++ apps/bridge-ssr-demo/remote-react/src/App.tsx | 72 + .../remote-react/src/bootstrap.tsx | 10 + .../bridge-ssr-demo/remote-react/src/env.d.ts | 1 + .../remote-react/src/export-app.server.tsx | 26 + .../remote-react/src/export-app.tsx | 20 + .../remote-react/src/index.tsx | 1 + .../remote-react/src/ssr-env.ts | 6 + .../remote-react/tsconfig.json | 15 + apps/bridge-ssr-demo/remote-vue/package.json | 29 + .../remote-vue/rsbuild.config.ts | 93 ++ .../remote-vue/src/RemoteVueApplication.vue | 20 + .../remote-vue/src/export-app.server.ts | 32 + .../remote-vue/src/export-app.ts | 26 + .../bridge-ssr-demo/remote-vue/src/index.html | 11 + .../remote-vue/src/pages/Detail.vue | 6 + .../remote-vue/src/pages/Home.vue | 16 + .../bridge-ssr-demo/remote-vue/src/ssr-env.ts | 6 + .../remote-vue/src/standalone.ts | 15 + apps/bridge-ssr-demo/remote-vue/tsconfig.json | 13 + .../remote-vue/vite.config.mts | 51 + .../shared/createHostServer.mjs | 106 ++ apps/bridge-ssr-demo/shared/devHost.ts | 17 + apps/bridge-ssr-demo/shared/package.json | 11 + .../shared/pluginServeSsrDist.ts | 63 + apps/bridge-ssr-demo/shared/routerAlias.ts | 14 + apps/bridge-ssr-demo/shared/serveDist.mjs | 19 + .../docs/en/guide/bridge/_meta.json | 5 + apps/website-new/docs/en/guide/bridge/ssr.mdx | 55 + package.json | 3 + packages/bridge/bridge-react/package.json | 11 +- .../provider/versions/bridge-base.spec.tsx | 47 + .../src/provider/versions/bridge-base.tsx | 132 +- .../src/provider/versions/bridge-render.tsx | 54 + .../src/provider/versions/bridge-server.tsx | 68 + .../src/provider/versions/server-renderer.ts | 8 + .../src/provider/versions/v18.server.ts | 17 + .../bridge-react/src/provider/versions/v18.ts | 3 +- .../src/remote/RemoteAppWrapper.tsx | 27 +- .../bridge-react/src/remote/createHelpers.tsx | 19 +- .../bridge/bridge-react/src/router/static.tsx | 52 + .../bridge/bridge-react/src/router/v6.tsx | 12 + packages/bridge/bridge-react/src/types.ts | 33 +- .../bridge/bridge-react/src/v18.server.ts | 9 + packages/bridge/bridge-react/src/v18.ts | 1 + packages/bridge/bridge-react/vite.config.ts | 1 + packages/bridge/bridge-shared/package.json | 2 + packages/bridge/bridge-shared/src/index.ts | 24 + .../bridge-shared/src/renderRemoteBridge.ts | 92 ++ packages/bridge/bridge-shared/src/ssr.spec.ts | 75 ++ packages/bridge/bridge-shared/src/ssr.ts | 175 +++ packages/bridge/bridge-shared/src/type.ts | 66 + packages/bridge/vue3-bridge/package.json | 25 +- packages/bridge/vue3-bridge/rstest.config.ts | 5 + .../bridge/vue3-bridge/src/index.server.ts | 16 + .../bridge/vue3-bridge/src/provider.spec.ts | 46 + packages/bridge/vue3-bridge/src/provider.ts | 247 +++- packages/bridge/vue3-bridge/src/remoteApp.tsx | 26 +- .../bridge/vue3-bridge/src/server-renderer.ts | 7 + packages/bridge/vue3-bridge/vite.config.ts | 16 +- pnpm-lock.yaml | 1196 +++++++++++------ pnpm-workspace.yaml | 1 + tools/scripts/ci-local.mjs | 21 + tools/scripts/run-bridge-ssr-e2e.mjs | 212 +++ .../verify-bridge-ssr-browser-bundles.mjs | 49 + 108 files changed, 4213 insertions(+), 589 deletions(-) create mode 100644 .changeset/bridge-ssr-v1.md create mode 100644 .github/workflows/e2e-bridge-ssr.yml create mode 100644 apps/bridge-ssr-demo/.gitignore create mode 100644 apps/bridge-ssr-demo/README.md create mode 100644 apps/bridge-ssr-demo/host-vue/package.json create mode 100644 apps/bridge-ssr-demo/host-vue/playwright.config.ts create mode 100644 apps/bridge-ssr-demo/host-vue/rsbuild.config.ts create mode 100644 apps/bridge-ssr-demo/host-vue/server.mjs create mode 100644 apps/bridge-ssr-demo/host-vue/src/App.vue create mode 100644 apps/bridge-ssr-demo/host-vue/src/entry.client.ts create mode 100644 apps/bridge-ssr-demo/host-vue/src/entry.server.ts create mode 100644 apps/bridge-ssr-demo/host-vue/src/env.d.ts create mode 100644 apps/bridge-ssr-demo/host-vue/src/index.html create mode 100644 apps/bridge-ssr-demo/host-vue/src/prepareSSRContext.ts create mode 100644 apps/bridge-ssr-demo/host-vue/src/remoteApps.ts create mode 100644 apps/bridge-ssr-demo/host-vue/src/ssrContext.ts create mode 100644 apps/bridge-ssr-demo/host-vue/tsconfig.json create mode 100644 apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts create mode 100644 apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts create mode 100644 apps/bridge-ssr-demo/host/e2e/fixtures.ts create mode 100644 apps/bridge-ssr-demo/host/package.json create mode 100644 apps/bridge-ssr-demo/host/playwright.config.ts create mode 100644 apps/bridge-ssr-demo/host/public/.gitkeep create mode 100644 apps/bridge-ssr-demo/host/rsbuild.config.ts create mode 100644 apps/bridge-ssr-demo/host/server.mjs create mode 100644 apps/bridge-ssr-demo/host/src/App.tsx create mode 100644 apps/bridge-ssr-demo/host/src/bootstrap.tsx create mode 100644 apps/bridge-ssr-demo/host/src/entry.client.tsx create mode 100644 apps/bridge-ssr-demo/host/src/entry.server.tsx create mode 100644 apps/bridge-ssr-demo/host/src/env.d.ts create mode 100644 apps/bridge-ssr-demo/host/src/index.html create mode 100644 apps/bridge-ssr-demo/host/src/index.tsx create mode 100644 apps/bridge-ssr-demo/host/src/lib/hostSsrContext.ts create mode 100644 apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.d.mts create mode 100644 apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.mjs create mode 100644 apps/bridge-ssr-demo/host/src/lib/prepareSSRContext.ts create mode 100644 apps/bridge-ssr-demo/host/src/lib/remoteApps.tsx create mode 100644 apps/bridge-ssr-demo/host/src/lib/remoteRoutes.ts create mode 100644 apps/bridge-ssr-demo/host/src/lib/ssrContext.ts create mode 100644 apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts create mode 100644 apps/bridge-ssr-demo/host/tsconfig.json create mode 100644 apps/bridge-ssr-demo/remote-react/package.json create mode 100644 apps/bridge-ssr-demo/remote-react/rsbuild.config.ts create mode 100644 apps/bridge-ssr-demo/remote-react/src/App.tsx create mode 100644 apps/bridge-ssr-demo/remote-react/src/bootstrap.tsx create mode 100644 apps/bridge-ssr-demo/remote-react/src/env.d.ts create mode 100644 apps/bridge-ssr-demo/remote-react/src/export-app.server.tsx create mode 100644 apps/bridge-ssr-demo/remote-react/src/export-app.tsx create mode 100644 apps/bridge-ssr-demo/remote-react/src/index.tsx create mode 100644 apps/bridge-ssr-demo/remote-react/src/ssr-env.ts create mode 100644 apps/bridge-ssr-demo/remote-react/tsconfig.json create mode 100644 apps/bridge-ssr-demo/remote-vue/package.json create mode 100644 apps/bridge-ssr-demo/remote-vue/rsbuild.config.ts create mode 100644 apps/bridge-ssr-demo/remote-vue/src/RemoteVueApplication.vue create mode 100644 apps/bridge-ssr-demo/remote-vue/src/export-app.server.ts create mode 100644 apps/bridge-ssr-demo/remote-vue/src/export-app.ts create mode 100644 apps/bridge-ssr-demo/remote-vue/src/index.html create mode 100644 apps/bridge-ssr-demo/remote-vue/src/pages/Detail.vue create mode 100644 apps/bridge-ssr-demo/remote-vue/src/pages/Home.vue create mode 100644 apps/bridge-ssr-demo/remote-vue/src/ssr-env.ts create mode 100644 apps/bridge-ssr-demo/remote-vue/src/standalone.ts create mode 100644 apps/bridge-ssr-demo/remote-vue/tsconfig.json create mode 100644 apps/bridge-ssr-demo/remote-vue/vite.config.mts create mode 100644 apps/bridge-ssr-demo/shared/createHostServer.mjs create mode 100644 apps/bridge-ssr-demo/shared/devHost.ts create mode 100644 apps/bridge-ssr-demo/shared/package.json create mode 100644 apps/bridge-ssr-demo/shared/pluginServeSsrDist.ts create mode 100644 apps/bridge-ssr-demo/shared/routerAlias.ts create mode 100644 apps/bridge-ssr-demo/shared/serveDist.mjs create mode 100644 apps/website-new/docs/en/guide/bridge/ssr.mdx create mode 100644 packages/bridge/bridge-react/src/provider/versions/bridge-base.spec.tsx create mode 100644 packages/bridge/bridge-react/src/provider/versions/bridge-render.tsx create mode 100644 packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx create mode 100644 packages/bridge/bridge-react/src/provider/versions/server-renderer.ts create mode 100644 packages/bridge/bridge-react/src/provider/versions/v18.server.ts create mode 100644 packages/bridge/bridge-react/src/router/static.tsx create mode 100644 packages/bridge/bridge-react/src/v18.server.ts create mode 100644 packages/bridge/bridge-shared/src/renderRemoteBridge.ts create mode 100644 packages/bridge/bridge-shared/src/ssr.spec.ts create mode 100644 packages/bridge/bridge-shared/src/ssr.ts create mode 100644 packages/bridge/vue3-bridge/src/index.server.ts create mode 100644 packages/bridge/vue3-bridge/src/provider.spec.ts create mode 100644 packages/bridge/vue3-bridge/src/server-renderer.ts create mode 100644 tools/scripts/run-bridge-ssr-e2e.mjs create mode 100644 tools/scripts/verify-bridge-ssr-browser-bundles.mjs diff --git a/.changeset/bridge-ssr-v1.md b/.changeset/bridge-ssr-v1.md new file mode 100644 index 00000000000..d7aa1efd2e8 --- /dev/null +++ b/.changeset/bridge-ssr-v1.md @@ -0,0 +1,7 @@ +--- +'@module-federation/bridge-shared': patch +'@module-federation/bridge-react': patch +'@module-federation/bridge-vue3': patch +--- + +add a thin buffered Bridge SSR contract with remote-owned React 18 and Vue 3 rendering, host-passed hydration payloads, instance-scoped mount markers, and contextual server-render failures diff --git a/.github/workflows/e2e-bridge-ssr.yml b/.github/workflows/e2e-bridge-ssr.yml new file mode 100644 index 00000000000..9cb1a7a5595 --- /dev/null +++ b/.github/workflows/e2e-bridge-ssr.yml @@ -0,0 +1,45 @@ +name: E2E Test for Bridge SSR + +on: + pull_request: + paths: + - 'packages/bridge/**' + - 'apps/bridge-ssr-demo/**' + - 'tools/scripts/*bridge-ssr*' + - '.github/workflows/e2e-bridge-ssr.yml' + - 'pnpm-lock.yaml' + +concurrency: + group: e2e-bridge-ssr-${{ github.ref }} + cancel-in-progress: true + +jobs: + rsbuild: + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: '20' + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm run build:packages + - run: pnpm run e2e:bridge:ssr + - run: pnpm run e2e:bridge:ssr:production + + vite-smoke: + runs-on: ubuntu-latest + timeout-minutes: 30 + continue-on-error: true + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + with: + node-version: '20' + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm run build:packages + - run: pnpm run e2e:bridge:ssr:vite-smoke diff --git a/.prettierignore b/.prettierignore index a9e2bf4e1d4..70683db1d6b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -8,6 +8,9 @@ pnpm-lock.yaml **/dist/** **/dist-rslib/** +**/dist-vite/** +**/playwright-report/** +**/test-results/** apps/website-new/docs packages/treeshake-server/template/** diff --git a/apps/bridge-ssr-demo/.gitignore b/apps/bridge-ssr-demo/.gitignore new file mode 100644 index 00000000000..a7fe3c62b30 --- /dev/null +++ b/apps/bridge-ssr-demo/.gitignore @@ -0,0 +1,3 @@ +**/dist-vite/ +**/test-results/ +**/playwright-report/ diff --git a/apps/bridge-ssr-demo/README.md b/apps/bridge-ssr-demo/README.md new file mode 100644 index 00000000000..2b33c2f014d --- /dev/null +++ b/apps/bridge-ssr-demo/README.md @@ -0,0 +1,22 @@ +# Bridge SSR V1 acceptance demo + +This focused demo proves buffered, application-level Bridge SSR in both cross-framework directions: + +- React 18 host → Vue 3 remote +- Vue 3 host → React 18 remote + +The server host calls `renderRemoteBridge`, carries the complete result in its normal SSR payload, and renders the same instance-scoped mount attributes on the server and client. The remote hydrates that mount when the payload and markers match; client navigation without a payload uses the existing CSR path. + +Client and Node builds expose the same `./export-app` key from different source files. Preparation and the framework server renderer stay in the Node graph; hydration mapping stays browser-safe. + +Run from the repository root: + +```bash +pnpm run e2e:bridge:ssr +pnpm run e2e:bridge:ssr:production +pnpm run e2e:bridge:ssr:vite-smoke +``` + +Rsbuild development and production are required. The Vite command is a non-blocking React-host → Vue-remote smoke proof. The suites cover raw HTML, hydration, deep routes, host and remote navigation, CSR mounting, multiple independent instances, browser/server error monitoring, and exclusion of server-only renderers and preparation from browser bundles. + +Assets and head management, response status/headers, fallbacks, timeouts, hydration recovery registries, data routers, streaming, and framework adapters are intentionally outside V1. diff --git a/apps/bridge-ssr-demo/host-vue/package.json b/apps/bridge-ssr-demo/host-vue/package.json new file mode 100644 index 00000000000..50dd19c626d --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/package.json @@ -0,0 +1,31 @@ +{ + "name": "bridge-ssr-host-vue", + "private": true, + "version": "0.0.1", + "scripts": { + "dev": "NODE_OPTIONS=--experimental-vm-modules node ./server.mjs", + "build": "rsbuild build", + "serve:production": "NODE_OPTIONS=--experimental-vm-modules BRIDGE_SSR_MODE=production node ./server.mjs", + "e2e:ssr:ci": "node ../../../scripts/ensure-playwright.js && playwright test --config playwright.config.ts --reporter=line" + }, + "dependencies": { + "@module-federation/bridge-react": "workspace:*", + "@module-federation/bridge-shared": "workspace:*", + "@module-federation/bridge-vue3": "workspace:*", + "@module-federation/enhanced": "workspace:*", + "@module-federation/runtime": "workspace:*", + "@vue/server-renderer": "^3.5.30", + "express": "^4.21.2", + "react": "18.3.1", + "react-dom": "18.3.1", + "vue": "^3.5.30", + "vue-router": "4.4.5" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "workspace:*", + "@playwright/test": "1.57.0", + "@rsbuild/core": "1.7.3", + "@rsbuild/plugin-vue": "^1.2.6", + "typescript": "~5.0.4" + } +} diff --git a/apps/bridge-ssr-demo/host-vue/playwright.config.ts b/apps/bridge-ssr-demo/host-vue/playwright.config.ts new file mode 100644 index 00000000000..db2de20c99a --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/playwright.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: '../host/e2e', + timeout: 60_000, + fullyParallel: false, + retries: process.env.CI ? 2 : 0, + workers: 1, + use: { + baseURL: process.env.BRIDGE_SSR_VUE_BASE_URL ?? 'http://localhost:2303', + trace: 'on-first-retry', + ...devices['Desktop Chrome'], + }, + projects: [ + { + name: 'vue-host-nojs', + testMatch: /bridge-ssr-nojs\.spec\.ts/, + use: { javaScriptEnabled: false }, + }, + { + name: 'vue-host-browser', + testMatch: /bridge-ssr-browser\.spec\.ts/, + }, + ], +}); diff --git a/apps/bridge-ssr-demo/host-vue/rsbuild.config.ts b/apps/bridge-ssr-demo/host-vue/rsbuild.config.ts new file mode 100644 index 00000000000..318329e9621 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/rsbuild.config.ts @@ -0,0 +1,49 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginVue } from '@rsbuild/plugin-vue'; +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { + bridgeSsrHostUrl, + bridgeSsrRemotePort, + bridgeSsrServerManifestPath, +} from '../shared/devHost'; + +const reactOrigin = bridgeSsrHostUrl(bridgeSsrRemotePort('react')); +const webRemotes = { + bridge_ssr_react: `bridge_ssr_react@${reactOrigin}/mf-manifest.json`, +}; +const ssrRemotes = { + bridge_ssr_react: `bridge_ssr_react@${reactOrigin}/${bridgeSsrServerManifestPath}`, +}; +const shared = { + vue: { singleton: true, eager: true }, + 'vue-router': { singleton: true, eager: true }, + react: { singleton: true, eager: true }, + 'react-dom': { singleton: true, eager: true }, +}; + +export default defineConfig({ + performance: { buildCache: false }, + server: { port: 2303, cors: true, middlewareMode: true }, + environments: { + client: { + source: { entry: { index: './src/entry.client.ts' } }, + html: { template: './src/index.html' }, + output: { distPath: { root: 'dist' } }, + }, + ssr: { + source: { entry: { index: './src/entry.server.ts' } }, + output: { target: 'node', distPath: { root: 'dist/ssr' } }, + }, + }, + plugins: [ + pluginVue(), + pluginModuleFederation( + { name: 'bridge_ssr_vue_host', remotes: webRemotes, shared }, + { environment: 'client' }, + ), + pluginModuleFederation( + { name: 'bridge_ssr_vue_host', remotes: ssrRemotes, shared }, + { target: 'node', environment: 'ssr' }, + ), + ], +}); diff --git a/apps/bridge-ssr-demo/host-vue/server.mjs b/apps/bridge-ssr-demo/host-vue/server.mjs new file mode 100644 index 00000000000..69bf42e65b0 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/server.mjs @@ -0,0 +1,11 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { startBridgeHost } from '../shared/createHostServer.mjs'; + +const rootDir = path.dirname(fileURLToPath(import.meta.url)); +startBridgeHost({ rootDir, port: 2303, label: 'bridge-ssr-vue-host' }).catch( + (error) => { + console.error('[bridge-ssr-vue-host] failed:', error); + process.exitCode = 1; + }, +); diff --git a/apps/bridge-ssr-demo/host-vue/src/App.vue b/apps/bridge-ssr-demo/host-vue/src/App.vue new file mode 100644 index 00000000000..aaa0d334d81 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/App.vue @@ -0,0 +1,65 @@ + + + diff --git a/apps/bridge-ssr-demo/host-vue/src/entry.client.ts b/apps/bridge-ssr-demo/host-vue/src/entry.client.ts new file mode 100644 index 00000000000..e83cec85dfa --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/entry.client.ts @@ -0,0 +1,13 @@ +import { createSSRApp } from 'vue'; +import { createRouter, createWebHistory } from 'vue-router'; +import App from './App.vue'; +import { readHostSSRContext } from './ssrContext'; + +const router = createRouter({ + history: createWebHistory(), + routes: [{ path: '/:pathMatch(.*)*', component: App }], +}); +const app = createSSRApp(App, { ssrContext: readHostSSRContext() }); +app.use(router); +await router.isReady(); +app.mount('#root'); diff --git a/apps/bridge-ssr-demo/host-vue/src/entry.server.ts b/apps/bridge-ssr-demo/host-vue/src/entry.server.ts new file mode 100644 index 00000000000..5da8cd99a98 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/entry.server.ts @@ -0,0 +1,29 @@ +import { createSSRApp } from 'vue'; +import { renderToString } from '@vue/server-renderer'; +import { createMemoryHistory, createRouter } from 'vue-router'; +import App from './App.vue'; +import { + prepareSSRContext, + type PrepareSSRContextOptions, +} from './prepareSSRContext'; + +async function createHostApp(url: string, options: PrepareSSRContextOptions) { + const ssrContext = await prepareSSRContext(url, options); + const router = createRouter({ + history: createMemoryHistory(), + routes: [{ path: '/:pathMatch(.*)*', component: App }], + }); + await router.push(url); + await router.isReady(); + const app = createSSRApp(App, { ssrContext }); + app.use(router); + return { app, ssrContext }; +} + +export async function render( + url: string, + options: PrepareSSRContextOptions = {}, +) { + const { app, ssrContext } = await createHostApp(url, options); + return { html: await renderToString(app), ssrContext }; +} diff --git a/apps/bridge-ssr-demo/host-vue/src/env.d.ts b/apps/bridge-ssr-demo/host-vue/src/env.d.ts new file mode 100644 index 00000000000..c736914276c --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/env.d.ts @@ -0,0 +1,4 @@ +/// + +declare module 'bridge_ssr_react/export-app'; +declare module 'bridge_ssr_vue/export-app'; diff --git a/apps/bridge-ssr-demo/host-vue/src/index.html b/apps/bridge-ssr-demo/host-vue/src/index.html new file mode 100644 index 00000000000..edf442c4adf --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/index.html @@ -0,0 +1,11 @@ + + + + + + Bridge SSR Vue Host + + +

+ + diff --git a/apps/bridge-ssr-demo/host-vue/src/prepareSSRContext.ts b/apps/bridge-ssr-demo/host-vue/src/prepareSSRContext.ts new file mode 100644 index 00000000000..97af22acd50 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/prepareSSRContext.ts @@ -0,0 +1,51 @@ +import { getInstance } from '@module-federation/runtime'; +import { renderRemoteBridge } from '@module-federation/bridge-shared'; +import { normalizeBridgeRequestUrl } from '../../host/src/lib/normalizeRequestUrl.mjs'; +import type { HostSSRContext } from './ssrContext'; + +export type PrepareSSRContextOptions = { signal?: AbortSignal }; + +export async function prepareSSRContext( + url: string, + options: PrepareSSRContextOptions = {}, +): Promise { + const requestUrl = normalizeBridgeRequestUrl(url); + const parsed = new URL(requestUrl, 'http://bridge-ssr.local'); + const context: HostSSRContext = { url: requestUrl }; + const instance = getInstance(); + if (!instance) + throw new Error('Module Federation runtime is not initialized'); + const request = new Request(parsed, { signal: options.signal }); + + const renderReact = ( + instanceId: string, + basename: string, + name: string, + age: number, + ) => + renderRemoteBridge({ + loader: () => + instance.loadRemote>( + 'bridge_ssr_react/export-app', + ), + moduleName: 'bridge_ssr_react', + instanceId, + request, + props: { basename, name, age }, + }); + + if (parsed.pathname.startsWith('/react-pair')) { + context.reactPair = await Promise.all([ + renderReact('react-pair-left', '/react-pair', 'Left', 1), + renderReact('react-pair-right', '/react-pair', 'Right', 2), + ]); + } else if (parsed.pathname.startsWith('/react-remote')) { + context.reactRemote = await renderReact( + 'react-primary', + '/react-remote', + 'Ming', + 12, + ); + } + return context; +} diff --git a/apps/bridge-ssr-demo/host-vue/src/remoteApps.ts b/apps/bridge-ssr-demo/host-vue/src/remoteApps.ts new file mode 100644 index 00000000000..0ffa9858501 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/remoteApps.ts @@ -0,0 +1,5 @@ +import { createRemoteAppComponent } from '@module-federation/bridge-vue3'; + +export const RemoteReactApp = createRemoteAppComponent({ + loader: () => import('bridge_ssr_react/export-app'), +}); diff --git a/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts b/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts new file mode 100644 index 00000000000..52d784a2610 --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts @@ -0,0 +1,19 @@ +import type { BridgeSSRResult } from '@module-federation/bridge-shared'; + +export type HostSSRContext = { + url: string; + reactRemote?: BridgeSSRResult; + reactPair?: [BridgeSSRResult, BridgeSSRResult]; +}; + +export const HOST_SSR_CONTEXT_SCRIPT_ID = 'bridge-ssr-host-context'; + +export function readHostSSRContext() { + const script = document.getElementById(HOST_SSR_CONTEXT_SCRIPT_ID); + if (!script?.textContent) return undefined; + try { + return JSON.parse(script.textContent) as HostSSRContext; + } catch { + return undefined; + } +} diff --git a/apps/bridge-ssr-demo/host-vue/tsconfig.json b/apps/bridge-ssr-demo/host-vue/tsconfig.json new file mode 100644 index 00000000000..8a26c51abfb --- /dev/null +++ b/apps/bridge-ssr-demo/host-vue/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "skipLibCheck": true, + "allowJs": true, + "types": ["node"] + }, + "include": ["src", "rsbuild.config.ts", "playwright.config.ts"] +} diff --git a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts new file mode 100644 index 00000000000..113abff34e3 --- /dev/null +++ b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts @@ -0,0 +1,97 @@ +import { expect, test } from './fixtures'; + +const direction = (projectName: string) => + projectName.startsWith('vue-host') + ? { + route: '/react-remote', + detail: '/react-remote/detail', + homeHeading: 'React Remote Home', + detailHeading: 'React Remote Detail', + counter: '.react-remote-counter', + detailLink: '.react-remote-detail-link', + hostLink: '.host-react-remote-link', + } + : { + route: '/vue-remote', + detail: '/vue-remote/detail', + homeHeading: 'Vue Remote Home', + detailHeading: 'Vue Remote Detail', + counter: '.vue-remote-counter', + detailLink: '.vue-remote-detail-link', + hostLink: '.host-vue-remote-link', + }; + +test('hydrates the direct SSR island and remains interactive', async ({ + page, +}, testInfo) => { + const remote = direction(testInfo.project.name); + await page.goto(remote.route); + await expect( + page.getByRole('heading', { name: remote.homeHeading }), + ).toBeVisible(); + const mount = page.locator('[data-mf-bridge-ssr="true"]'); + await expect(mount).toHaveCount(1); + const counter = page.locator(remote.counter); + await counter.click(); + await expect(counter).toHaveText(/Count: 1/); +}); + +test('server-renders a deep route and remote navigation updates the URL', async ({ + page, +}, testInfo) => { + const remote = direction(testInfo.project.name); + await page.goto(remote.detail); + await expect( + page.getByRole('heading', { name: remote.detailHeading }), + ).toBeVisible(); + await page.goto(remote.route); + await page.locator(remote.detailLink).click(); + await expect(page).toHaveURL(new RegExp(`${remote.detail}$`)); + await expect( + page.getByRole('heading', { name: remote.detailHeading }), + ).toBeVisible(); +}); + +test('host navigation enters, leaves, and returns through CSR without reload', async ({ + page, +}, testInfo) => { + const remote = direction(testInfo.project.name); + await page.goto('/'); + await page.evaluate(() => { + ( + window as Window & { __navigationSentinel?: string } + ).__navigationSentinel = 'alive'; + }); + await page.locator(remote.hostLink).first().click(); + await expect( + page.getByRole('heading', { name: remote.homeHeading }), + ).toBeVisible(); + await page.getByRole('link', { name: 'Home' }).first().click(); + await expect(page).toHaveURL(/\/$/); + await page.locator(remote.hostLink).first().click(); + await expect( + page.getByRole('heading', { name: remote.homeHeading }), + ).toBeVisible(); + await expect + .poll(() => page.evaluate(() => (window as any).__navigationSentinel)) + .toBe('alive'); +}); + +test('two instances of one React remote hydrate independently', async ({ + page, +}, testInfo) => { + test.skip(!testInfo.project.name.startsWith('vue-host')); + await page.goto('/react-pair'); + const mounts = page.locator('[data-mf-bridge-ssr="true"]'); + await expect(mounts).toHaveCount(2); + const ids = await mounts.evaluateAll((nodes) => + nodes.map((node) => node.getAttribute('data-mf-bridge-instance')), + ); + expect(new Set(ids).size).toBe(2); + const counters = page.locator('.react-remote-counter'); + await counters.nth(0).click(); + await expect(counters.nth(0)).toHaveText('Count: 1'); + await expect(counters.nth(1)).toHaveText('Count: 0'); + await expect(page.getByText('name: Left, age: 1')).toBeVisible(); + await expect(page.getByText('name: Right, age: 2')).toBeVisible(); +}); diff --git a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts new file mode 100644 index 00000000000..5628de49bbd --- /dev/null +++ b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts @@ -0,0 +1,19 @@ +import { expect, test } from '@playwright/test'; + +test('raw response contains the cross-framework remote route', async ({ + page, + request, +}, testInfo) => { + const vueHost = testInfo.project.name.startsWith('vue-host'); + const route = vueHost ? '/react-remote/detail' : '/vue-remote/detail'; + const heading = vueHost ? 'React Remote Detail' : 'Vue Remote Detail'; + const response = await request.get(route); + const html = await response.text(); + expect(response.ok()).toBeTruthy(); + expect(html).toContain(heading); + expect(html).toContain('data-mf-bridge-ssr="true"'); + expect(html).toContain('bridge-ssr-host-context'); + + await page.goto(route); + await expect(page.getByRole('heading', { name: heading })).toBeVisible(); +}); diff --git a/apps/bridge-ssr-demo/host/e2e/fixtures.ts b/apps/bridge-ssr-demo/host/e2e/fixtures.ts new file mode 100644 index 00000000000..5fe4e8bfd83 --- /dev/null +++ b/apps/bridge-ssr-demo/host/e2e/fixtures.ts @@ -0,0 +1,24 @@ +import { expect, test as base } from '@playwright/test'; + +export const test = base.extend({ + page: async ({ page }, use) => { + const browserErrors: string[] = []; + page.on('console', (message) => { + const text = message.text(); + if ( + message.type() === 'error' || + (message.type() === 'warning' && + /hydration|hydrate|did not match|mount|mismatch|recoverable/i.test( + text, + )) + ) { + browserErrors.push(text); + } + }); + page.on('pageerror', (error) => browserErrors.push(error.message)); + await use(page); + expect(browserErrors, 'unexpected browser errors').toEqual([]); + }, +}); + +export { expect }; diff --git a/apps/bridge-ssr-demo/host/package.json b/apps/bridge-ssr-demo/host/package.json new file mode 100644 index 00000000000..195929df962 --- /dev/null +++ b/apps/bridge-ssr-demo/host/package.json @@ -0,0 +1,35 @@ +{ + "name": "bridge-ssr-host", + "private": true, + "version": "0.0.1", + "scripts": { + "dev": "NODE_OPTIONS=--experimental-vm-modules node ./server.mjs", + "build": "rsbuild build", + "preview": "rsbuild preview", + "serve": "pnpm run dev", + "serve:production": "NODE_OPTIONS=--experimental-vm-modules BRIDGE_SSR_MODE=production node ./server.mjs", + "e2e:ssr": "node ../../../scripts/ensure-playwright.js && playwright test", + "e2e:ssr:ci": "node ../../../scripts/ensure-playwright.js && playwright test --reporter=line" + }, + "dependencies": { + "@module-federation/bridge-react": "workspace:*", + "@module-federation/bridge-shared": "workspace:*", + "@module-federation/enhanced": "workspace:*", + "express": "^4.21.2", + "react": "~18.3.1", + "react-dom": "~18.3.1", + "react-router-dom": "6.30.2", + "vue": "^3.5.30", + "vue-router": "4.4.5" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "workspace:*", + "@rsbuild/core": "1.7.3", + "@rsbuild/plugin-react": "^1.4.5", + "@types/express": "^4.17.21", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.3.0", + "@playwright/test": "1.57.0", + "typescript": "~5.0.4" + } +} diff --git a/apps/bridge-ssr-demo/host/playwright.config.ts b/apps/bridge-ssr-demo/host/playwright.config.ts new file mode 100644 index 00000000000..2d5ba9852f6 --- /dev/null +++ b/apps/bridge-ssr-demo/host/playwright.config.ts @@ -0,0 +1,25 @@ +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + testDir: './e2e', + timeout: 60_000, + fullyParallel: false, + retries: process.env.CI ? 2 : 0, + workers: 1, + use: { + baseURL: process.env.BRIDGE_SSR_BASE_URL ?? 'http://localhost:2300', + trace: 'on-first-retry', + ...devices['Desktop Chrome'], + }, + projects: [ + { + name: 'react-host-nojs', + testMatch: /bridge-ssr-nojs\.spec\.ts/, + use: { javaScriptEnabled: false }, + }, + { + name: 'react-host-browser', + testMatch: /bridge-ssr-browser\.spec\.ts/, + }, + ], +}); diff --git a/apps/bridge-ssr-demo/host/public/.gitkeep b/apps/bridge-ssr-demo/host/public/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/apps/bridge-ssr-demo/host/rsbuild.config.ts b/apps/bridge-ssr-demo/host/rsbuild.config.ts new file mode 100644 index 00000000000..4778e56b240 --- /dev/null +++ b/apps/bridge-ssr-demo/host/rsbuild.config.ts @@ -0,0 +1,109 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import path from 'path'; +import { + bridgeSsrHostUrl, + bridgeSsrRemotePort, + bridgeSsrServerManifestPath, +} from '../shared/devHost'; + +const vueRemoteOrigin = bridgeSsrHostUrl(bridgeSsrRemotePort('vue')); + +const clientRuntimePlugins = [ + require.resolve('@module-federation/bridge-react/plugin'), +]; + +const ssrRuntimePlugins = [ + require.resolve('@module-federation/bridge-react/plugin'), +]; + +const shared = { + react: { singleton: true, eager: true }, + 'react-dom': { singleton: true, eager: true }, + vue: { singleton: true, eager: true }, + 'vue-router': { singleton: true, eager: true }, +}; + +const ssrShared = { + react: { singleton: true, eager: true }, + 'react-dom': { singleton: true, eager: true }, + vue: { singleton: true, eager: true }, + 'vue-router': { singleton: true, eager: true }, +}; + +const webRemotes = { + bridge_ssr_vue: `bridge_ssr_vue@${vueRemoteOrigin}/mf-manifest.json`, +}; + +const ssrRemotes = { + bridge_ssr_vue: `bridge_ssr_vue@${vueRemoteOrigin}/${bridgeSsrServerManifestPath}`, +}; + +export default defineConfig({ + performance: { buildCache: false }, + resolve: { + alias: { + react: path.resolve(__dirname, 'node_modules/react'), + 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'), + }, + }, + server: { + port: 2300, + cors: true, + middlewareMode: true, + }, + environments: { + client: { + source: { + entry: { + index: './src/entry.client.tsx', + }, + }, + html: { + template: './src/index.html', + }, + output: { + distPath: { + root: 'dist', + }, + }, + }, + ssr: { + source: { + entry: { + index: './src/entry.server.tsx', + }, + }, + output: { + target: 'node', + distPath: { + root: 'dist/ssr', + }, + }, + }, + }, + plugins: [ + pluginReact(), + pluginModuleFederation( + { + name: 'bridge_ssr_host', + shareStrategy: 'loaded-first', + remotes: webRemotes, + shared, + runtimePlugins: clientRuntimePlugins, + }, + { environment: 'client' }, + ), + pluginModuleFederation( + { + name: 'bridge_ssr_host', + shareStrategy: 'loaded-first', + remotes: ssrRemotes, + shared: ssrShared, + runtimePlugins: ssrRuntimePlugins, + }, + { target: 'node', environment: 'ssr' }, + ), + ], +}); diff --git a/apps/bridge-ssr-demo/host/server.mjs b/apps/bridge-ssr-demo/host/server.mjs new file mode 100644 index 00000000000..f52a629c0a1 --- /dev/null +++ b/apps/bridge-ssr-demo/host/server.mjs @@ -0,0 +1,11 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { startBridgeHost } from '../shared/createHostServer.mjs'; + +const rootDir = path.dirname(fileURLToPath(import.meta.url)); +startBridgeHost({ rootDir, port: 2300, label: 'bridge-ssr-react-host' }).catch( + (error) => { + console.error('[bridge-ssr-react-host] failed:', error); + process.exitCode = 1; + }, +); diff --git a/apps/bridge-ssr-demo/host/src/App.tsx b/apps/bridge-ssr-demo/host/src/App.tsx new file mode 100644 index 00000000000..4f552b830f2 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/App.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { Link, Route, Routes } from 'react-router-dom'; +import { RemoteVueApp } from './lib/remoteApps'; +import { VUE_REMOTE_BASENAME, VUE_REMOTE_MODULE } from './lib/remoteRoutes'; +import type { HostSSRContext } from './lib/ssrContext'; +import { useHostSsrContext } from './lib/useHostSsrContext'; + +type AppProps = { + ssrContext?: HostSSRContext; +}; + +const Layout = ({ children }: { children: React.ReactNode }) => ( +
+ + {children} +
+); + +const Home = () => ( +
+

Bridge SSR Host

+

+ Direct visits are server-rendered. In-app navigation is instant on the + client — federated remotes load and hydrate through the bridge without a + document reload (Nuxt-style takeover). +

+
    +
  • + + Vue Remote (federated SSR on direct visit) + +
  • +
+
+); + +const VueRemotePage = ({ ssrContext }: { ssrContext?: HostSSRContext }) => ( +
+

Vue Remote

+ +
+); + +const AppRoutes = ({ ssrContext }: { ssrContext?: HostSSRContext }) => ( + + } /> + } + /> + +); + +const App = ({ ssrContext: initialSsrContext }: AppProps) => { + const { ssrContext } = useHostSsrContext(initialSsrContext); + + return ( + + + + ); +}; + +export default App; diff --git a/apps/bridge-ssr-demo/host/src/bootstrap.tsx b/apps/bridge-ssr-demo/host/src/bootstrap.tsx new file mode 100644 index 00000000000..9e2c30be810 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/bootstrap.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { BrowserRouter } from 'react-router-dom'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')!); +root.render( + + + + + , +); diff --git a/apps/bridge-ssr-demo/host/src/entry.client.tsx b/apps/bridge-ssr-demo/host/src/entry.client.tsx new file mode 100644 index 00000000000..c006d63a909 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/entry.client.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { hydrateRoot } from 'react-dom/client'; +import { BrowserRouter } from 'react-router-dom'; +import App from './App'; +import { readHostSSRContextFromDocument } from './lib/hostSsrContext'; + +async function bootstrap() { + const ssrContext = readHostSSRContextFromDocument(); + hydrateRoot( + document.getElementById('root')!, + + + , + ); +} + +const bootstrapPromise = bootstrap(); +( + window as Window & { __BRIDGE_SSR_BOOTSTRAP__?: Promise } +).__BRIDGE_SSR_BOOTSTRAP__ = bootstrapPromise; + +void bootstrapPromise; diff --git a/apps/bridge-ssr-demo/host/src/entry.server.tsx b/apps/bridge-ssr-demo/host/src/entry.server.tsx new file mode 100644 index 00000000000..3ffb09399c3 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/entry.server.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { renderToString } from 'react-dom/server'; +import { StaticRouter } from 'react-router-dom/server'; +import App from './App'; +import { + prepareSSRContext, + type PrepareSSRContextOptions, +} from './lib/prepareSSRContext'; + +export { prepareSSRContext as getSSRContext }; + +function createHostTree( + url: string, + ssrContext: Awaited>, +) { + return ( + + + + ); +} + +/** String rendering remains available to focused tests and non-streaming consumers. */ +export async function render( + url: string, + options: PrepareSSRContextOptions = {}, +) { + const ssrContext = await prepareSSRContext(url, options); + return { + html: renderToString(createHostTree(url, ssrContext)), + ssrContext, + }; +} diff --git a/apps/bridge-ssr-demo/host/src/env.d.ts b/apps/bridge-ssr-demo/host/src/env.d.ts new file mode 100644 index 00000000000..69f2a7d3d5c --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/env.d.ts @@ -0,0 +1,23 @@ +/// + +declare module 'bridge_ssr_react/export-app' { + const provider: () => { + render: (info: Record) => void | Promise; + destroy: (info: { dom: HTMLElement }) => void; + renderToString?: ( + info: Record, + ) => Promise<{ html: string; state?: Record }>; + }; + export default provider; +} + +declare module 'bridge_ssr_vue/export-app' { + const provider: () => { + render: (info: Record) => void | Promise; + destroy: (info: { dom: HTMLElement }) => void; + renderToString?: ( + info: Record, + ) => Promise<{ html: string; state?: Record }>; + }; + export default provider; +} diff --git a/apps/bridge-ssr-demo/host/src/index.html b/apps/bridge-ssr-demo/host/src/index.html new file mode 100644 index 00000000000..e983dbe344a --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/index.html @@ -0,0 +1,11 @@ + + + + + + Bridge SSR Host + + +
+ + diff --git a/apps/bridge-ssr-demo/host/src/index.tsx b/apps/bridge-ssr-demo/host/src/index.tsx new file mode 100644 index 00000000000..b93c7a0268a --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/index.tsx @@ -0,0 +1 @@ +import('./bootstrap'); diff --git a/apps/bridge-ssr-demo/host/src/lib/hostSsrContext.ts b/apps/bridge-ssr-demo/host/src/lib/hostSsrContext.ts new file mode 100644 index 00000000000..a789b87cf7f --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/hostSsrContext.ts @@ -0,0 +1,21 @@ +import type { HostSSRContext } from './ssrContext'; + +// Kept in sync with server.mjs, which injects the script server-side. +export const HOST_SSR_CONTEXT_SCRIPT_ID = 'bridge-ssr-host-context'; + +export function readHostSSRContextFromDocument(): HostSSRContext | undefined { + if (typeof document === 'undefined') { + return undefined; + } + + const script = document.getElementById(HOST_SSR_CONTEXT_SCRIPT_ID); + if (!script?.textContent) { + return undefined; + } + + try { + return JSON.parse(script.textContent) as HostSSRContext; + } catch { + return undefined; + } +} diff --git a/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.d.mts b/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.d.mts new file mode 100644 index 00000000000..40a1f869740 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.d.mts @@ -0,0 +1,4 @@ +export function normalizeBridgeRequestUrl( + url: string, + fallback?: string, +): string; diff --git a/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.mjs b/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.mjs new file mode 100644 index 00000000000..41e6660fcce --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/normalizeRequestUrl.mjs @@ -0,0 +1,30 @@ +/** + * Restrict request URLs to same-origin pathnames with search for SSR routing. + * + * Single source of truth shared by the Express server (`server.mjs`) and the + * bundled host code (`prepareSSRContext.ts`). + * + * @param {string} url + * @param {string} [fallback] + * @returns {string} + */ +export function normalizeBridgeRequestUrl(url, fallback = '/') { + if (!url || typeof url !== 'string') { + return fallback; + } + + const trimmed = url.trim(); + if ( + /^[a-zA-Z][a-zA-Z\d+.-]*:\/\//.test(trimmed) || + trimmed.startsWith('//') + ) { + return fallback; + } + + const withoutHash = trimmed.split('#')[0] ?? ''; + const pathname = withoutHash.startsWith('/') + ? withoutHash + : `/${withoutHash}`; + + return pathname || fallback; +} diff --git a/apps/bridge-ssr-demo/host/src/lib/prepareSSRContext.ts b/apps/bridge-ssr-demo/host/src/lib/prepareSSRContext.ts new file mode 100644 index 00000000000..5d227b1cf5a --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/prepareSSRContext.ts @@ -0,0 +1,35 @@ +import { getInstance } from '@module-federation/runtime'; +import { renderRemoteBridge } from '@module-federation/bridge-shared'; +import type { HostSSRContext } from './ssrContext'; +import { normalizeBridgeRequestUrl } from './normalizeRequestUrl.mjs'; +import { VUE_REMOTE_BASENAME, VUE_REMOTE_MODULE } from './remoteRoutes'; + +export type PrepareSSRContextOptions = { signal?: AbortSignal }; + +export async function prepareSSRContext( + url: string, + options: PrepareSSRContextOptions = {}, +): Promise { + const requestUrl = normalizeBridgeRequestUrl(url); + const pathname = new URL(requestUrl, 'http://bridge-ssr.local').pathname; + const context: HostSSRContext = { url: requestUrl }; + if (!pathname.startsWith(VUE_REMOTE_BASENAME)) return context; + + const instance = getInstance(); + if (!instance) + throw new Error('Module Federation runtime is not initialized'); + const request = new Request(`http://bridge-ssr.local${requestUrl}`, { + signal: options.signal, + }); + context.vueRemote = await renderRemoteBridge({ + loader: () => + instance.loadRemote>( + `${VUE_REMOTE_MODULE}/export-app`, + ), + moduleName: VUE_REMOTE_MODULE, + instanceId: 'vue-primary', + request, + props: { basename: VUE_REMOTE_BASENAME, test: 'vue-ssr' }, + }); + return context; +} diff --git a/apps/bridge-ssr-demo/host/src/lib/remoteApps.tsx b/apps/bridge-ssr-demo/host/src/lib/remoteApps.tsx new file mode 100644 index 00000000000..ce3705b4393 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/remoteApps.tsx @@ -0,0 +1,11 @@ +import { createRemoteAppComponent } from '@module-federation/bridge-react'; + +export const vueRemoteLoader = () => import('bridge_ssr_vue/export-app'); + +export const RemoteVueApp = createRemoteAppComponent({ + loader: vueRemoteLoader, + loading:
Loading Vue remote...
, + fallback: ({ error }: { error: Error }) => ( +
Vue remote error: {error.message}
+ ), +}); diff --git a/apps/bridge-ssr-demo/host/src/lib/remoteRoutes.ts b/apps/bridge-ssr-demo/host/src/lib/remoteRoutes.ts new file mode 100644 index 00000000000..6d97b207d9c --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/remoteRoutes.ts @@ -0,0 +1,31 @@ +import type { HostSSRContext } from './ssrContext'; + +export const VUE_REMOTE_BASENAME = '/vue-remote'; +export const VUE_REMOTE_MODULE = 'bridge_ssr_vue'; + +export function isVueRemotePath(pathname: string) { + return pathname.startsWith(VUE_REMOTE_BASENAME); +} + +/** + * Keep SSR payload only when it matches the active URL and remote route. + * Client navigations without a document reload use CSR (no remote SSR fields). + */ +export function resolveHostSsrContextForLocation( + locationUrl: string, + pathname: string, + seed?: HostSSRContext, +): HostSSRContext { + const context: HostSSRContext = { url: locationUrl }; + const seedPath = seed?.url?.split('?')[0]?.split('#')[0]; + + if (!seed || seedPath !== pathname) { + return context; + } + + if (isVueRemotePath(pathname) && seed.vueRemote) { + context.vueRemote = seed.vueRemote; + } + + return context; +} diff --git a/apps/bridge-ssr-demo/host/src/lib/ssrContext.ts b/apps/bridge-ssr-demo/host/src/lib/ssrContext.ts new file mode 100644 index 00000000000..e2f18d057bf --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/ssrContext.ts @@ -0,0 +1,6 @@ +import type { BridgeSSRResult } from '@module-federation/bridge-shared'; + +export type HostSSRContext = { + url: string; + vueRemote?: BridgeSSRResult; +}; diff --git a/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts b/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts new file mode 100644 index 00000000000..89873221f46 --- /dev/null +++ b/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts @@ -0,0 +1,39 @@ +import { useMemo } from 'react'; +import { useLocation } from 'react-router-dom'; +import { readHostSSRContextFromDocument } from './hostSsrContext'; +import { resolveHostSsrContextForLocation } from './remoteRoutes'; +import type { HostSSRContext } from './ssrContext'; + +function getLocationUrl(pathname: string, search: string) { + return `${pathname}${search}`; +} + +/** + * Nuxt-style SSR takeover: + * - Direct visit / hard refresh: use SSR payload embedded in the document (or passed from server render). + * - Client-side navigations: no document reload; remotes mount via federated CSR + bridge hydrate. + */ +export function useHostSsrContext(initialContext?: HostSSRContext) { + const location = useLocation(); + const locationUrl = getLocationUrl(location.pathname, location.search); + const documentContext = useMemo(() => readHostSSRContextFromDocument(), []); + + const seedContext = + initialContext?.url?.split('?')[0]?.split('#')[0] === location.pathname + ? initialContext + : documentContext?.url?.split('?')[0]?.split('#')[0] === location.pathname + ? documentContext + : undefined; + + const ssrContext = useMemo( + () => + resolveHostSsrContextForLocation( + locationUrl, + location.pathname, + seedContext, + ), + [location.pathname, locationUrl, seedContext], + ); + + return { ssrContext }; +} diff --git a/apps/bridge-ssr-demo/host/tsconfig.json b/apps/bridge-ssr-demo/host/tsconfig.json new file mode 100644 index 00000000000..3519d14e252 --- /dev/null +++ b/apps/bridge-ssr-demo/host/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["DOM", "ES2020"], + "module": "ESNext", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true + }, + "include": ["src"] +} diff --git a/apps/bridge-ssr-demo/remote-react/package.json b/apps/bridge-ssr-demo/remote-react/package.json new file mode 100644 index 00000000000..9b2c14adaac --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/package.json @@ -0,0 +1,26 @@ +{ + "name": "bridge-ssr-remote-react", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "rsbuild dev", + "build": "rsbuild build", + "preview": "rsbuild preview", + "serve": "pnpm run dev" + }, + "dependencies": { + "@module-federation/bridge-react": "workspace:*", + "react": "~18.3.1", + "react-dom": "~18.3.1", + "react-router-dom": "6.30.2" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "workspace:*", + "@rsbuild/core": "1.7.3", + "@rsbuild/plugin-react": "^1.4.5", + "@types/react": "~18.2.0", + "@types/react-dom": "~18.3.0", + "typescript": "~5.0.4" + } +} diff --git a/apps/bridge-ssr-demo/remote-react/rsbuild.config.ts b/apps/bridge-ssr-demo/remote-react/rsbuild.config.ts new file mode 100644 index 00000000000..81bb920a46d --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/rsbuild.config.ts @@ -0,0 +1,124 @@ +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { defineConfig } from '@rsbuild/core'; +import { pluginReact } from '@rsbuild/plugin-react'; +import path from 'path'; +import { createBridgeRouterAlias } from '../shared/routerAlias'; +import { pluginServeSsrDist } from '../shared/pluginServeSsrDist'; +import { bridgeSsrHostUrl } from '../shared/devHost'; + +const remoteOrigin = bridgeSsrHostUrl(2301); + +const runtimePlugins = [ + require.resolve('@module-federation/bridge-react/plugin'), +]; + +const shared = { + react: { singleton: true }, + 'react-dom': { singleton: true }, +}; + +const mfOptions = { + name: 'bridge_ssr_react', + runtimePlugins, + exposes: { + './export-app': './src/export-app.tsx', + }, + shared, + dts: false, + getPublicPath: `return '${remoteOrigin}/'`, +}; + +const ssrMfOptions = { + ...mfOptions, + exposes: { + './export-app': './src/export-app.server.tsx', + }, + // The server remote owns a matching React + renderer pair. Sharing either + // with the host would reintroduce cross-version renderer coupling. + shared: {}, + getPublicPath: `return '${remoteOrigin}/ssr/'`, +}; + +export default defineConfig({ + performance: { buildCache: false }, + resolve: { + alias: { + react: path.resolve(__dirname, 'node_modules/react'), + 'react-dom': path.resolve(__dirname, 'node_modules/react-dom'), + }, + }, + server: { + port: 2301, + cors: true, + }, + dev: { + assetPrefix: remoteOrigin, + writeToDisk: true, + }, + tools: { + rspack: (config) => { + delete config.optimization?.splitChunks; + }, + }, + environments: { + web: { + source: { + entry: { + index: './src/index.tsx', + }, + }, + output: { + distPath: { + root: 'dist', + }, + }, + tools: { + rspack: (config) => { + config.resolve ??= {}; + config.resolve.alias = { + ...(config.resolve.alias as Record), + ...createBridgeRouterAlias( + path.resolve(__dirname, 'node_modules/react-router-dom'), + ), + }; + }, + }, + }, + ssr: { + source: { + entry: { + index: './src/ssr-env.ts', + }, + }, + output: { + target: 'node', + distPath: { + root: 'dist/ssr', + }, + emitAssets: true, + }, + tools: { + rspack: (config) => { + config.output ??= {}; + config.output.publicPath = `${remoteOrigin}/ssr/`; + config.resolve ??= {}; + config.resolve.alias = { + ...(config.resolve.alias as Record), + ...createBridgeRouterAlias( + path.resolve(__dirname, 'node_modules/react-router-dom'), + ), + }; + }, + }, + }, + }, + plugins: [ + pluginReact(), + pluginServeSsrDist(__dirname), + pluginModuleFederation(mfOptions, { environment: 'web' }), + pluginModuleFederation(ssrMfOptions, { + target: 'node', + environment: 'ssr', + }), + ], +}); diff --git a/apps/bridge-ssr-demo/remote-react/src/App.tsx b/apps/bridge-ssr-demo/remote-react/src/App.tsx new file mode 100644 index 00000000000..cdf4bf13d2f --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/App.tsx @@ -0,0 +1,72 @@ +import React, { useId, useState } from 'react'; +import { BrowserRouter, Link, Route, Routes } from 'react-router-dom'; + +function Home({ name, age }: { name?: string; age?: number }) { + const [count, setCount] = useState(0); + const fieldId = useId(); + return ( +
+

React Remote Home

+

+ name: {name}, age: {age} +

+ + + +
+ ); +} + +function Detail() { + return ( +
+

React Remote Detail

+

SSR detail page content

+
+ ); +} + +export type ReactRemoteProps = { + name?: string; + age?: number; + basename?: string; +}; + +const ReactRemoteRouteTree = (props: ReactRemoteProps) => { + return ( + <> + + + } /> + } /> + + + ); +}; + +const App = (props: ReactRemoteProps) => ( + + + +); + +export default App; diff --git a/apps/bridge-ssr-demo/remote-react/src/bootstrap.tsx b/apps/bridge-ssr-demo/remote-react/src/bootstrap.tsx new file mode 100644 index 00000000000..032f8ba0220 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/bootstrap.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')!); +root.render( + + + , +); diff --git a/apps/bridge-ssr-demo/remote-react/src/env.d.ts b/apps/bridge-ssr-demo/remote-react/src/env.d.ts new file mode 100644 index 00000000000..b0ac762b091 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/apps/bridge-ssr-demo/remote-react/src/export-app.server.tsx b/apps/bridge-ssr-demo/remote-react/src/export-app.server.tsx new file mode 100644 index 00000000000..c9f10b62515 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/export-app.server.tsx @@ -0,0 +1,26 @@ +import App, { type ReactRemoteProps } from './App'; +import { createBridgeComponent } from '@module-federation/bridge-react/v18'; + +export default createBridgeComponent({ + rootComponent: App, + ssr: { + prepare(context) { + const props = context.props as ReactRemoteProps; + const applicationProps: ReactRemoteProps = { + ...(typeof props.name === 'string' ? { name: props.name } : {}), + ...(typeof props.age === 'number' ? { age: props.age } : {}), + ...(typeof props.basename === 'string' + ? { basename: props.basename } + : {}), + }; + return { + props: applicationProps, + dehydratedState: { + name: props.name ?? null, + age: props.age ?? null, + basename: props.basename ?? null, + }, + }; + }, + }, +}); diff --git a/apps/bridge-ssr-demo/remote-react/src/export-app.tsx b/apps/bridge-ssr-demo/remote-react/src/export-app.tsx new file mode 100644 index 00000000000..13fb3e1d3f2 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/export-app.tsx @@ -0,0 +1,20 @@ +import App, { type ReactRemoteProps } from './App'; +import { createBridgeComponent } from '@module-federation/bridge-react/v18'; + +export default createBridgeComponent({ + rootComponent: App, + ssr: { + hydrate(state) { + if (!state || Array.isArray(state) || typeof state !== 'object') + return {}; + const props = state as Record; + return { + ...(typeof props.name === 'string' ? { name: props.name } : {}), + ...(typeof props.age === 'number' ? { age: props.age } : {}), + ...(typeof props.basename === 'string' + ? { basename: props.basename } + : {}), + } satisfies ReactRemoteProps; + }, + }, +}); diff --git a/apps/bridge-ssr-demo/remote-react/src/index.tsx b/apps/bridge-ssr-demo/remote-react/src/index.tsx new file mode 100644 index 00000000000..b93c7a0268a --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/index.tsx @@ -0,0 +1 @@ +import('./bootstrap'); diff --git a/apps/bridge-ssr-demo/remote-react/src/ssr-env.ts b/apps/bridge-ssr-demo/remote-react/src/ssr-env.ts new file mode 100644 index 00000000000..31b8b869cc5 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/src/ssr-env.ts @@ -0,0 +1,6 @@ +/** + * Node MF environment entry for the React remote. + * Rsbuild builds this to dist/ssr/ for the host to consume via + * bridge_ssr_react@/ssr/mf-manifest.json at request time. + */ +export {}; diff --git a/apps/bridge-ssr-demo/remote-react/tsconfig.json b/apps/bridge-ssr-demo/remote-react/tsconfig.json new file mode 100644 index 00000000000..3519d14e252 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-react/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["DOM", "ES2020"], + "module": "ESNext", + "jsx": "react-jsx", + "strict": true, + "skipLibCheck": true, + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true + }, + "include": ["src"] +} diff --git a/apps/bridge-ssr-demo/remote-vue/package.json b/apps/bridge-ssr-demo/remote-vue/package.json new file mode 100644 index 00000000000..16d0d021a78 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/package.json @@ -0,0 +1,29 @@ +{ + "name": "bridge-ssr-remote-vue", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "rsbuild dev", + "build": "rsbuild build", + "build:vite": "pnpm run build:vite:web && pnpm run build:vite:ssr", + "build:vite:web": "vite build --config vite.config.mts", + "build:vite:ssr": "BRIDGE_VITE_SSR=true vite build --config vite.config.mts && cp dist-vite/ssr/remoteEntry.js dist-vite/ssr/remoteEntry.ssr.js", + "preview": "rsbuild preview" + }, + "dependencies": { + "@module-federation/bridge-vue3": "workspace:*", + "@vue/server-renderer": "^3.5.30", + "vue": "^3.5.30", + "vue-router": "4.4.5" + }, + "devDependencies": { + "@module-federation/rsbuild-plugin": "workspace:*", + "@module-federation/vite": "1.16.16", + "@rsbuild/core": "1.7.3", + "@rsbuild/plugin-vue": "^1.2.6", + "@vitejs/plugin-vue": "^5.0.4", + "typescript": "~5.0.4", + "vite": "^5.4.21" + } +} diff --git a/apps/bridge-ssr-demo/remote-vue/rsbuild.config.ts b/apps/bridge-ssr-demo/remote-vue/rsbuild.config.ts new file mode 100644 index 00000000000..86c3bedfefd --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/rsbuild.config.ts @@ -0,0 +1,93 @@ +import { defineConfig } from '@rsbuild/core'; +import { pluginVue } from '@rsbuild/plugin-vue'; +import { pluginModuleFederation } from '@module-federation/rsbuild-plugin'; +import { pluginServeSsrDist } from '../shared/pluginServeSsrDist'; +import { bridgeSsrHostUrl } from '../shared/devHost'; + +const remoteOrigin = bridgeSsrHostUrl(2302); + +const mfOptions = { + name: 'bridge_ssr_vue', + exposes: { + './export-app': './src/export-app.ts', + }, + shared: { + vue: { singleton: true }, + 'vue-router': { singleton: true }, + }, + dts: false, + getPublicPath: `return '${remoteOrigin}/'`, +}; + +const ssrMfOptions = { + ...mfOptions, + exposes: { + './export-app': './src/export-app.server.ts', + }, + // Keep the Vue app and its renderer request-local to the remote server graph. + shared: {}, + getPublicPath: `return '${remoteOrigin}/ssr/'`, +}; + +export default defineConfig({ + performance: { buildCache: false }, + server: { + port: 2302, + cors: true, + }, + dev: { + assetPrefix: remoteOrigin, + writeToDisk: true, + }, + tools: { + rspack: (config) => { + delete config.optimization?.splitChunks; + }, + }, + environments: { + web: { + source: { + entry: { + index: './src/standalone.ts', + }, + }, + html: { + template: './src/index.html', + }, + output: { + distPath: { + root: 'dist', + }, + }, + }, + ssr: { + source: { + entry: { + index: './src/ssr-env.ts', + }, + }, + output: { + target: 'node', + distPath: { + root: 'dist/ssr', + }, + emitAssets: true, + }, + tools: { + rspack: (config) => { + config.output ??= {}; + config.output.publicPath = `${remoteOrigin}/ssr/`; + }, + }, + }, + }, + plugins: [ + pluginVue(), + pluginServeSsrDist(__dirname), + pluginModuleFederation(mfOptions, { environment: 'web' }), + pluginModuleFederation(ssrMfOptions, { + target: 'node', + environment: 'ssr', + }), + ], +}); diff --git a/apps/bridge-ssr-demo/remote-vue/src/RemoteVueApplication.vue b/apps/bridge-ssr-demo/remote-vue/src/RemoteVueApplication.vue new file mode 100644 index 00000000000..e653b29596f --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/RemoteVueApplication.vue @@ -0,0 +1,20 @@ + + + diff --git a/apps/bridge-ssr-demo/remote-vue/src/export-app.server.ts b/apps/bridge-ssr-demo/remote-vue/src/export-app.server.ts new file mode 100644 index 00000000000..c90e02a653d --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/export-app.server.ts @@ -0,0 +1,32 @@ +import App from './RemoteVueApplication.vue'; +import { createBridgeComponent } from '@module-federation/bridge-vue3'; +import { createMemoryHistory, createRouter } from 'vue-router'; +import Home from './pages/Home.vue'; +import Detail from './pages/Detail.vue'; + +export default createBridgeComponent({ + rootComponent: App, + appOptions: () => ({ + router: createRouter({ + history: createMemoryHistory(), + routes: [ + { path: '/', component: Home }, + { path: '/detail', component: Detail }, + ], + }), + }), + ssr: { + prepare(context) { + const props = context.props as { test?: string; basename?: string }; + return { + props: { + ...(typeof props.test === 'string' ? { test: props.test } : {}), + ...(typeof props.basename === 'string' + ? { basename: props.basename } + : {}), + }, + dehydratedState: { test: props.test ?? null }, + }; + }, + }, +}); diff --git a/apps/bridge-ssr-demo/remote-vue/src/export-app.ts b/apps/bridge-ssr-demo/remote-vue/src/export-app.ts new file mode 100644 index 00000000000..fcb14c40b0c --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/export-app.ts @@ -0,0 +1,26 @@ +import App from './RemoteVueApplication.vue'; +import { createBridgeComponent } from '@module-federation/bridge-vue3'; +import { createRouter, createWebHistory } from 'vue-router'; +import Home from './pages/Home.vue'; +import Detail from './pages/Detail.vue'; + +export default createBridgeComponent({ + rootComponent: App, + appOptions: () => ({ + router: createRouter({ + history: createWebHistory(), + routes: [ + { path: '/', component: Home }, + { path: '/detail', component: Detail }, + ], + }), + }), + ssr: { + hydrate(state) { + if (!state || Array.isArray(state) || typeof state !== 'object') + return {}; + const test = (state as Record).test; + return typeof test === 'string' ? { test } : {}; + }, + }, +}); diff --git a/apps/bridge-ssr-demo/remote-vue/src/index.html b/apps/bridge-ssr-demo/remote-vue/src/index.html new file mode 100644 index 00000000000..c7fe0adc4c3 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/index.html @@ -0,0 +1,11 @@ + + + + + + Bridge SSR Vue Remote + + +
+ + diff --git a/apps/bridge-ssr-demo/remote-vue/src/pages/Detail.vue b/apps/bridge-ssr-demo/remote-vue/src/pages/Detail.vue new file mode 100644 index 00000000000..2e05e520e52 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/pages/Detail.vue @@ -0,0 +1,6 @@ + diff --git a/apps/bridge-ssr-demo/remote-vue/src/pages/Home.vue b/apps/bridge-ssr-demo/remote-vue/src/pages/Home.vue new file mode 100644 index 00000000000..8373d64d00d --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/pages/Home.vue @@ -0,0 +1,16 @@ + + + diff --git a/apps/bridge-ssr-demo/remote-vue/src/ssr-env.ts b/apps/bridge-ssr-demo/remote-vue/src/ssr-env.ts new file mode 100644 index 00000000000..ffee3d7483a --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/ssr-env.ts @@ -0,0 +1,6 @@ +/** + * Node MF environment entry for the Vue remote. + * Rsbuild builds this to dist/ssr/ for the host to consume via + * bridge_ssr_vue@/ssr/mf-manifest.json at request time. + */ +export {}; diff --git a/apps/bridge-ssr-demo/remote-vue/src/standalone.ts b/apps/bridge-ssr-demo/remote-vue/src/standalone.ts new file mode 100644 index 00000000000..4f6adaaeb2d --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/src/standalone.ts @@ -0,0 +1,15 @@ +import { createApp } from 'vue'; +import App from './RemoteVueApplication.vue'; +import { createRouter, createWebHistory } from 'vue-router'; +import Home from './pages/Home.vue'; +import Detail from './pages/Detail.vue'; + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { path: '/', component: Home }, + { path: '/detail', component: Detail }, + ], +}); + +createApp(App).use(router).mount('#root'); diff --git a/apps/bridge-ssr-demo/remote-vue/tsconfig.json b/apps/bridge-ssr-demo/remote-vue/tsconfig.json new file mode 100644 index 00000000000..ac97d6272cc --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "jsx": "preserve", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src", "rsbuild.config.ts"] +} diff --git a/apps/bridge-ssr-demo/remote-vue/vite.config.mts b/apps/bridge-ssr-demo/remote-vue/vite.config.mts new file mode 100644 index 00000000000..3e7ba50bbd4 --- /dev/null +++ b/apps/bridge-ssr-demo/remote-vue/vite.config.mts @@ -0,0 +1,51 @@ +import { federation } from '@module-federation/vite'; +import vue from '@vitejs/plugin-vue'; +import { defineConfig } from 'vite'; +import path from 'node:path'; +import { bridgeSsrHostUrl } from '../shared/devHost'; + +const isSSR = process.env.BRIDGE_VITE_SSR === 'true'; +const remoteOrigin = bridgeSsrHostUrl(2402); + +export default defineConfig({ + plugins: [ + vue(), + federation({ + name: 'bridge_ssr_vue', + filename: 'remoteEntry.js', + exposes: { + './export-app': isSSR + ? './src/export-app.server.ts' + : './src/export-app.ts', + }, + shared: isSSR + ? {} + : { + vue: { singleton: true }, + 'vue-router': { singleton: true }, + }, + manifest: true, + dts: false, + target: isSSR ? 'node' : 'web', + getPublicPath: `return '${remoteOrigin}${isSSR ? '/ssr' : ''}/'`, + }), + ], + server: { + origin: remoteOrigin, + port: 2402, + }, + build: { + outDir: isSSR ? 'dist-vite/ssr' : 'dist-vite', + emptyOutDir: !isSSR, + target: isSSR ? 'node20' : 'es2020', + ssr: isSSR ? './src/ssr-env.ts' : undefined, + rollupOptions: isSSR + ? undefined + : { + input: path.resolve(__dirname, 'src/standalone.ts'), + }, + }, + ssr: { + noExternal: true, + }, +}); diff --git a/apps/bridge-ssr-demo/shared/createHostServer.mjs b/apps/bridge-ssr-demo/shared/createHostServer.mjs new file mode 100644 index 00000000000..57aec8ba0b5 --- /dev/null +++ b/apps/bridge-ssr-demo/shared/createHostServer.mjs @@ -0,0 +1,106 @@ +import express from 'express'; +import { createRsbuild, loadConfig } from '@rsbuild/core'; +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { serializeBridgeJSON } from '@module-federation/bridge-shared/dist/index.es.js'; + +const shouldRender = (url) => { + if (url.startsWith('/@') || url.startsWith('/__rsbuild')) return false; + const pathname = url.split('?')[0]; + return !pathname.includes('.') || pathname.endsWith('.html'); +}; + +function assembleDocument(template, html, ssrContext) { + const marker = ''; + if (!template.includes(marker)) { + throw new Error(`Bridge SSR host template is missing ${marker}`); + } + const payload = ``; + return template.replace(marker, html).replace('', `${payload}`); +} + +function registerSSRRoute(app, getBundle, getTemplate, label) { + app.get('*', async (req, res, next) => { + if (!shouldRender(req.originalUrl)) return next(); + const controller = new AbortController(); + const disconnect = () => controller.abort(new Error('Client disconnected')); + req.once('aborted', disconnect); + try { + const [bundle, template] = await Promise.all([ + getBundle(), + getTemplate(), + ]); + const rendered = await bundle.render(req.originalUrl, { + signal: controller.signal, + }); + if (controller.signal.aborted) return; + res + .status(200) + .type('html') + .set('Cache-Control', 'no-store') + .send(assembleDocument(template, rendered.html, rendered.ssrContext)); + } catch (error) { + if (!controller.signal.aborted) { + console.error(`[${label}] SSR request failed`, error, error?.cause); + next(error); + } + } finally { + req.off('aborted', disconnect); + } + }); +} + +export async function startBridgeHost({ rootDir, port, label }) { + const host = + process.env.HOST ?? process.env.BRIDGE_SSR_DEV_HOST ?? 'localhost'; + const app = express(); + if (process.env.BRIDGE_SSR_MODE === 'production') { + const dist = path.join(rootDir, 'dist'); + const template = await readFile(path.join(dist, 'index.html'), 'utf8'); + const imported = await import( + `${pathToFileURL(path.join(dist, 'ssr', 'index.js')).href}?${Date.now()}` + ); + registerSSRRoute( + app, + async () => imported.default ?? imported, + async () => template, + label, + ); + app.use(express.static(dist)); + } else { + const { content } = await loadConfig({ cwd: rootDir }); + const rsbuild = await createRsbuild({ + cwd: rootDir, + rsbuildConfig: content, + }); + const server = await rsbuild.createDevServer(); + let bundlePromise; + const getBundle = () => { + bundlePromise ??= server.environments.ssr + .loadBundle('index') + .catch((error) => { + bundlePromise = undefined; + throw error; + }); + return bundlePromise; + }; + registerSSRRoute( + app, + getBundle, + () => server.environments.client.getTransformedHtml('index'), + label, + ); + app.use(server.middlewares); + const httpServer = app.listen(port, host, async () => { + await server.afterListen(); + console.log(`[${label}] ready at http://${host}:${port}`); + }); + server.connectWebSocket({ server: httpServer }); + return; + } + + app.listen(port, host, () => { + console.log(`[${label}] production ready at http://${host}:${port}`); + }); +} diff --git a/apps/bridge-ssr-demo/shared/devHost.ts b/apps/bridge-ssr-demo/shared/devHost.ts new file mode 100644 index 00000000000..b5aefe9ca6f --- /dev/null +++ b/apps/bridge-ssr-demo/shared/devHost.ts @@ -0,0 +1,17 @@ +export const BRIDGE_SSR_DEV_HOST = + process.env.BRIDGE_SSR_DEV_HOST ?? 'localhost'; + +export const BRIDGE_SSR_REMOTE_BUNDLER = + process.env.BRIDGE_SSR_REMOTE_BUNDLER === 'vite' ? 'vite' : 'rsbuild'; + +export const bridgeSsrRemotePort = (framework: 'react' | 'vue') => { + if (BRIDGE_SSR_REMOTE_BUNDLER === 'vite') { + return framework === 'react' ? 2401 : 2402; + } + return framework === 'react' ? 2301 : 2302; +}; + +export const bridgeSsrServerManifestPath = 'ssr/mf-manifest.json'; + +export const bridgeSsrHostUrl = (port: number) => + `http://${BRIDGE_SSR_DEV_HOST}:${port}`; diff --git a/apps/bridge-ssr-demo/shared/package.json b/apps/bridge-ssr-demo/shared/package.json new file mode 100644 index 00000000000..99cc4bbc4db --- /dev/null +++ b/apps/bridge-ssr-demo/shared/package.json @@ -0,0 +1,11 @@ +{ + "name": "bridge-ssr-demo-shared", + "private": true, + "version": "0.0.1", + "type": "module", + "dependencies": { + "@module-federation/bridge-shared": "workspace:*", + "@rsbuild/core": "1.7.3", + "express": "^4.21.2" + } +} diff --git a/apps/bridge-ssr-demo/shared/pluginServeSsrDist.ts b/apps/bridge-ssr-demo/shared/pluginServeSsrDist.ts new file mode 100644 index 00000000000..fa6c1f40146 --- /dev/null +++ b/apps/bridge-ssr-demo/shared/pluginServeSsrDist.ts @@ -0,0 +1,63 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import type { RsbuildPlugin } from '@rsbuild/core'; + +function getContentType(filePath: string) { + if (filePath.endsWith('.json')) { + return 'application/json'; + } + if (filePath.endsWith('.js')) { + return 'application/javascript'; + } + if (filePath.endsWith('.map')) { + return 'application/json'; + } + return 'application/octet-stream'; +} + +export function pluginServeSsrDist(rootDir = process.cwd()): RsbuildPlugin { + const ssrDir = path.join(rootDir, 'dist', 'ssr'); + + return { + name: 'plugin-serve-ssr-dist', + setup(api) { + api.modifyRsbuildConfig((config) => { + config.dev ??= {}; + const previous = config.dev.setupMiddlewares; + + config.dev.setupMiddlewares = (middlewares, server) => { + if (typeof previous === 'function') { + previous(middlewares, server); + } else if (Array.isArray(previous)) { + previous.forEach((setup) => setup(middlewares, server)); + } + + middlewares.unshift((req, res, next) => { + const url = req.url?.split('?')[0] ?? ''; + if (!url.startsWith('/ssr/')) { + next(); + return; + } + + const relativePath = decodeURIComponent(url.slice('/ssr/'.length)); + const filePath = path.join(ssrDir, relativePath); + + if ( + !filePath.startsWith(ssrDir) || + !fs.existsSync(filePath) || + fs.statSync(filePath).isDirectory() + ) { + next(); + return; + } + + res.statusCode = 200; + res.setHeader('Content-Type', getContentType(filePath)); + res.setHeader('Access-Control-Allow-Origin', '*'); + fs.createReadStream(filePath).pipe(res); + }); + }; + }); + }, + }; +} diff --git a/apps/bridge-ssr-demo/shared/routerAlias.ts b/apps/bridge-ssr-demo/shared/routerAlias.ts new file mode 100644 index 00000000000..6ce885d8c98 --- /dev/null +++ b/apps/bridge-ssr-demo/shared/routerAlias.ts @@ -0,0 +1,14 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const directory = path.dirname(fileURLToPath(import.meta.url)); + +export function createBridgeRouterAlias(reactRouterDomPath: string) { + return { + 'react-router-dom$': path.resolve( + directory, + '../../../packages/bridge/bridge-react/dist/router-v6.es.js', + ), + 'react-router-dom/dist/index.js': reactRouterDomPath, + }; +} diff --git a/apps/bridge-ssr-demo/shared/serveDist.mjs b/apps/bridge-ssr-demo/shared/serveDist.mjs new file mode 100644 index 00000000000..292ec4f14fa --- /dev/null +++ b/apps/bridge-ssr-demo/shared/serveDist.mjs @@ -0,0 +1,19 @@ +import express from 'express'; +import path from 'node:path'; + +const [distDir, portValue] = process.argv.slice(2); +const port = Number(portValue); + +if (!distDir || !Number.isInteger(port)) { + throw new Error('Usage: serveDist.mjs '); +} + +const app = express(); +app.use((_req, res, next) => { + res.setHeader('Access-Control-Allow-Origin', '*'); + next(); +}); +app.use(express.static(path.resolve(distDir))); +app.listen(port, process.env.HOST ?? 'localhost', () => { + console.log(`[bridge-ssr-static] serving ${distDir} on port ${port}`); +}); diff --git a/apps/website-new/docs/en/guide/bridge/_meta.json b/apps/website-new/docs/en/guide/bridge/_meta.json index b7f300763b2..9703deaca9e 100644 --- a/apps/website-new/docs/en/guide/bridge/_meta.json +++ b/apps/website-new/docs/en/guide/bridge/_meta.json @@ -10,5 +10,10 @@ "label": "React", "collapsible": true, "collapsed": true + }, + { + "type": "file", + "name": "ssr", + "label": "Server rendering" } ] diff --git a/apps/website-new/docs/en/guide/bridge/ssr.mdx b/apps/website-new/docs/en/guide/bridge/ssr.mdx new file mode 100644 index 00000000000..bc78c0d62c0 --- /dev/null +++ b/apps/website-new/docs/en/guide/bridge/ssr.mdx @@ -0,0 +1,55 @@ +# Server rendering Bridge applications + +Bridge SSR V1 lets a federated application provider return a buffered HTML island on the server and hydrate that same island through the existing client lifecycle. + +## Supported scope + +- React 18 with declarative React Router v6 +- Vue 3 with Vue Router 4 +- Full host-passed `{ html, dehydratedState, moduleName, instanceId, protocolVersion }` payloads +- Multiple instances of the same remote through document-unique instance IDs + +React data routers and other React or Router versions keep their existing client-rendering support but are not supported for SSR in V1. + +## Remote provider + +Set `ssr: true` when no request preparation is needed. If preparation is required, map the same federated export key to separate browser and Node source files. The browser file supplies `hydrate`; the Node file supplies `prepare`. This keeps server renderers and request-only code out of browser chunks. + +```ts +// export-app.server.ts +export default createBridgeComponent({ + rootComponent: App, + ssr: { + prepare({ props }) { + return { + props, + dehydratedState: { initialValue: props.initialValue }, + }; + }, + }, +}); +``` + +The React Node entry owns `react-dom/server`; the Vue Node entry owns `@vue/server-renderer`. Framework elements, routers, application instances, and renderers never cross `@module-federation/bridge-shared`. + +## Host rendering + +Use `renderRemoteBridge` with an intentional, sanitized standard `Request`, stable module name, document-unique instance ID, and explicit props: + +```ts +const result = await renderRemoteBridge({ + loader: () => federationInstance.loadRemote('catalog/export-app'), + moduleName: 'catalog', + instanceId: 'catalog-sidebar', + request, + props: { basename: '/catalog' }, +}); +``` + +Carry the complete result in the host application's normal SSR payload and pass it to `createRemoteAppComponent` as `ssr`. Serialize payloads with `serializeBridgeJSON`, which validates JSON-only data and escapes executable HTML sequences. The adapters hydrate only when the payload identity matches the instance-scoped SSR mount marker; otherwise they use the unchanged CSR path. V1 does not scan the document or use a hydration registry. + +`renderRemoteBridge` rejects provider-load, unsupported-contract, identity, and rendering failures with contextual errors. Response policy remains host-owned. + +## Not included in V1 + +Assets/CSP/head management, status and header conflict policy, timeouts and fallbacks, DOM-reference payload recovery, React data routers, additional React/Router versions, Nuxt or Modern.js adapters, portals/Teleports, streaming, backpressure, and benchmarks are follow-up work. diff --git a/package.json b/package.json index 55523b699b2..cb0ce05748a 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,9 @@ "e2e:treeshake:frontend": "pnpm exec turbo run e2e --filter=@module-federation/treeshake-frontend", "e2e:modern:ssr": "node tools/scripts/run-modern-e2e.mjs --mode=manifest", "e2e:router": "node tools/scripts/run-router-e2e.mjs --mode=dev", + "e2e:bridge:ssr": "node tools/scripts/run-bridge-ssr-e2e.mjs", + "e2e:bridge:ssr:production": "BRIDGE_SSR_MODE=production node tools/scripts/run-bridge-ssr-e2e.mjs", + "e2e:bridge:ssr:vite-smoke": "BRIDGE_SSR_REMOTE_BUNDLER=vite node tools/scripts/run-bridge-ssr-e2e.mjs", "e2e:shared-tree-shaking:runtime-infer": "npx kill-port --port 3001,3002 && pnpm exec turbo run test:e2e --filter=shared-tree-shaking-no-server-host && lsof -ti tcp:3001,3002 | xargs kill", "e2e:shared-tree-shaking:server-calc": "npx kill-port --port 3001,3002,3003 && pnpm exec turbo run test:e2e --filter=shared-tree-shaking-with-server-host && lsof -ti tcp:3001,3002,3003 | xargs kill", "e2e:devtools:dev": "npx kill-port 3009 3010 3011 3012 3013 4001 && pnpm run app:manifest:dev & echo \"done\" && npx wait-on tcp:3009 tcp:3010 tcp:3011 tcp:3012 tcp:3013 && sleep 10 && pnpm exec turbo run test:e2e --filter=@module-federation/devtools", diff --git a/packages/bridge/bridge-react/package.json b/packages/bridge/bridge-react/package.json index 72f234abd30..934c4c83fc8 100644 --- a/packages/bridge/bridge-react/package.json +++ b/packages/bridge/bridge-react/package.json @@ -32,6 +32,14 @@ }, "./v18": { "types": "./dist/v18.d.ts", + "browser": { + "import": "./dist/v18.es.js", + "require": "./dist/v18.cjs.js" + }, + "node": { + "import": "./dist/v18.server.es.js", + "require": "./dist/v18.server.cjs.js" + }, "import": "./dist/v18.es.js", "require": "./dist/v18.cjs.js" }, @@ -189,6 +197,7 @@ "vite": "^5.4.21", "@module-federation/runtime": "workspace:*", "@module-federation/runtime-core": "workspace:*", - "hono": "4.12.26" + "hono": "4.12.26", + "jsdom": "20.0.3" } } diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-base.spec.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-base.spec.tsx new file mode 100644 index 00000000000..4bb011e6b19 --- /dev/null +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-base.spec.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { describe, expect, it, rs } from '@rstest/core'; +import { getBridgeSSRContainerAttrs } from '@module-federation/bridge-shared'; +import { createBaseBridgeComponent } from './bridge-base'; + +const Root = () =>
remote
; + +describe('React Bridge hydration selection', () => { + it('hydrates only a matching host-passed SSR mount', async () => { + const hydrateRoot = rs.fn(() => ({ render: rs.fn(), unmount: rs.fn() })); + const createRoot = rs.fn(() => ({ render: rs.fn(), unmount: rs.fn() })); + const dom = document.createElement('div'); + for (const [name, value] of Object.entries( + getBridgeSSRContainerAttrs({ moduleName: 'remote', instanceId: 'one' }), + )) + dom.setAttribute(name, value); + dom.innerHTML = '
remote
'; + const provider = createBaseBridgeComponent({ + rootComponent: Root, + createRoot, + hydrateRoot, + ssr: true, + })(); + await provider.render({ dom, moduleName: 'remote', instanceId: 'one' }); + expect(hydrateRoot).toHaveBeenCalledOnce(); + expect(createRoot).not.toHaveBeenCalled(); + }); + + it('keeps the existing CSR path without a payload marker', async () => { + const root = { render: rs.fn(), unmount: rs.fn() }; + const createRoot = rs.fn(() => root); + const hydrate = rs.fn(() => ({ restored: true })); + const provider = createBaseBridgeComponent({ + rootComponent: Root, + createRoot, + hydrateRoot: rs.fn(), + ssr: { hydrate }, + })(); + await provider.render({ + dom: document.createElement('div'), + moduleName: 'remote', + }); + expect(createRoot).toHaveBeenCalledOnce(); + expect(root.render).toHaveBeenCalledOnce(); + expect(hydrate).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx index 174dbf0f3f8..8af2c4491ea 100644 --- a/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-base.tsx @@ -2,23 +2,24 @@ * Base bridge component implementation * This file contains bridge component logic shared across all React versions */ -import * as React from 'react'; import type { - ProviderParams, ProviderFnParams, RootType, DestroyParams, RenderParams, CreateRootOptions, - ErrorFallbackProps, } from '../../types'; -import { ErrorBoundary } from '../../error-boundary'; -import { RouterContext } from '../context'; import { LoggerInstance } from '../../utils'; import { federationRuntime } from '../plugin'; +import { + hasBridgeSSRMarkup, + type BridgeJSONValue, +} from '@module-federation/bridge-shared'; +import { createBridgeReactElement, omitHostFallback } from './bridge-render'; export function createBaseBridgeComponent({ createRoot, + hydrateRoot, defaultRootOptions, ...bridgeInfo }: ProviderFnParams) { @@ -30,60 +31,14 @@ export function createBaseBridgeComponent({ instance, ); - const RawComponent = (info: { propsInfo: T; appInfo: ProviderParams }) => { - const { appInfo, propsInfo, ...restProps } = info; - const { moduleName, memoryRoute, basename = '/' } = appInfo; - return ( - - - - ); - }; - - const DefaultFallback = ({ error }: ErrorFallbackProps) => ( -
-

Something went wrong:

-
-          {error instanceof Error ? error.message : String(error)}
-        
-
- ); - - const omitHostFallback =

>(props: P) => { - const nextProps = { ...props }; - delete nextProps.fallback; - return nextProps; - }; - - const BridgeWrapper = ({ - basename, - moduleName, - memoryRoute, - propsInfo, - }: { - basename?: string; - moduleName?: string; - memoryRoute?: any; - propsInfo: T; - }) => ( - - - - ); + const hydrateState = + bridgeInfo.ssr && typeof bridgeInfo.ssr === 'object' + ? bridgeInfo.ssr.hydrate + : undefined; return { async render(info: RenderParams) { + if (info.signal?.aborted) return; LoggerInstance.debug(`createBridgeComponent render Info`, info); const { moduleName, @@ -91,38 +46,71 @@ export function createBaseBridgeComponent({ basename, memoryRoute, rootOptions, + instanceId, + ssrState, ...propsInfo } = info; const mergedRootOptions: CreateRootOptions | undefined = { ...defaultRootOptions, ...(rootOptions as CreateRootOptions), + ...(instanceId + ? { identifierPrefix: `mf-${encodeURIComponent(instanceId)}-` } + : {}), }; + const isFirstRender = !rootMap.has(dom); + const shouldHydrate = + isFirstRender && + hasBridgeSSRMarkup(dom, { + moduleName, + instanceId, + }); + const hydratedProps = + shouldHydrate && hydrateState + ? hydrateState(ssrState as BridgeJSONValue | undefined) + : {}; + const beforeBridgeRenderRes = instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info) || {}; - const rootComponentWithErrorBoundary = ( - ), - basename, - ...(beforeBridgeRenderRes as any)?.extraProps, - } as T - } - /> - ); + const rootComponentWithErrorBoundary = createBridgeReactElement({ + rootComponent: bridgeInfo.rootComponent, + basename, + moduleName, + memoryRoute, + propsInfo: { + ...hydratedProps, + ...omitHostFallback(propsInfo as Record), + basename, + ...(beforeBridgeRenderRes as any)?.extraProps, + } as T, + }); if (bridgeInfo.render) { + const renderer = shouldHydrate + ? bridgeInfo.hydrate + : bridgeInfo.render; + if (!renderer) { + throw new Error( + 'A custom Bridge renderer must provide hydrate when SSR is enabled', + ); + } await Promise.resolve( - bridgeInfo.render(rootComponentWithErrorBoundary, dom), + renderer(rootComponentWithErrorBoundary, dom), ).then((root: RootType) => rootMap.set(dom, root)); } else { let root = rootMap.get(dom); + let didHydrate = false; + if (shouldHydrate && hydrateRoot) { + root = hydrateRoot!( + dom, + rootComponentWithErrorBoundary, + mergedRootOptions, + ); + rootMap.set(dom, root as RootType); + didHydrate = true; + } // Do not call createRoot multiple times if (!root && createRoot) { root = createRoot(dom, mergedRootOptions); @@ -130,7 +118,7 @@ export function createBaseBridgeComponent({ } if (root && 'render' in root) { - root.render(rootComponentWithErrorBoundary); + if (!didHydrate) root.render(rootComponentWithErrorBoundary); } } instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info) || {}; diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-render.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-render.tsx new file mode 100644 index 00000000000..1747425d787 --- /dev/null +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-render.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import { ErrorBoundary } from '../../error-boundary'; +import type { + ErrorFallbackProps, + ProviderFnParams, + ProviderParams, +} from '../../types'; +import { RouterContext } from '../context'; + +export function omitHostFallback

>(props: P) { + const next = { ...props }; + delete next.fallback; + return next; +} + +export function createBridgeReactElement({ + rootComponent: RootComponent, + basename, + moduleName, + memoryRoute, + ssrLocation, + propsInfo, +}: { + rootComponent: ProviderFnParams['rootComponent']; + basename?: string; + moduleName?: string; + memoryRoute?: ProviderParams['memoryRoute']; + ssrLocation?: string; + propsInfo: T; +}) { + const DefaultFallback = ({ error }: ErrorFallbackProps) => ( +

+

Something went wrong:

+
+        {error instanceof Error ? error.message : String(error)}
+      
+
+ ); + + return ( + + + + + + ); +} diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx new file mode 100644 index 00000000000..ab3839cdcbb --- /dev/null +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx @@ -0,0 +1,68 @@ +import { + BRIDGE_SSR_PROTOCOL_VERSION, + type BridgeSSRPrepareResult, + type BridgeSSRResult, + type BridgeServerRenderContext, +} from '@module-federation/bridge-shared'; +import type { ProviderFnParams, ProviderParams } from '../../types'; +import { createBaseBridgeComponent } from './bridge-base'; +import { createBridgeReactElement, omitHostFallback } from './bridge-render'; + +export function createServerBridgeComponent( + bridgeInfo: ProviderFnParams & { + serverRenderer: ( + element: React.ReactElement, + options: { identifierPrefix: string }, + ) => string | Promise; + }, +) { + const { serverRenderer, ...clientInfo } = bridgeInfo; + const createClientProvider = createBaseBridgeComponent(clientInfo); + + return () => { + const provider = createClientProvider() as ReturnType< + typeof createClientProvider + > & { + renderServer?: ( + context: BridgeServerRenderContext, + ) => Promise; + }; + if (!bridgeInfo.ssr) return provider; + + provider.renderServer = async (context) => { + if (context.signal.aborted) throw context.signal.reason; + const config = + typeof bridgeInfo.ssr === 'object' ? bridgeInfo.ssr : undefined; + const preparedValue = await config?.prepare?.(context); + const prepared = (preparedValue || {}) as BridgeSSRPrepareResult; + const renderInfo = (prepared.props ?? context.props) as T & + ProviderParams; + const { basename, memoryRoute, ...applicationProps } = renderInfo; + delete (applicationProps as Record).moduleName; + const url = new URL(context.request.url); + const element = createBridgeReactElement({ + rootComponent: bridgeInfo.rootComponent, + basename, + moduleName: context.moduleName, + memoryRoute, + ssrLocation: `${url.pathname}${url.search}`, + propsInfo: { + ...omitHostFallback(applicationProps as Record), + basename, + } as T, + }); + const html = await serverRenderer(element, { + identifierPrefix: `mf-${encodeURIComponent(context.instanceId)}-`, + }); + if (context.signal.aborted) throw context.signal.reason; + return { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: context.moduleName, + instanceId: context.instanceId, + html, + dehydratedState: prepared.dehydratedState, + }; + }; + return provider; + }; +} diff --git a/packages/bridge/bridge-react/src/provider/versions/server-renderer.ts b/packages/bridge/bridge-react/src/provider/versions/server-renderer.ts new file mode 100644 index 00000000000..de5bd538e08 --- /dev/null +++ b/packages/bridge/bridge-react/src/provider/versions/server-renderer.ts @@ -0,0 +1,8 @@ +import { renderToString } from 'react-dom/server'; + +export function renderBridgeReactToString( + element: React.ReactElement, + options: { identifierPrefix: string }, +) { + return renderToString(element, options); +} diff --git a/packages/bridge/bridge-react/src/provider/versions/v18.server.ts b/packages/bridge/bridge-react/src/provider/versions/v18.server.ts new file mode 100644 index 00000000000..56fdf46abea --- /dev/null +++ b/packages/bridge/bridge-react/src/provider/versions/v18.server.ts @@ -0,0 +1,17 @@ +import type { ProviderFnParams } from '../../types'; +import { createReact18Root, hydrateReact18Root } from './v18'; +import { createServerBridgeComponent } from './bridge-server'; +import { renderBridgeReactToString } from './server-renderer'; + +export function createBridgeComponent( + bridgeInfo: Omit, 'createRoot' | 'hydrateRoot'>, +) { + return createServerBridgeComponent({ + ...bridgeInfo, + createRoot: createReact18Root, + hydrateRoot: hydrateReact18Root, + serverRenderer: renderBridgeReactToString, + }); +} + +export type { CreateRootOptions, Root } from './v18'; diff --git a/packages/bridge/bridge-react/src/provider/versions/v18.ts b/packages/bridge/bridge-react/src/provider/versions/v18.ts index 31436fde6cd..937a50fdb51 100644 --- a/packages/bridge/bridge-react/src/provider/versions/v18.ts +++ b/packages/bridge/bridge-react/src/provider/versions/v18.ts @@ -36,10 +36,11 @@ export function hydrateReact18Root( } export function createBridgeComponent( - bridgeInfo: Omit, 'createRoot'>, + bridgeInfo: Omit, 'createRoot' | 'hydrateRoot'>, ) { const fullBridgeInfo = { createRoot: createReact18Root, + hydrateRoot: hydrateReact18Root, ...bridgeInfo, } as unknown as ProviderFnParams; diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx index 44b6887f43c..ed6f85bd968 100644 --- a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx @@ -6,9 +6,11 @@ import React, { useEffect, useRef, useState, forwardRef } from 'react'; import { LoggerInstance, getRootDomDefaultClassName } from '../utils'; import { federationRuntime } from '../provider/plugin'; import { RemoteComponentProps, RemoteAppParams } from '../types'; +import type { RemoteAppSSRProps } from '../types'; +import { getBridgeSSRContainerAttrs } from '@module-federation/bridge-shared'; export const RemoteAppWrapper = forwardRef(function ( - props: RemoteAppParams & RemoteComponentProps, + props: RemoteAppParams & RemoteComponentProps & RemoteAppSSRProps, ref, ) { const { @@ -20,8 +22,12 @@ export const RemoteAppWrapper = forwardRef(function ( style, fallback, loading, + ssr, + instanceId: suppliedInstanceId, ...resProps } = props; + const instanceId = suppliedInstanceId || ssr?.instanceId; + const hasSSRPayload = Boolean(ssr && instanceId); const instance = federationRuntime.instance; const rootRef: React.MutableRefObject = @@ -85,6 +91,8 @@ export const RemoteAppWrapper = forwardRef(function ( basename, memoryRoute, fallback, + instanceId, + ssrState: ssr?.dehydratedState, ...resProps, }; renderDom.current = rootRef.current; @@ -101,8 +109,21 @@ export const RemoteAppWrapper = forwardRef(function ( // bridge-remote-root const rootComponentClassName = `${getRootDomDefaultClassName(moduleName)} ${className || ''}`; return ( -
- {loading} +
+ {hasSSRPayload ? null : loading}
); }); diff --git a/packages/bridge/bridge-react/src/remote/createHelpers.tsx b/packages/bridge/bridge-react/src/remote/createHelpers.tsx index b0580acacde..65e4eacb2fc 100644 --- a/packages/bridge/bridge-react/src/remote/createHelpers.tsx +++ b/packages/bridge/bridge-react/src/remote/createHelpers.tsx @@ -100,15 +100,28 @@ export function createRemoteAppComponentFactory( >(info: LazyRemoteComponentInfo) { const LazyComponent = createLazyRemoteComponent(info); return forwardRef((props, ref) => { + const ssrResult = (props as any).ssr; + const content = + typeof window === 'undefined' && ssrResult ? ( + ({ render() {}, destroy() {} })} + exportName={info.export || 'default'} + fallback={info.fallback} + loading={info.loading} + ref={ref} + /> + ) : ( + + ); return ( } > - - - + {content} ); }); diff --git a/packages/bridge/bridge-react/src/router/static.tsx b/packages/bridge/bridge-react/src/router/static.tsx new file mode 100644 index 00000000000..10bb00308fb --- /dev/null +++ b/packages/bridge/bridge-react/src/router/static.tsx @@ -0,0 +1,52 @@ +import React from 'react'; + +function parsePath(value: string) { + const url = new URL(value, 'http://bridge.invalid'); + return { + pathname: url.pathname, + search: url.search, + hash: url.hash, + state: null, + key: 'default', + }; +} + +const navigator = { + createHref: (value: any) => + typeof value === 'string' + ? value + : `${value.pathname || '/'}${value.search || ''}${value.hash || ''}`, + encodeLocation: (value: any) => + typeof value === 'string' ? parsePath(value) : value, + push: () => { + throw new Error('Cannot navigate while server rendering a Bridge remote'); + }, + replace: () => { + throw new Error('Cannot navigate while server rendering a Bridge remote'); + }, + go: () => undefined, +}; + +export function BridgeStaticRouter({ + Router, + basename, + location, + children, +}: { + Router: React.ComponentType; + basename?: string; + location: string; + children?: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/packages/bridge/bridge-react/src/router/v6.tsx b/packages/bridge/bridge-react/src/router/v6.tsx index c0b2025a5a3..52897ecdc6e 100644 --- a/packages/bridge/bridge-react/src/router/v6.tsx +++ b/packages/bridge/bridge-react/src/router/v6.tsx @@ -3,6 +3,7 @@ import React, { useContext } from 'react'; import * as ReactRouterDom from 'react-router-dom/dist/index.js'; import { RouterContext } from '../provider/context'; import { LoggerInstance } from '../utils'; +import { BridgeStaticRouter } from './static'; function WraperRouter( props: @@ -18,6 +19,17 @@ function WraperRouter( WraperRouterProps: props, }); + if (routerContextProps?.ssrLocation) { + return ( + + {props.children} + + ); + } if (routerContextProps?.memoryRoute) { return ( ; + instanceId?: string; + ssrState?: BridgeJSONValue; + signal?: AbortSignal; [key: string]: unknown; } @@ -90,10 +103,19 @@ export interface ProviderFnParams { App: React.ReactElement, id?: HTMLElement | string, ) => RootType | Promise; + hydrate?: ( + App: React.ReactElement, + id?: HTMLElement | string, + ) => RootType | Promise; createRoot?: ( container: Element | DocumentFragment, options?: CreateRootOptions, ) => Root; + hydrateRoot?: ( + container: Element | DocumentFragment, + initialChildren: React.ReactNode, + options?: CreateRootOptions, + ) => Root; /** * Default options to pass to createRoot for React 18 and 19 * These options will be used when creating a root unless overridden by rootOptions in render params @@ -104,6 +126,7 @@ export interface ProviderFnParams { * } */ defaultRootOptions?: CreateRootOptions; + ssr?: BridgeSSRConfig; } /** @@ -135,11 +158,19 @@ export interface RemoteComponentParams< */ export interface RemoteModule { provider: () => { - render: (info: RenderFnParams) => void; + render: (info: RenderFnParams) => void | Promise; destroy: (info: { dom: any }) => void; + renderServer?: ( + context: BridgeServerRenderContext, + ) => Promise; }; } +export type RemoteAppSSRProps = { + ssr?: BridgeSSRResult; + instanceId?: string; +}; + /** * Parameters for a remote app component */ diff --git a/packages/bridge/bridge-react/src/v18.server.ts b/packages/bridge/bridge-react/src/v18.server.ts new file mode 100644 index 00000000000..72b84752cb4 --- /dev/null +++ b/packages/bridge/bridge-react/src/v18.server.ts @@ -0,0 +1,9 @@ +export { createBridgeComponent } from './provider/versions/v18.server'; +export type { CreateRootOptions, Root } from './provider/versions/v18.server'; +export type { + ProviderParams, + ProviderFnParams, + RootType, + DestroyParams, + RenderParams, +} from './types'; diff --git a/packages/bridge/bridge-react/src/v18.ts b/packages/bridge/bridge-react/src/v18.ts index 626628602f2..0b21ad5f54a 100644 --- a/packages/bridge/bridge-react/src/v18.ts +++ b/packages/bridge/bridge-react/src/v18.ts @@ -6,4 +6,5 @@ export type { RootType, DestroyParams, RenderParams, + RemoteAppSSRProps, } from './types'; diff --git a/packages/bridge/bridge-react/vite.config.ts b/packages/bridge/bridge-react/vite.config.ts index e703d5ea572..bbb8f7b4115 100644 --- a/packages/bridge/bridge-react/vite.config.ts +++ b/packages/bridge/bridge-react/vite.config.ts @@ -16,6 +16,7 @@ export default defineConfig({ 'router-v6': path.resolve(__dirname, 'src/router/v6.tsx'), 'router-v7': path.resolve(__dirname, 'src/router/v7.tsx'), v18: path.resolve(__dirname, 'src/v18.ts'), + 'v18.server': path.resolve(__dirname, 'src/v18.server.ts'), v19: path.resolve(__dirname, 'src/v19.ts'), 'lazy-load-component-plugin': path.resolve( __dirname, diff --git a/packages/bridge/bridge-shared/package.json b/packages/bridge/bridge-shared/package.json index 9c59ec8e9c5..67be6000a2c 100644 --- a/packages/bridge/bridge-shared/package.json +++ b/packages/bridge/bridge-shared/package.json @@ -22,6 +22,7 @@ "scripts": { "dev": "vite", "build": "vite build && tsc -p tsconfig.json", + "test": "vitest run", "preview": "vite preview" }, "devDependencies": { @@ -31,6 +32,7 @@ "@vitejs/plugin-vue-jsx": "^4.0.0", "typescript": "7.0.2", "vite": "^5.4.21", + "vitest": "1.6.0", "vue-tsc": "^2.0.6" } } diff --git a/packages/bridge/bridge-shared/src/index.ts b/packages/bridge/bridge-shared/src/index.ts index 825eade3082..4c4886467f5 100644 --- a/packages/bridge/bridge-shared/src/index.ts +++ b/packages/bridge/bridge-shared/src/index.ts @@ -1,2 +1,26 @@ export type { RenderFnParams, ProviderParams } from './type'; +export { BRIDGE_SSR_PROTOCOL_VERSION, BridgeSSRError } from './type'; +export type { + BridgeJSONValue, + BridgeProviderAPI, + BridgeServerRenderContext, + BridgeSSRConfig, + BridgeSSRPrepareResult, + BridgeSSRResult, +} from './type'; export { dispatchPopstateEnv } from './env'; +export { + MF_BRIDGE_INSTANCE_ATTR, + MF_BRIDGE_MODULE_ATTR, + MF_BRIDGE_SSR_ATTR, + MF_BRIDGE_VERSION_ATTR, + assertBridgeJSONValue, + assertBridgeSSRIdentity, + assertBridgeSSRResult, + getBridgeSSRContainerAttrs, + hasBridgeSSRMarkup, + serializeBridgeJSON, + serializeBridgeSSRResult, +} from './ssr'; +export { renderRemoteBridge } from './renderRemoteBridge'; +export type { RenderRemoteBridgeOptions } from './renderRemoteBridge'; diff --git a/packages/bridge/bridge-shared/src/renderRemoteBridge.ts b/packages/bridge/bridge-shared/src/renderRemoteBridge.ts new file mode 100644 index 00000000000..556ad8ba6b8 --- /dev/null +++ b/packages/bridge/bridge-shared/src/renderRemoteBridge.ts @@ -0,0 +1,92 @@ +import { assertBridgeSSRIdentity, assertBridgeSSRResult } from './ssr'; +import { + BridgeSSRError, + type BridgeServerRenderContext, + type BridgeSSRResult, +} from './type'; + +export type RenderRemoteBridgeOptions

> = { + loader: () => Promise>; + export?: string; + moduleName: string; + instanceId: string; + request: Request; + props?: P; +}; + +export async function renderRemoteBridge

>( + options: RenderRemoteBridgeOptions

, +): Promise { + if (typeof window !== 'undefined' || typeof document !== 'undefined') { + throw new BridgeSSRError( + 'renderRemoteBridge can only be called in a server environment', + ); + } + if (!(options.request instanceof Request)) { + throw new BridgeSSRError('Bridge SSR requires a standard Request'); + } + assertBridgeSSRIdentity(options); + if (options.request.signal.aborted) { + throw new BridgeSSRError( + `Bridge SSR request for ${options.moduleName} was aborted`, + options.request.signal.reason, + ); + } + + let remoteModule: Record; + try { + remoteModule = await options.loader(); + } catch (error) { + throw new BridgeSSRError( + `Unable to load Bridge remote ${options.moduleName}`, + error, + ); + } + + const exportName = options.export ?? 'default'; + const factory = remoteModule[exportName]; + if (typeof factory !== 'function') { + throw new BridgeSSRError( + `Bridge remote ${options.moduleName} does not export ${exportName}`, + ); + } + + const provider = factory() as { + renderServer?: ( + context: BridgeServerRenderContext

, + ) => Promise; + }; + if (typeof provider?.renderServer !== 'function') { + throw new BridgeSSRError( + `Bridge remote ${options.moduleName} does not support server rendering`, + ); + } + + let result: BridgeSSRResult; + try { + result = await provider.renderServer({ + moduleName: options.moduleName, + instanceId: options.instanceId, + request: options.request, + signal: options.request.signal, + props: (options.props ?? {}) as P, + }); + } catch (error) { + if (error instanceof BridgeSSRError) throw error; + throw new BridgeSSRError( + `Unable to render Bridge remote ${options.moduleName}`, + error, + ); + } + + assertBridgeSSRResult(result); + if ( + result.moduleName !== options.moduleName || + result.instanceId !== options.instanceId + ) { + throw new BridgeSSRError( + `Bridge remote ${options.moduleName} returned mismatched identity`, + ); + } + return result; +} diff --git a/packages/bridge/bridge-shared/src/ssr.spec.ts b/packages/bridge/bridge-shared/src/ssr.spec.ts new file mode 100644 index 00000000000..4fa61a16d83 --- /dev/null +++ b/packages/bridge/bridge-shared/src/ssr.spec.ts @@ -0,0 +1,75 @@ +import { describe, expect, it, vi } from 'vitest'; +import { + BRIDGE_SSR_PROTOCOL_VERSION, + BridgeSSRError, + assertBridgeJSONValue, + renderRemoteBridge, + serializeBridgeJSON, +} from './index'; + +describe('Bridge SSR V1 contract', () => { + it('escapes executable sequences in host-carried JSON', () => { + expect(serializeBridgeJSON({ value: '\u2028\u2029' })).toBe( + '{"value":"\\u003c/script>\\u2028\\u2029"}', + ); + }); + + it('rejects cyclic and non-JSON state', () => { + const cyclic: Record = {}; + cyclic.self = cyclic; + expect(() => assertBridgeJSONValue(cyclic)).toThrow(/cyclic/); + expect(() => assertBridgeJSONValue({ value: Number.NaN })).toThrow( + /finite/, + ); + }); + + it('loads, renders, and validates a remote provider', async () => { + const renderServer = vi.fn(async (context) => ({ + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: context.moduleName, + instanceId: context.instanceId, + html: '

remote

', + dehydratedState: { ready: true }, + })); + const request = new Request('http://bridge.test/detail'); + await expect( + renderRemoteBridge({ + loader: async () => ({ default: () => ({ renderServer }) }), + moduleName: 'remote/app', + instanceId: 'remote-1', + request, + props: { intentional: true }, + }), + ).resolves.toMatchObject({ html: '

remote

' }); + expect(renderServer).toHaveBeenCalledWith( + expect.objectContaining({ request, signal: request.signal }), + ); + }); + + it('adds context to load and contract failures', async () => { + await expect( + renderRemoteBridge({ + loader: async () => { + throw new Error('network'); + }, + moduleName: 'remote/app', + instanceId: 'remote-1', + request: new Request('http://bridge.test/'), + }), + ).rejects.toEqual( + expect.objectContaining({ + name: 'BridgeSSRError', + message: 'Unable to load Bridge remote remote/app', + }), + ); + + await expect( + renderRemoteBridge({ + loader: async () => ({ default: () => ({}) }), + moduleName: 'remote/app', + instanceId: 'remote-1', + request: new Request('http://bridge.test/'), + }), + ).rejects.toBeInstanceOf(BridgeSSRError); + }); +}); diff --git a/packages/bridge/bridge-shared/src/ssr.ts b/packages/bridge/bridge-shared/src/ssr.ts new file mode 100644 index 00000000000..e295ae62b1e --- /dev/null +++ b/packages/bridge/bridge-shared/src/ssr.ts @@ -0,0 +1,175 @@ +import { + BRIDGE_SSR_PROTOCOL_VERSION, + BridgeSSRError, + type BridgeJSONValue, + type BridgeSSRResult, +} from './type'; + +export const MF_BRIDGE_SSR_ATTR = 'data-mf-bridge-ssr'; +export const MF_BRIDGE_VERSION_ATTR = 'data-mf-bridge-version'; +export const MF_BRIDGE_MODULE_ATTR = 'data-mf-bridge-module'; +export const MF_BRIDGE_INSTANCE_ATTR = 'data-mf-bridge-instance'; + +function assertPrintable(value: string, label: string) { + if (!value || /[\u0000-\u001f\u007f]/.test(value)) { + throw new BridgeSSRError( + `Bridge SSR ${label} must be a non-empty printable string`, + ); + } +} + +export function assertBridgeSSRIdentity(value: { + moduleName: string; + instanceId: string; +}) { + assertPrintable(value.moduleName, 'moduleName'); + assertPrintable(value.instanceId, 'instanceId'); +} + +function validateJSON( + value: unknown, + path: string, + ancestors: WeakSet, +): void { + if ( + value === null || + typeof value === 'string' || + typeof value === 'boolean' + ) { + return; + } + if (typeof value === 'number') { + if (Number.isFinite(value)) return; + throw new BridgeSSRError(`Bridge SSR value at ${path} must be finite`); + } + if (typeof value !== 'object' || value === undefined) { + throw new BridgeSSRError( + `Bridge SSR value at ${path} must be JSON serializable`, + ); + } + if (ancestors.has(value)) { + throw new BridgeSSRError(`Bridge SSR value at ${path} must not be cyclic`); + } + ancestors.add(value); + if (Array.isArray(value)) { + for (let index = 0; index < value.length; index += 1) { + if (!Object.prototype.hasOwnProperty.call(value, index)) { + throw new BridgeSSRError( + `Bridge SSR array at ${path} must not be sparse`, + ); + } + validateJSON(value[index], `${path}[${index}]`, ancestors); + } + } else { + const prototype = Object.getPrototypeOf(value); + if (prototype !== Object.prototype && prototype !== null) { + throw new BridgeSSRError( + `Bridge SSR value at ${path} must use plain objects`, + ); + } + for (const [key, descriptor] of Object.entries( + Object.getOwnPropertyDescriptors(value), + )) { + if ( + !descriptor.enumerable || + !Object.prototype.hasOwnProperty.call(descriptor, 'value') + ) { + throw new BridgeSSRError( + `Bridge SSR value at ${path}.${key} must be an enumerable data property`, + ); + } + validateJSON(descriptor.value, `${path}.${key}`, ancestors); + } + if (Object.getOwnPropertySymbols(value).length > 0) { + throw new BridgeSSRError( + `Bridge SSR value at ${path} must not contain symbol keys`, + ); + } + } + ancestors.delete(value); +} + +export function assertBridgeJSONValue( + value: unknown, +): asserts value is BridgeJSONValue { + validateJSON(value, 'state', new WeakSet()); +} + +export function serializeBridgeJSON(value: BridgeJSONValue): string { + assertBridgeJSONValue(value); + return JSON.stringify(value) + .replace(/; + const allowedKeys = new Set([ + 'protocolVersion', + 'moduleName', + 'instanceId', + 'html', + 'dehydratedState', + ]); + if (Object.keys(result).some((key) => !allowedKeys.has(key))) { + throw new BridgeSSRError('Bridge SSR returned unsupported result fields'); + } + if ( + result.protocolVersion !== BRIDGE_SSR_PROTOCOL_VERSION || + typeof result.moduleName !== 'string' || + typeof result.instanceId !== 'string' || + typeof result.html !== 'string' + ) { + throw new BridgeSSRError('Bridge SSR returned an incompatible result'); + } + assertBridgeSSRIdentity({ + moduleName: result.moduleName, + instanceId: result.instanceId, + }); + if (result.dehydratedState !== undefined) { + assertBridgeJSONValue(result.dehydratedState); + } +} + +export function getBridgeSSRContainerAttrs(value: { + moduleName: string; + instanceId: string; +}): Record { + assertBridgeSSRIdentity(value); + return { + [MF_BRIDGE_SSR_ATTR]: 'true', + [MF_BRIDGE_VERSION_ATTR]: String(BRIDGE_SSR_PROTOCOL_VERSION), + [MF_BRIDGE_MODULE_ATTR]: value.moduleName, + [MF_BRIDGE_INSTANCE_ATTR]: value.instanceId, + }; +} + +export function hasBridgeSSRMarkup( + dom: HTMLElement, + value?: { moduleName?: string; instanceId?: string }, +) { + return ( + dom.getAttribute(MF_BRIDGE_SSR_ATTR) === 'true' && + dom.getAttribute(MF_BRIDGE_VERSION_ATTR) === + String(BRIDGE_SSR_PROTOCOL_VERSION) && + (!value?.moduleName || + dom.getAttribute(MF_BRIDGE_MODULE_ATTR) === value.moduleName) && + (!value?.instanceId || + dom.getAttribute(MF_BRIDGE_INSTANCE_ATTR) === value.instanceId) && + dom.hasChildNodes() + ); +} diff --git a/packages/bridge/bridge-shared/src/type.ts b/packages/bridge/bridge-shared/src/type.ts index e788d81a6ac..29bfe5af306 100644 --- a/packages/bridge/bridge-shared/src/type.ts +++ b/packages/bridge/bridge-shared/src/type.ts @@ -1,5 +1,60 @@ import type { CSSProperties } from 'react'; +export const BRIDGE_SSR_PROTOCOL_VERSION = 1 as const; + +export type BridgeJSONValue = + | null + | boolean + | number + | string + | BridgeJSONValue[] + | { [key: string]: BridgeJSONValue }; + +export type BridgeSSRPrepareResult

> = { + props?: P; + dehydratedState?: BridgeJSONValue; +}; + +export type BridgeSSRConfig

> = + | boolean + | { + prepare?: ( + context: BridgeServerRenderContext

, + ) => + | void + | BridgeSSRPrepareResult

+ | Promise>; + hydrate?: ( + state: BridgeJSONValue | undefined, + ) => Partial

| Record; + }; + +export type BridgeServerRenderContext

> = { + moduleName: string; + instanceId: string; + request: Request; + signal: AbortSignal; + props: P; +}; + +export type BridgeSSRResult = { + protocolVersion: typeof BRIDGE_SSR_PROTOCOL_VERSION; + moduleName: string; + instanceId: string; + html: string; + dehydratedState?: BridgeJSONValue; +}; + +export class BridgeSSRError extends Error { + override readonly cause?: unknown; + + constructor(message: string, cause?: unknown) { + super(message); + this.name = 'BridgeSSRError'; + this.cause = cause; + } +} + export interface ProviderParams { moduleName?: string; basename?: string; @@ -11,4 +66,15 @@ export interface ProviderParams { export interface RenderFnParams extends ProviderParams { dom: HTMLElement; + instanceId?: string; + ssrState?: BridgeJSONValue; + signal?: AbortSignal; +} + +export interface BridgeProviderAPI { + render: (info: RenderFnParams) => void | Promise; + destroy: (info: { dom: HTMLElement }) => void; + renderServer?: ( + context: BridgeServerRenderContext, + ) => Promise; } diff --git a/packages/bridge/vue3-bridge/package.json b/packages/bridge/vue3-bridge/package.json index 05ba58f5357..ff944f92aaf 100644 --- a/packages/bridge/vue3-bridge/package.json +++ b/packages/bridge/vue3-bridge/package.json @@ -15,6 +15,22 @@ "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "browser": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "node": { + "import": "./dist/index.server.js", + "require": "./dist/index.server.cjs" + }, + "import": "./dist/index.js", + "require": "./dist/index.cjs" + }, + "./*": "./*" + }, "files": [ "dist/", "package.json", @@ -28,7 +44,13 @@ }, "peerDependencies": { "vue": "=3", - "vue-router": "=4" + "vue-router": "=4", + "@vue/server-renderer": "^3.0.0" + }, + "peerDependenciesMeta": { + "@vue/server-renderer": { + "optional": true + } }, "dependencies": { "@module-federation/bridge-shared": "workspace:*", @@ -45,6 +67,7 @@ "vite": "^5.4.21", "vue": "^3.5.30", "vue-router": "4.4.5", + "@vue/server-renderer": "^3.5.30", "vue-tsc": "^2.2.12" } } diff --git a/packages/bridge/vue3-bridge/rstest.config.ts b/packages/bridge/vue3-bridge/rstest.config.ts index c24e78e6123..5d1bb8841bb 100644 --- a/packages/bridge/vue3-bridge/rstest.config.ts +++ b/packages/bridge/vue3-bridge/rstest.config.ts @@ -4,6 +4,11 @@ import { pluginVueJsx } from '@rsbuild/plugin-vue-jsx'; import { resolve } from 'path'; export default defineConfig({ + source: { + define: { + __APP_VERSION__: '"unknown"', + }, + }, plugins: [ pluginBabel({ include: /\.(?:jsx|tsx)$/, diff --git a/packages/bridge/vue3-bridge/src/index.server.ts b/packages/bridge/vue3-bridge/src/index.server.ts new file mode 100644 index 00000000000..a260a91227a --- /dev/null +++ b/packages/bridge/vue3-bridge/src/index.server.ts @@ -0,0 +1,16 @@ +import { + createBridgeComponentWithServerRenderer, + type ProviderFnParams, +} from './provider'; +import { renderBridgeVueToString } from './server-renderer'; + +export function createBridgeComponent(bridgeInfo: ProviderFnParams) { + return createBridgeComponentWithServerRenderer( + bridgeInfo, + renderBridgeVueToString, + ); +} + +export type { ProviderFnParams } from './provider'; +export { createRemoteComponent, createRemoteAppComponent } from './create'; +export type { RenderFnParams } from '@module-federation/bridge-shared'; diff --git a/packages/bridge/vue3-bridge/src/provider.spec.ts b/packages/bridge/vue3-bridge/src/provider.spec.ts new file mode 100644 index 00000000000..9e34fec2006 --- /dev/null +++ b/packages/bridge/vue3-bridge/src/provider.spec.ts @@ -0,0 +1,46 @@ +import { describe, expect, it, rs } from '@rstest/core'; +import { defineComponent, h } from 'vue'; +import { createMemoryHistory, createRouter } from 'vue-router'; +import { createBridgeComponentWithServerRenderer } from './provider'; + +describe('Vue Bridge server provider', () => { + it('creates a request-local app and returns the thin V1 result', async () => { + const serverRenderer = rs.fn(async () => '

vue remote

'); + const factory = createBridgeComponentWithServerRenderer( + { + rootComponent: defineComponent(() => () => h('p', 'vue remote')), + appOptions: () => ({ + router: createRouter({ + history: createMemoryHistory(), + routes: [ + { + path: '/detail', + component: defineComponent(() => () => h('p')), + }, + ], + }), + }), + ssr: true, + }, + serverRenderer, + ); + const provider = factory(); + const request = new Request('http://bridge.test/detail'); + await expect( + provider.renderServer!({ + moduleName: 'vue/remote', + instanceId: 'vue-1', + request, + signal: request.signal, + props: {}, + }), + ).resolves.toEqual({ + protocolVersion: 1, + moduleName: 'vue/remote', + instanceId: 'vue-1', + html: '

vue remote

', + dehydratedState: undefined, + }); + expect(serverRenderer).toHaveBeenCalledOnce(); + }); +}); diff --git a/packages/bridge/vue3-bridge/src/provider.ts b/packages/bridge/vue3-bridge/src/provider.ts index 6b3e66eee41..0c2e6723aad 100644 --- a/packages/bridge/vue3-bridge/src/provider.ts +++ b/packages/bridge/vue3-bridge/src/provider.ts @@ -1,6 +1,14 @@ import * as Vue from 'vue'; import * as VueRouter from 'vue-router'; -import { RenderFnParams } from '@module-federation/bridge-shared'; +import { + BRIDGE_SSR_PROTOCOL_VERSION, + hasBridgeSSRMarkup, + type BridgeSSRConfig, + type BridgeSSRPrepareResult, + type BridgeSSRResult, + type BridgeServerRenderContext, + type RenderFnParams, +} from '@module-federation/bridge-shared'; import { LoggerInstance } from './utils'; import { getInstance } from '@module-federation/runtime'; import { processRoutes } from './routeUtils'; @@ -11,6 +19,9 @@ type AddOptionsFnParams = { app: Vue.App; basename: RenderFnParams['basename']; memoryRoute: RenderFnParams['memoryRoute']; + request?: Request; + signal?: AbortSignal; + ssr: boolean; [key: string]: any; }; @@ -18,95 +29,193 @@ export type ProviderFnParams = { rootComponent: Vue.Component; appOptions: (params: AddOptionsFnParams) => { router?: VueRouter.Router; - /** Called with the bridge's internal router after creation but before navigation. - * Use this to register global guards (beforeEach, afterEach, etc.) that would - * otherwise be lost when the bridge recreates the router. */ afterRouterCreate?: (router: VueRouter.Router) => void; } | void; + ssr?: BridgeSSRConfig>; }; -export function createBridgeComponent(bridgeInfo: ProviderFnParams) { - const rootMap = new Map(); - const instance = getInstance(); +export type BridgeVueServerRenderer = ( + app: Vue.App, + context: Record, +) => string | Promise; + +type BridgeAppInfo = Omit & { + dom?: HTMLElement; + request?: Request; + url?: string; +}; + +async function setupBridgeApp( + bridgeInfo: ProviderFnParams, + info: BridgeAppInfo, + props: Record, + mode: 'ssr' | 'hydrate' | 'csr', +) { + if (info.signal?.aborted) throw info.signal.reason; + const app = (mode === 'csr' ? Vue.createApp : Vue.createSSRApp)( + bridgeInfo.rootComponent, + props, + ); + const options = bridgeInfo.appOptions({ + ...props, + app, + basename: info.basename, + memoryRoute: info.memoryRoute, + hashRoute: info.hashRoute, + request: info.request, + signal: info.signal, + ssr: mode === 'ssr', + }); + let router: VueRouter.Router | undefined; + if (options?.router) { + const effectiveMemoryRoute = + mode === 'ssr' ? { entryPath: info.url ?? '/' } : info.memoryRoute; + const processed = processRoutes({ + router: options.router, + basename: info.basename, + memoryRoute: effectiveMemoryRoute, + hashRoute: info.hashRoute, + }); + router = VueRouter.createRouter({ + ...options.router.options, + history: processed.history, + routes: processed.routes, + }); + processed.patchRouter?.(router); + options.afterRouterCreate?.(router); + if (effectiveMemoryRoute) { + await router.push(effectiveMemoryRoute.entryPath); + } + app.use(router); + if (mode !== 'csr') await router.isReady(); + } + if (info.signal?.aborted) throw info.signal.reason; + return { app, router }; +} + +function serverLocation(request: Request, basename?: string) { + const url = new URL(request.url); + let pathname = url.pathname || '/'; + const base = (basename || '/').replace(/\/$/, '') || '/'; + if (base !== '/' && (pathname === base || pathname.startsWith(`${base}/`))) { + pathname = pathname.slice(base.length) || '/'; + } + return `${pathname}${url.search}`; +} + +export function createBridgeComponentWithServerRenderer( + bridgeInfo: ProviderFnParams, + serverRenderer?: BridgeVueServerRenderer, +) { + const roots = new Map(); + const runtime = getInstance(); + return () => { - return { + const config = + typeof bridgeInfo.ssr === 'object' ? bridgeInfo.ssr : undefined; + const provider: { + __APP_VERSION__: string; + render: (info: RenderFnParams) => Promise; + destroy: (info: { dom: HTMLElement }) => void; + renderServer?: ( + context: BridgeServerRenderContext>, + ) => Promise; + } = { __APP_VERSION__, - async render(info: RenderFnParams) { - LoggerInstance.debug(`createBridgeComponent render Info`, info); + async render(info) { + if (info.signal?.aborted) return; const { moduleName, dom, basename, memoryRoute, hashRoute, - ...propsInfo + instanceId, + ssrState, + signal, + ...applicationProps } = info; - const app = Vue.createApp(bridgeInfo.rootComponent, propsInfo); - rootMap.set(dom, app); - const beforeBridgeRenderRes = - await instance?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info); - + await runtime?.bridgeHook?.lifecycle?.beforeBridgeRender?.emit(info); const extraProps = beforeBridgeRenderRes && typeof beforeBridgeRenderRes === 'object' && - beforeBridgeRenderRes?.extraProps - ? beforeBridgeRenderRes?.extraProps + beforeBridgeRenderRes.extraProps + ? beforeBridgeRenderRes.extraProps : {}; - - const bridgeOptions = bridgeInfo.appOptions({ - app, - basename, - memoryRoute, - hashRoute, - ...propsInfo, - ...extraProps, + const shouldHydrate = hasBridgeSSRMarkup(dom, { + moduleName, + instanceId, }); - if (bridgeOptions?.router) { - const { history, routes, patchRouter } = processRoutes({ - router: bridgeOptions.router, - basename: info.basename, - memoryRoute: info.memoryRoute, - hashRoute: info.hashRoute, - }); - - const router = VueRouter.createRouter({ - ...bridgeOptions.router.options, - history, - routes, - }); - - if (patchRouter) { - patchRouter(router); - } - - if (bridgeOptions.afterRouterCreate) { - bridgeOptions.afterRouterCreate(router); - } - - LoggerInstance.debug(`createBridgeComponent render router info>>>`, { - moduleName, - router, - }); - // memory route Initializes the route - if (memoryRoute) { - await router.push(memoryRoute.entryPath); - } - - app.use(router); - } - - app.mount(dom); - instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info); + const hydrated = + shouldHydrate && config?.hydrate ? config.hydrate(ssrState) : {}; + const nextProps = { ...hydrated, ...applicationProps, ...extraProps }; + const { app } = await setupBridgeApp( + bridgeInfo, + { basename, memoryRoute, hashRoute, instanceId, signal }, + nextProps, + shouldHydrate ? 'hydrate' : 'csr', + ); + if (signal?.aborted) return; + roots.set(dom, app); + app.mount(dom, shouldHydrate); + runtime?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info); + LoggerInstance.debug('createBridgeComponent rendered', { moduleName }); }, - destroy(info: { dom: HTMLElement }) { - LoggerInstance.debug(`createBridgeComponent destroy Info`, info); - const root = rootMap.get(info?.dom); - - instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit(info); - root?.unmount(); - instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit(info); + destroy({ dom }) { + const info = { dom }; + LoggerInstance.debug('createBridgeComponent destroy Info', info); + runtime?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit(info); + roots.get(dom)?.unmount(); + roots.delete(dom); + runtime?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit(info); }, }; + + if (serverRenderer && bridgeInfo.ssr) { + provider.renderServer = async (context) => { + if (context.signal.aborted) throw context.signal.reason; + const preparedValue = await config?.prepare?.(context); + const prepared = (preparedValue || {}) as BridgeSSRPrepareResult< + Record + >; + const renderInfo = prepared.props ?? context.props; + const { basename, memoryRoute, hashRoute, ...applicationProps } = + renderInfo; + delete applicationProps.moduleName; + const { app } = await setupBridgeApp( + bridgeInfo, + { + moduleName: context.moduleName, + basename: basename as string | undefined, + memoryRoute: memoryRoute as RenderFnParams['memoryRoute'], + hashRoute: Boolean(hashRoute), + request: context.request, + signal: context.signal, + url: serverLocation( + context.request, + basename as string | undefined, + ), + }, + applicationProps, + 'ssr', + ); + const ssrContext: Record = {}; + const html = await serverRenderer(app, ssrContext); + if (context.signal.aborted) throw context.signal.reason; + return { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: context.moduleName, + instanceId: context.instanceId, + html, + dehydratedState: prepared.dehydratedState, + }; + }; + } + return provider; }; } + +export function createBridgeComponent(bridgeInfo: ProviderFnParams) { + return createBridgeComponentWithServerRenderer(bridgeInfo); +} diff --git a/packages/bridge/vue3-bridge/src/remoteApp.tsx b/packages/bridge/vue3-bridge/src/remoteApp.tsx index 3a04bb951f2..d32f5e4e947 100644 --- a/packages/bridge/vue3-bridge/src/remoteApp.tsx +++ b/packages/bridge/vue3-bridge/src/remoteApp.tsx @@ -9,7 +9,11 @@ import { useAttrs, nextTick, } from 'vue'; -import { dispatchPopstateEnv } from '@module-federation/bridge-shared'; +import { + dispatchPopstateEnv, + getBridgeSSRContainerAttrs, + type BridgeSSRResult, +} from '@module-federation/bridge-shared'; import { useRoute } from 'vue-router'; import { LoggerInstance } from './utils'; import { getInstance } from '@module-federation/runtime'; @@ -23,6 +27,8 @@ export default defineComponent({ hashRoute: Boolean, providerInfo: Function, rootAttrs: Object, + ssr: Object, + instanceId: String, }, inheritAttrs: false, setup(props) { @@ -35,6 +41,8 @@ export default defineComponent({ const route = useRoute(); const hostInstance = getInstance(); const componentAttrs = useAttrs(); + const ssrPayload = props.ssr as BridgeSSRResult | undefined; + const instanceId = props.instanceId || ssrPayload?.instanceId; const getBridgeRenderProps = () => ({ name: props.moduleName, @@ -58,6 +66,8 @@ export default defineComponent({ basename: props.basename, memoryRoute: props.memoryRoute, hashRoute: props.hashRoute, + instanceId, + ssrState: ssrPayload?.dehydratedState, }; LoggerInstance.debug( `createRemoteAppComponent LazyComponent render >>>`, @@ -149,6 +159,18 @@ export default defineComponent({ destroyComponent(); }); - return () =>
; + return () => ( +
+ ); }, }); diff --git a/packages/bridge/vue3-bridge/src/server-renderer.ts b/packages/bridge/vue3-bridge/src/server-renderer.ts new file mode 100644 index 00000000000..bf6d7415596 --- /dev/null +++ b/packages/bridge/vue3-bridge/src/server-renderer.ts @@ -0,0 +1,7 @@ +import { renderToString } from '@vue/server-renderer'; +import type { BridgeVueServerRenderer } from './provider'; + +export const renderBridgeVueToString: BridgeVueServerRenderer = ( + app, + context, +) => renderToString(app, context); diff --git a/packages/bridge/vue3-bridge/vite.config.ts b/packages/bridge/vue3-bridge/vite.config.ts index 1edf7166783..f5bfe76d640 100644 --- a/packages/bridge/vue3-bridge/vite.config.ts +++ b/packages/bridge/vue3-bridge/vite.config.ts @@ -8,12 +8,22 @@ export default defineConfig({ plugins: [vue(), vueJsx()], build: { lib: { - entry: path.resolve(__dirname, 'src/index.ts'), + entry: { + index: path.resolve(__dirname, 'src/index.ts'), + 'index.server': path.resolve(__dirname, 'src/index.server.ts'), + }, formats: ['cjs', 'es'], - fileName: 'index', + fileName: (format, entryName) => + entryName === 'index' + ? format === 'es' + ? 'index.js' + : 'index.cjs' + : format === 'es' + ? `${entryName}.js` + : `${entryName}.cjs`, }, rollupOptions: { - external: ['vue', 'vue-router'], + external: ['vue', 'vue-router', '@vue/server-renderer'], }, }, define: { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ea99f92f2e..8c841f7d3bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,7 +127,7 @@ importers: version: 6.0.1(rollup@4.59.0) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(typescript@6.0.3) '@rspack/cli': specifier: 1.3.9 version: 1.3.9(@rspack/core@1.3.9(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.104.1) @@ -139,7 +139,7 @@ importers: version: 1.1.1(@rspack/core@1.3.9(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.104.1) '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(jsdom@20.0.3) '@storybook/addon-docs': specifier: 9.0.17 version: 9.0.17(@types/react@19.2.14)(storybook@8.6.17(prettier@3.8.1)) @@ -355,7 +355,7 @@ importers: version: 0.2.1(@rsbuild/core@1.7.3) rstest-fetch-mock: specifier: 0.1.0 - version: 0.1.0(@rstest/core@0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3)) + version: 0.1.0(@rstest/core@0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(jsdom@20.0.3)) serve: specifier: ^14.2.4 version: 14.2.5 @@ -549,6 +549,196 @@ importers: specifier: 5.104.1 version: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) + apps/bridge-ssr-demo/host: + dependencies: + '@module-federation/bridge-react': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-react + '@module-federation/bridge-shared': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-shared + '@module-federation/enhanced': + specifier: workspace:* + version: link:../../../packages/enhanced + express: + specifier: ^4.21.2 + version: 4.22.1 + react: + specifier: ~18.3.1 + version: 18.3.1 + react-dom: + specifier: ~18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: 6.30.2 + version: 6.30.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + vue: + specifier: ^3.5.30 + version: 3.5.30(typescript@5.0.4) + vue-router: + specifier: 4.4.5 + version: 4.4.5(vue@3.5.30(typescript@5.0.4)) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: workspace:* + version: link:../../../packages/rsbuild-plugin + '@playwright/test': + specifier: 1.57.0 + version: 1.57.0 + '@rsbuild/core': + specifier: 1.7.3 + version: 1.7.3 + '@rsbuild/plugin-react': + specifier: ^1.4.5 + version: 1.4.5(@rsbuild/core@1.7.3)(webpack-hot-middleware@2.26.1) + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/react': + specifier: ~18.2.0 + version: 18.2.79 + '@types/react-dom': + specifier: ~18.3.0 + version: 18.3.7(@types/react@18.2.79) + typescript: + specifier: ~5.0.4 + version: 5.0.4 + + apps/bridge-ssr-demo/host-vue: + dependencies: + '@module-federation/bridge-react': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-react + '@module-federation/bridge-shared': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-shared + '@module-federation/bridge-vue3': + specifier: workspace:* + version: link:../../../packages/bridge/vue3-bridge + '@module-federation/enhanced': + specifier: workspace:* + version: link:../../../packages/enhanced + '@module-federation/runtime': + specifier: workspace:* + version: link:../../../packages/runtime + '@vue/server-renderer': + specifier: ^3.5.30 + version: 3.5.30(vue@3.5.30(typescript@5.0.4)) + express: + specifier: ^4.21.2 + version: 4.22.1 + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1(react@18.3.1) + vue: + specifier: ^3.5.30 + version: 3.5.30(typescript@5.0.4) + vue-router: + specifier: 4.4.5 + version: 4.4.5(vue@3.5.30(typescript@5.0.4)) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: workspace:* + version: link:../../../packages/rsbuild-plugin + '@playwright/test': + specifier: 1.57.0 + version: 1.57.0 + '@rsbuild/core': + specifier: 1.7.3 + version: 1.7.3 + '@rsbuild/plugin-vue': + specifier: ^1.2.6 + version: 1.2.9(@rsbuild/core@1.7.3)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.0.4)) + typescript: + specifier: ~5.0.4 + version: 5.0.4 + + apps/bridge-ssr-demo/remote-react: + dependencies: + '@module-federation/bridge-react': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-react + react: + specifier: ~18.3.1 + version: 18.3.1 + react-dom: + specifier: ~18.3.1 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: 6.30.2 + version: 6.30.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: workspace:* + version: link:../../../packages/rsbuild-plugin + '@rsbuild/core': + specifier: 1.7.3 + version: 1.7.3 + '@rsbuild/plugin-react': + specifier: ^1.4.5 + version: 1.4.5(@rsbuild/core@1.7.3)(webpack-hot-middleware@2.26.1) + '@types/react': + specifier: ~18.2.0 + version: 18.2.79 + '@types/react-dom': + specifier: ~18.3.0 + version: 18.3.7(@types/react@18.2.79) + typescript: + specifier: ~5.0.4 + version: 5.0.4 + + apps/bridge-ssr-demo/remote-vue: + dependencies: + '@module-federation/bridge-vue3': + specifier: workspace:* + version: link:../../../packages/bridge/vue3-bridge + '@vue/server-renderer': + specifier: ^3.5.30 + version: 3.5.30(vue@3.5.30(typescript@5.0.4)) + vue: + specifier: ^3.5.30 + version: 3.5.30(typescript@5.0.4) + vue-router: + specifier: 4.4.5 + version: 4.4.5(vue@3.5.30(typescript@5.0.4)) + devDependencies: + '@module-federation/rsbuild-plugin': + specifier: workspace:* + version: link:../../../packages/rsbuild-plugin + '@module-federation/vite': + specifier: 1.16.16 + version: 1.16.16(typescript@5.0.4)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@5.0.4)) + '@rsbuild/core': + specifier: 1.7.3 + version: 1.7.3 + '@rsbuild/plugin-vue': + specifier: ^1.2.6 + version: 1.2.9(@rsbuild/core@1.7.3)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.0.4)) + '@vitejs/plugin-vue': + specifier: ^5.0.4 + version: 5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@5.0.4)) + typescript: + specifier: ~5.0.4 + version: 5.0.4 + vite: + specifier: ^5.4.21 + version: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) + + apps/bridge-ssr-demo/shared: + dependencies: + '@module-federation/bridge-shared': + specifier: workspace:* + version: link:../../../packages/bridge/bridge-shared + '@rsbuild/core': + specifier: 1.7.3 + version: 1.7.3 + express: + specifier: ^4.21.2 + version: 4.22.1 + apps/bundle-size: dependencies: antd: @@ -1091,7 +1281,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1110,7 +1300,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1152,7 +1342,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1171,7 +1361,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1222,7 +1412,7 @@ importers: version: link:../../../packages/storybook-addon '@rsbuild/plugin-react': specifier: ^1.4.5 - version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) + version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: ^0.9.0 version: 0.9.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(typescript@5.9.3) @@ -1249,7 +1439,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1268,7 +1458,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1323,7 +1513,7 @@ importers: version: link:../../../packages/rsbuild-plugin '@rsbuild/plugin-react': specifier: ^1.4.5 - version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) + version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: ^0.9.0 version: 0.9.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(typescript@5.9.3) @@ -1341,7 +1531,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1360,7 +1550,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1402,7 +1592,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1421,7 +1611,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1463,7 +1653,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1482,7 +1672,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1524,7 +1714,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1543,7 +1733,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1585,7 +1775,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../packages/modernjs-v3 @@ -1604,7 +1794,7 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) @@ -1880,7 +2070,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) apps/react-ts-host: dependencies: @@ -2054,10 +2244,10 @@ importers: version: link:../../../packages/rsbuild-plugin '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^18.2.79 version: 18.3.28 @@ -2103,10 +2293,10 @@ importers: version: link:../../../packages/rsbuild-plugin '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^18.2.79 version: 18.3.28 @@ -2140,10 +2330,10 @@ importers: version: link:../../../packages/rsbuild-plugin '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-vue': specifier: ^2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) tailwindcss: specifier: ^3.4.3 version: 3.4.13(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@26.1.0)(typescript@7.0.2)) @@ -2180,10 +2370,10 @@ importers: version: 1.24.0(react-dom@17.0.2(react@17.0.2))(react@17.0.2) '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@0.7.5(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@0.7.5(@swc/helpers@0.5.23)) '@rsbuild/shared': specifier: ^0.7.10 version: 0.7.10(@swc/helpers@0.5.23) @@ -2226,10 +2416,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^18.2.79 version: 18.3.28 @@ -2257,10 +2447,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-vue': specifier: ^2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) '@vue/tsconfig': specifier: ^0.5.1 version: 0.5.1 @@ -2300,10 +2490,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^18.2.79 version: 18.3.28 @@ -2340,10 +2530,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^19.0.0 version: 19.2.14 @@ -2383,10 +2573,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@types/react': specifier: ^18.2.79 version: 18.3.28 @@ -2410,10 +2600,10 @@ importers: version: link:../../packages/storybook-addon '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@types/react': specifier: ^18.3.11 version: 18.3.28 @@ -2431,10 +2621,10 @@ importers: version: 8.6.17(prettier@3.8.1) storybook-addon-rslib: specifier: ^1.0.1 - version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2) + version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2) storybook-react-rsbuild: specifier: ^1.0.1 - version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) + version: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) apps/runtime-demo/3005-runtime-host: dependencies: @@ -2564,10 +2754,10 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) apps/shared-tree-shaking/no-server/host: dependencies: @@ -2576,7 +2766,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/enhanced': specifier: workspace:* version: link:../../../../packages/enhanced @@ -2595,13 +2785,13 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/plugin-server': specifier: 2.68.0 - version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-runtime': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -2646,7 +2836,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/enhanced': specifier: workspace:* version: link:../../../../packages/enhanced @@ -2665,13 +2855,13 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 - version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -2713,7 +2903,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../../packages/modernjs-v3 @@ -2732,16 +2922,16 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 - version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-runtime': specifier: 3.0.1 - version: 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -2789,7 +2979,7 @@ importers: version: 7.28.2 '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@module-federation/modern-js-v3': specifier: workspace:* version: link:../../../../packages/modernjs-v3 @@ -2808,13 +2998,13 @@ importers: version: 2.59.0(typescript@7.0.2) '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/eslint-config': specifier: 2.59.0 version: 2.59.0(typescript@7.0.2) '@modern-js/plugin-server': specifier: 2.68.0 - version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/tsconfig': specifier: 3.0.1 version: 3.0.1 @@ -2859,10 +3049,10 @@ importers: version: link:../../packages/runtime '@rsbuild/plugin-sass': specifier: ^2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@rspress/core': specifier: 2.0.14 - version: 2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) + version: 2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) framer-motion: specifier: ^10.0.0 version: 10.18.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -2893,7 +3083,7 @@ importers: version: 19.2.3(@types/react@19.2.14) zephyr-rspress-plugin: specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@rspress/core@2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) + version: 1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@rspress/core@2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) packages/assemble-release-plan: dependencies: @@ -2937,7 +3127,7 @@ importers: version: link:../../runtime-core '@rsbuild/plugin-react': specifier: 2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@testing-library/jest-dom': specifier: 6.6.3 version: 6.6.3 @@ -2962,6 +3152,9 @@ importers: hono: specifier: 4.12.26 version: 4.12.26 + jsdom: + specifier: 20.0.3 + version: 20.0.3 react: specifier: 18.3.1 version: 18.3.1 @@ -3014,6 +3207,9 @@ importers: vite: specifier: ^5.4.21 version: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) + vitest: + specifier: 1.6.0 + version: 1.6.0(@edge-runtime/vm@3.2.0)(@types/node@20.19.5)(@vitest/ui@1.6.0)(jsdom@20.0.3)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) vue-tsc: specifier: ^2.0.6 version: 2.2.12(typescript@7.0.2) @@ -3032,10 +3228,10 @@ importers: devDependencies: '@rsbuild/plugin-babel': specifier: 2.0.1 - version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)) + version: 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)) '@rsbuild/plugin-vue-jsx': specifier: 2.0.1 - version: 2.0.1(@babel/core@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + version: 2.0.1(@babel/core@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@types/react': specifier: ^18.3.11 version: 18.3.28 @@ -3045,6 +3241,9 @@ importers: '@vitejs/plugin-vue-jsx': specifier: ^4.0.0 version: 4.2.0(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2)) + '@vue/server-renderer': + specifier: ^3.5.30 + version: 3.5.30(vue@3.5.30(typescript@7.0.2)) typescript: specifier: 7.0.2 version: 7.0.2 @@ -3212,7 +3411,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@types/glob': specifier: 7.2.0 version: 7.2.0 @@ -3255,7 +3454,7 @@ importers: version: link:../runtime '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) '@types/ws': specifier: 8.5.12 version: 8.5.12 @@ -3391,7 +3590,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) typescript: specifier: 7.0.2 version: 7.0.2 @@ -3445,7 +3644,7 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3) '@types/node': specifier: ^20.19.5 version: 20.19.5 @@ -3517,7 +3716,7 @@ importers: version: 0.7.28 '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3) '@types/node': specifier: ^20.0.0 version: 20.19.5 @@ -3544,7 +3743,7 @@ importers: version: 0.13.0 '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3) '@types/node': specifier: ^20.0.0 version: 20.19.5 @@ -3626,10 +3825,10 @@ importers: version: 1.4.5(@rsbuild/core@1.3.21)(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: 0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) '@types/react': specifier: ^18.3.11 version: 18.3.28 @@ -3681,34 +3880,34 @@ importers: devDependencies: '@modern-js/app-tools': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) '@modern-js/module-tools': specifier: 2.70.5 version: 2.70.5(@types/node@26.1.0)(typescript@7.0.2) '@modern-js/runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@modern-js/server-runtime': specifier: 3.5.0 - version: 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@module-federation/manifest': specifier: workspace:* version: link:../manifest '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: 1.4.5 - version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) + version: 1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1) '@rslib/core': specifier: 0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@rspack/core': specifier: 2.0.6 - version: 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + version: 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) '@types/react': specifier: ^18.3.11 version: 18.3.28 @@ -3748,7 +3947,7 @@ importers: devDependencies: '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) directory-tree: specifier: 3.5.2 version: 3.5.2 @@ -3779,7 +3978,7 @@ importers: devDependencies: '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) directory-tree: specifier: 3.5.2 version: 3.5.2 @@ -3959,13 +4158,13 @@ importers: devDependencies: '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) typescript: specifier: 7.0.2 version: 7.0.2 @@ -4020,7 +4219,7 @@ importers: version: link:../sdk '@rspress/shared': specifier: 2.0.14 - version: 2.0.14(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.0.14(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) cheerio: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 @@ -4033,10 +4232,10 @@ importers: devDependencies: '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) '@rspress/core': specifier: 2.0.14 - version: 2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@18.3.28)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) + version: 2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@18.3.28)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) '@types/html-to-text': specifier: ^9.0.4 version: 9.0.4 @@ -4121,7 +4320,7 @@ importers: version: 22.5.4(@babel/traverse@7.29.7)(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23))(@swc/helpers@0.5.23)(esbuild@0.25.5)(nx@22.5.4(@swc-node/register@1.10.10(@swc/core@1.7.26(@swc/helpers@0.5.13))(@swc/types@0.1.27)(typescript@6.0.3))(@swc/core@1.15.41(@swc/helpers@0.5.23)))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack-cli@5.1.4) '@rsbuild/core': specifier: 2.1.4 - version: 2.1.4(@module-federation/runtime-tools@0.21.6)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(core-js@3.49.0) '@storybook/core': specifier: ^8.4.6 version: 8.6.14(prettier@3.8.1)(storybook@8.6.17(prettier@3.8.1)) @@ -4145,7 +4344,7 @@ importers: devDependencies: '@rstest/core': specifier: ^0.10.6 - version: 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3) + version: 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3) '@types/node': specifier: ^20.19.5 version: 20.19.5 @@ -4332,13 +4531,13 @@ importers: version: 1.57.0 '@rsbuild/core': specifier: ^2.1.4 - version: 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + version: 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-react': specifier: ^2.1.0 - version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + version: 2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)) '@rslib/core': specifier: ^0.23.2 - version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3) + version: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3) '@rstest/core': specifier: ^0.6.5 version: 0.6.9(jsdom@20.0.3) @@ -8504,6 +8703,15 @@ packages: vue-tsc: optional: true + '@module-federation/dts-plugin@2.7.0': + resolution: {integrity: sha512-mVKeGUf/7iqRMAFfikhsr2zXtA70WuzJdS1bPqqoeLQNRGXBLDjedcDG26RpIlsvuZcmIOqgN5Z6qw7Bh/HZUg==} + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 + vue-tsc: '>=1.0.24' + peerDependenciesMeta: + vue-tsc: + optional: true + '@module-federation/enhanced@0.21.6': resolution: {integrity: sha512-8PFQxtmXc6ukBC4CqGIoc96M2Ly9WVwCPu4Ffvt+K/SB6rGbeFeZoYAwREV1zGNMJ5v5ly6+AHIEOBxNuSnzSg==} hasBin: true @@ -8558,6 +8766,9 @@ packages: '@module-federation/error-codes@2.7.0': resolution: {integrity: sha512-syToF3H77IbBhJ7auGMCIb5ZDmJ5tvaqSeEvncJrOCq7JBT96F4UDlQDyNh6kCVznvYqqHsPeEMrfI9b5/Omlg==} + '@module-federation/error-codes@2.8.0': + resolution: {integrity: sha512-Gaog9904EmxYOQV0hli3XQ7jXeFaADfh5bnBtTCtbZ37Qd/Sz9kQfd+gYQRyIj7RGmkv9DPiN/SsmrTMrTymKw==} + '@module-federation/inject-external-runtime-core-plugin@0.21.6': resolution: {integrity: sha512-DJQne7NQ988AVi3QB8byn12FkNb+C2lBeU1NRf8/WbL0gmHsr6kW8hiEJCm8LYaURwtsQqtsEV7i+8+51qjSmQ==} peerDependencies: @@ -8574,6 +8785,9 @@ packages: '@module-federation/managers@2.2.2': resolution: {integrity: sha512-YuUCUdjwXGsFEWC6YwNjX+XC8V4i47549ljXarHBhCVIYIluigivpG5ZDq/kyoZQoeR9UnUwzMiKzt79y0f7Dg==} + '@module-federation/managers@2.7.0': + resolution: {integrity: sha512-cWohiUvSrY6dIfhwsRABmEWfvJiAD5u/gxU7XRk7bx5nYPj7qn5gvYWJtvLNWzenluHZR6sib+03QMlyo+MYKQ==} + '@module-federation/manifest@0.21.6': resolution: {integrity: sha512-yg93+I1qjRs5B5hOSvjbjmIoI2z3th8/yst9sfwvx4UDOG1acsE3HHMyPN0GdoIGwplC/KAnU5NmUz4tREUTGQ==} @@ -8636,6 +8850,9 @@ packages: '@module-federation/runtime-core@2.7.0': resolution: {integrity: sha512-5ROZLVIeV9YnWO2RwCwSHcy6sh48yclErO/2GZ2Xe8lFubPrFirgU8pbwBjZw+All0ZzN44BGS4ECRMVFzVcpg==} + '@module-federation/runtime-core@2.8.0': + resolution: {integrity: sha512-Tf98+epGGiPSHqmQHuXa2uXZMMvjGf1IqJDR1/FpXfmobv5ECN0mGZCjUHGNSyxvoDyXKIkKwJu7IwEoh0ouQA==} + '@module-federation/runtime-tools@0.1.6': resolution: {integrity: sha512-7ILVnzMIa0Dlc0Blck5tVZG1tnk1MmLnuZpLOMpbdW+zl+N6wdMjjHMjEZFCUAJh2E5XJ3BREwfX8Ets0nIkLg==} @@ -8663,8 +8880,8 @@ packages: '@module-federation/runtime-tools@2.2.2': resolution: {integrity: sha512-UnlKvy/zrbLTLItrI1tORiS6wdp5pYOCrR2LtDEbjJ2r+avzANSf2vJ7lAIT4SX5Pi9WwY5RhE4Y/BOwhAj4DA==} - '@module-federation/runtime-tools@2.7.0': - resolution: {integrity: sha512-AY61QeZ0jV0GywgR9j3Yd37KiXoY6gaSYABhjDF3q7XL9PNtb2Ezm1F/985wqaKJYX+qJvYv+PMH6hTvyHdPYQ==} + '@module-federation/runtime-tools@2.8.0': + resolution: {integrity: sha512-3yOqjdSHXxX4HA3GhlXg3hghGAXW2RJUsnwXCcik2/lTxOHizKI8f3RM+GGCKPxDVqtw43IShe3tA12jNL5A/A==} '@module-federation/runtime@0.1.6': resolution: {integrity: sha512-nj6a+yJ+QxmcE89qmrTl4lphBIoAds0PFPVGnqLRWflwAP88jrCcrrTqRhARegkFDL+wE9AE04+h6jzlbIfMKg==} @@ -8696,6 +8913,9 @@ packages: '@module-federation/runtime@2.7.0': resolution: {integrity: sha512-UtLozKKNvhT0D1+F0MEWsAmddJ39ItKW15E22LVMAwXmYZRSnzIvJQ2Y6kQ4LwhWABsw/GRSpUDex5OfhpSQPw==} + '@module-federation/runtime@2.8.0': + resolution: {integrity: sha512-cGtUBQ1/TVy7KrXy6xPgy3FEmOGyIYkBA2T4iGH3ZH5PNPPTmqN9jF2AfneTSOj0RtBr7Pxq3CUt81E/UCvK1A==} + '@module-federation/sdk@0.1.6': resolution: {integrity: sha512-qifXpyYLM7abUeEOIfv0oTkguZgRZuwh89YOAYIZJlkP6QbRG7DJMQvtM8X2yHXm9PTk0IYNnOJH0vNQCo6auQ==} @@ -8731,12 +8951,24 @@ packages: '@module-federation/sdk@2.7.0': resolution: {integrity: sha512-piiLEjaIdjbNq8E11Di6vsfryhcdN/+sBCH6NjG7gSU2VHHoHEayZQWWL7VVdS6rVjexF9McLhPTSrl0adUU+A==} + '@module-federation/sdk@2.8.0': + resolution: {integrity: sha512-yBP+9+0Z8nlvKEXAZS3AsQVy7bFbZf8eMivGk4q4ZdwG3TsLMlsPjb1dQb2i7gcAG6ux9y2LWLkj/0LVk74cnQ==} + '@module-federation/third-party-dts-extractor@0.21.6': resolution: {integrity: sha512-Il6x4hLsvCgZNk1DFwuMBNeoxD1BsZ5AW2BI/nUgu0k5FiAvfcz1OFawRFEHtaM/kVrCsymMOW7pCao90DaX3A==} '@module-federation/third-party-dts-extractor@2.2.2': resolution: {integrity: sha512-BWKLXQ2Me+zw6y2yhk8/URuVcyYFP1aJZlTqb7KpYeSJEp2z5jk8sZX2R42GraAGAwSe9IwcW6Y4Za/eoxt/tA==} + '@module-federation/third-party-dts-extractor@2.7.0': + resolution: {integrity: sha512-hZJKkngQ4hwe0U+vrT3KOsU11qoHCQK0wB4x1bXoTgpTfV9j5NSuddOyRmwbvXpir9bDWh3xy7ghqsx3mFf3kA==} + + '@module-federation/vite@1.16.16': + resolution: {integrity: sha512-XtgLXydgUblSzIJaRljVrg5xyogABEUUnTsSXX11W/q55XR+mnpKInsGY3uBgX09GbjSW5DNHWal+1zKt2d7uw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + '@module-federation/webpack-bundler-runtime@0.1.6': resolution: {integrity: sha512-K5WhKZ4RVNaMEtfHsd/9CNCgGKB0ipbm/tgweNNeC11mEuBTNxJ09Y630vg3WPkKv9vfMCuXg2p2Dk+Q/KWTSA==} @@ -8764,8 +8996,8 @@ packages: '@module-federation/webpack-bundler-runtime@2.2.2': resolution: {integrity: sha512-g5UEn5APnNYvajwWQ0oc3Um+HO1z/jBcBkLSKAoSOCI6XxQk5eAV1PNDuDehAgJEtJw5yFD25kZPW3X7m39y7g==} - '@module-federation/webpack-bundler-runtime@2.7.0': - resolution: {integrity: sha512-3qLRIqcZVBNgJrZpiEzcTP8a6+mCdUV1QGk/XljawsQHyNieMVdLQtdLvkoF5Z5kRXNMovq+wv3vchKOMWyA8w==} + '@module-federation/webpack-bundler-runtime@2.8.0': + resolution: {integrity: sha512-82fDy9v+7qV5fiN8TKVhOdrxhmAZnUIX/IKivYX5ulCt8aoOzVFTiwm/P1GQUDD8z6dqR48xgJdZdf0548Mc9w==} '@monaco-editor/loader@1.7.0': resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==} @@ -11899,6 +12131,14 @@ packages: '@rsbuild/core': optional: true + '@rsbuild/plugin-vue@1.2.9': + resolution: {integrity: sha512-ufD4eufkZZlNK3iY5NWg57AMK9qrTFmHycDkSTfRTua4Qczf7q9s7rCLYVfVv2w36cOXJIewM+376jD0zaQShQ==} + peerDependencies: + '@rsbuild/core': ^1.0.0 || ^2.0.0-0 + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@rsbuild/plugin-vue@2.0.1': resolution: {integrity: sha512-JbQ/e4J7lICXC6JpovJS9PHlIT0Vl1XngTni3HuVkXF82Q18k8nd0RmRDVRDFcb/mvqij5ITwZsez9h3DoYcQQ==} peerDependencies: @@ -14118,9 +14358,6 @@ packages: '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node-schedule@2.1.7': - resolution: {integrity: sha512-G7Z3R9H7r3TowoH6D2pkzUHPhcJrDF4Jz1JOQ80AX0K2DWTHoN9VC94XzFAPNMdbW9TBzMZ3LjpFi7RYdbxtXA==} - '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} @@ -14160,9 +14397,6 @@ packages: '@types/pug@2.0.10': resolution: {integrity: sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==} - '@types/qs@6.15.0': - resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} - '@types/qs@6.15.1': resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} @@ -22141,10 +22375,6 @@ packages: encoding: optional: true - node-fetch@3.3.0: - resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -24213,11 +24443,6 @@ packages: react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 - react-error-boundary@4.1.2: - resolution: {integrity: sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==} - peerDependencies: - react: '>=16.13.1' - react-error-boundary@5.0.0: resolution: {integrity: sha512-tnjAxG+IkpLephNcePNA7v6F/QpWLH8He65+DmedchDwg162JZqx4NmbXj0mlAYVVEd81OW7aFhmbsScYfiAFQ==} peerDependencies: @@ -26965,6 +27190,11 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + typescript@5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true + typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -33041,22 +33271,22 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 es-module-lexer: 1.7.0 @@ -33094,22 +33324,22 @@ snapshots: - utf-8-validate - webpack - '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 es-module-lexer: 1.7.0 @@ -33147,22 +33377,22 @@ snapshots: - utf-8-validate - webpack - '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/app-tools@3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(core-js@3.49.0)(encoding@0.1.13)(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@babel/parser': 7.29.7 '@babel/traverse': 7.29.7 '@babel/types': 7.29.7 - '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@modern-js/builder': 3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) '@modern-js/i18n-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/prod-server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 es-module-lexer: 1.7.0 @@ -33269,7 +33499,7 @@ snapshots: - '@rsbuild/core' - supports-color - '@modern-js/babel-preset@2.68.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@modern-js/babel-preset@2.68.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.7) @@ -33281,7 +33511,7 @@ snapshots: '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) '@babel/runtime': 7.28.2 '@babel/types': 7.29.7 - '@rsbuild/plugin-babel': 1.0.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-babel': 1.0.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@swc/helpers': 0.5.17 '@types/babel__core': 7.20.5 babel-plugin-dynamic-import-node: 2.3.3 @@ -33332,21 +33562,21 @@ snapshots: - '@rsbuild/core' - supports-color - '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) - '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) - '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) - '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@7.0.2) - '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) - '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)) + '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(typescript@7.0.2) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) + '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 autoprefixer: 10.4.27(postcss@8.5.15) @@ -33363,8 +33593,8 @@ snapshots: postcss-media-minmax: 5.0.0(postcss@8.5.15) postcss-nesting: 12.1.5(postcss@8.5.15) postcss-page-break: 3.0.4(postcss@8.5.15) - rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - rspack-manifest-plugin: 5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + rspack-manifest-plugin: 5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)) ts-deepmerge: 7.0.3 transitivePeerDependencies: - '@module-federation/runtime-tools' @@ -33384,21 +33614,21 @@ snapshots: - typescript - webpack - '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@modern-js/builder@3.5.0(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(esbuild@0.28.1)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) - '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) - '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) - '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(typescript@7.0.2) - '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) - '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rsbuild/plugin-assets-retry': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-check-syntax': 2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-css-minimizer': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@rsbuild/plugin-less': 1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@rsbuild/plugin-rem': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-sass': 1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-source-build': 1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) + '@rsbuild/plugin-svgr': 2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@7.0.2) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) + '@rsbuild/plugin-typed-css-modules': 1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@swc/core': 1.15.41(@swc/helpers@0.5.17) '@swc/helpers': 0.5.17 autoprefixer: 10.4.27(postcss@8.5.15) @@ -33415,8 +33645,8 @@ snapshots: postcss-media-minmax: 5.0.0(postcss@8.5.15) postcss-nesting: 12.1.5(postcss@8.5.15) postcss-page-break: 3.0.4(postcss@8.5.15) - rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - rspack-manifest-plugin: 5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + rsbuild-plugin-rsc: 0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + rspack-manifest-plugin: 5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) ts-deepmerge: 7.0.3 transitivePeerDependencies: - '@module-federation/runtime-tools' @@ -33627,10 +33857,10 @@ snapshots: '@modern-js/utils': 2.70.8 '@swc/helpers': 0.5.17 - '@modern-js/plugin-server@2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/plugin-server@2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 2.68.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-utils': 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@modern-js/server-utils': 2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@modern-js/utils': 2.68.0 '@swc/helpers': 0.5.17 transitivePeerDependencies: @@ -33693,12 +33923,12 @@ snapshots: '@modern-js/utils': 2.70.8 '@swc/helpers': 0.5.17 - '@modern-js/plugin@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/plugin@3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.0.1 '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.0.0-beta.2(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@swc/helpers': 0.5.17 jiti: 2.6.1 transitivePeerDependencies: @@ -33707,12 +33937,12 @@ snapshots: - react - react-dom - '@modern-js/plugin@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/plugin@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@swc/helpers': 0.5.17 jiti: 2.6.1 transitivePeerDependencies: @@ -33741,10 +33971,10 @@ snapshots: - react - react-dom - '@modern-js/prod-server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/prod-server@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 transitivePeerDependencies: @@ -33771,23 +34001,23 @@ snapshots: react-dom: 19.2.4(react@19.2.4) react-server-dom-webpack: 19.2.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)) - '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/render@3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/rsbuild-plugin-esbuild@2.70.5(@swc/core@1.15.41(@swc/helpers@0.5.17))(webpack-cli@5.1.4)': dependencies: @@ -33936,13 +34166,13 @@ snapshots: - react-server-dom-webpack - supports-color - '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@loadable/component': 5.16.7(react@18.3.1) '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -33965,13 +34195,13 @@ snapshots: - core-js - react-server-dom-rspack - '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + '@modern-js/runtime@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': dependencies: '@loadable/component': 5.16.7(react@18.3.1) '@loadable/server': 5.16.7(@loadable/component@5.16.7(react@18.3.1))(react@18.3.1) - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/plugin-data-loader': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@modern-js/render': 3.5.0(react-dom@18.3.1(react@18.3.1))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34030,9 +34260,9 @@ snapshots: - react - react-dom - '@modern-js/server-core@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/server-core@3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 @@ -34049,9 +34279,9 @@ snapshots: - react - react-dom - '@modern-js/server-core@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/server-core@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/plugin': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@swc/helpers': 0.5.17 @@ -34077,10 +34307,10 @@ snapshots: - react - react-dom - '@modern-js/server-runtime@3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/server-runtime@3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.0.1(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.0.1 '@swc/helpers': 0.5.17 transitivePeerDependencies: @@ -34089,10 +34319,10 @@ snapshots: - react - react-dom - '@modern-js/server-runtime@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@modern-js/server-runtime@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@swc/helpers': 0.5.17 transitivePeerDependencies: @@ -34101,7 +34331,7 @@ snapshots: - react - react-dom - '@modern-js/server-utils@2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@modern-js/server-utils@2.68.0(@babel/traverse@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.7) @@ -34110,7 +34340,7 @@ snapshots: '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) '@modern-js/babel-compiler': 2.68.0 '@modern-js/babel-plugin-module-resolver': 2.68.0 - '@modern-js/babel-preset': 2.68.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@modern-js/babel-preset': 2.68.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@modern-js/utils': 2.68.0 '@swc/helpers': 0.5.17 babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.29.7)(@babel/traverse@7.29.7) @@ -34221,10 +34451,10 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.17))(@types/node@26.1.0)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34248,10 +34478,10 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@3.14.2)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34275,10 +34505,10 @@ snapshots: - supports-color - utf-8-validate - '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)': + '@modern-js/server@3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(ts-node@10.9.2(@swc/core@1.15.41(@swc/helpers@0.5.23))(@types/node@20.19.5)(typescript@7.0.2))(tsconfig-paths@4.2.0)': dependencies: '@modern-js/runtime-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@modern-js/server-core': 3.5.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/server-utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@modern-js/types': 3.5.0 '@modern-js/utils': 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -34862,6 +35092,24 @@ snapshots: - supports-color - utf-8-validate + '@module-federation/dts-plugin@2.7.0(typescript@5.0.4)(vue-tsc@2.2.12(typescript@5.0.4))': + dependencies: + '@module-federation/error-codes': 2.7.0 + '@module-federation/managers': 2.7.0 + '@module-federation/sdk': 2.7.0 + '@module-federation/third-party-dts-extractor': 2.7.0 + adm-zip: 0.5.10 + isomorphic-ws: 5.0.0(ws@8.21.0) + node-schedule: 2.1.1 + typescript: 5.0.4 + undici: 7.28.0 + ws: 8.21.0 + optionalDependencies: + vue-tsc: 2.2.12(typescript@5.0.4) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@module-federation/enhanced@0.21.6(@rspack/core@1.6.8(@swc/helpers@0.5.23))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4))': dependencies: '@module-federation/bridge-react-webpack-plugin': 0.21.6 @@ -34937,7 +35185,9 @@ snapshots: '@module-federation/error-codes@2.2.2': {} - '@module-federation/error-codes@2.7.0': + '@module-federation/error-codes@2.7.0': {} + + '@module-federation/error-codes@2.8.0': optional: true '@module-federation/inject-external-runtime-core-plugin@0.21.6(@module-federation/runtime-tools@0.21.6)': @@ -34962,6 +35212,11 @@ snapshots: transitivePeerDependencies: - node-fetch + '@module-federation/managers@2.7.0': + dependencies: + '@module-federation/sdk': 2.7.0 + empathic: 2.0.0 + '@module-federation/manifest@0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2))': dependencies: '@module-federation/dts-plugin': 0.21.6(typescript@7.0.2)(vue-tsc@2.2.12(typescript@7.0.2)) @@ -35097,6 +35352,11 @@ snapshots: dependencies: '@module-federation/error-codes': 2.7.0 '@module-federation/sdk': 2.7.0 + + '@module-federation/runtime-core@2.8.0': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/sdk': 2.8.0 optional: true '@module-federation/runtime-tools@0.1.6': @@ -35146,10 +35406,10 @@ snapshots: transitivePeerDependencies: - node-fetch - '@module-federation/runtime-tools@2.7.0': + '@module-federation/runtime-tools@2.8.0': dependencies: - '@module-federation/runtime': 2.7.0 - '@module-federation/webpack-bundler-runtime': 2.7.0 + '@module-federation/runtime': 2.8.0 + '@module-federation/webpack-bundler-runtime': 2.8.0 optional: true '@module-federation/runtime@0.1.6': @@ -35209,6 +35469,12 @@ snapshots: '@module-federation/error-codes': 2.7.0 '@module-federation/runtime-core': 2.7.0 '@module-federation/sdk': 2.7.0 + + '@module-federation/runtime@2.8.0': + dependencies: + '@module-federation/error-codes': 2.8.0 + '@module-federation/runtime-core': 2.8.0 + '@module-federation/sdk': 2.8.0 optional: true '@module-federation/sdk@0.1.6': {} @@ -35231,7 +35497,9 @@ snapshots: optionalDependencies: node-fetch: 2.7.0(encoding@0.1.13) - '@module-federation/sdk@2.7.0': + '@module-federation/sdk@2.7.0': {} + + '@module-federation/sdk@2.8.0': optional: true '@module-federation/third-party-dts-extractor@0.21.6': @@ -35246,6 +35514,23 @@ snapshots: fs-extra: 9.1.0 resolve: 1.22.8 + '@module-federation/third-party-dts-extractor@2.7.0': + dependencies: + empathic: 2.0.0 + exsolve: 1.0.8 + + '@module-federation/vite@1.16.16(typescript@5.0.4)(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue-tsc@2.2.12(typescript@5.0.4))': + dependencies: + '@module-federation/dts-plugin': 2.7.0(typescript@5.0.4)(vue-tsc@2.2.12(typescript@5.0.4)) + '@module-federation/runtime': 2.7.0 + '@module-federation/sdk': 2.7.0 + vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - vue-tsc + '@module-federation/webpack-bundler-runtime@0.1.6': dependencies: '@module-federation/runtime': 0.1.6 @@ -35293,11 +35578,11 @@ snapshots: transitivePeerDependencies: - node-fetch - '@module-federation/webpack-bundler-runtime@2.7.0': + '@module-federation/webpack-bundler-runtime@2.8.0': dependencies: - '@module-federation/error-codes': 2.7.0 - '@module-federation/runtime': 2.7.0 - '@module-federation/sdk': 2.7.0 + '@module-federation/error-codes': 2.8.0 + '@module-federation/runtime': 2.8.0 + '@module-federation/sdk': 2.8.0 optional: true '@monaco-editor/loader@1.7.0': @@ -38908,9 +39193,9 @@ snapshots: core-js: 3.47.0 jiti: 2.6.1 - '@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)': + '@rsbuild/core@2.0.0-beta.2(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)': dependencies: - '@rspack/core': 2.0.0-beta.0(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.0.0-beta.0(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 jiti: 2.6.1 optionalDependencies: @@ -38918,54 +39203,54 @@ snapshots: transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.0.15(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)': + '@rsbuild/core@2.0.15(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)': dependencies: - '@rspack/core': 2.0.8(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.0.8(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.36.1 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.0.15(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)': + '@rsbuild/core@2.0.15(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)': dependencies: - '@rspack/core': 2.0.8(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.0.8(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.49.0 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)': + '@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)': dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.49.0 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.1.4(@module-federation/runtime-tools@0.21.6)(core-js@3.49.0)': + '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(core-js@3.49.0)': dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@0.21.6)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.49.0 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)': + '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)': dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.36.1 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)': + '@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)': dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 optionalDependencies: core-js: 3.49.0 @@ -38976,9 +39261,9 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-assets-retry@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-assets-retry@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-babel@1.0.1-rc.4(@rsbuild/core@1.0.1-rc.4)': dependencies: @@ -38994,13 +39279,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@rsbuild/plugin-babel@1.0.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-babel@1.0.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.7) '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.7) '@babel/preset-typescript': 7.28.5(@babel/core@7.29.7) - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@types/babel__core': 7.20.5 deepmerge: 4.3.1 reduce-configs: 1.1.2 @@ -39022,7 +39307,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@rsbuild/plugin-babel@1.2.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-babel@1.2.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.7) @@ -39031,21 +39316,21 @@ snapshots: '@types/babel__core': 7.20.5 reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - supports-color - '@rsbuild/plugin-babel@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@rsbuild/plugin-babel@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-proposal-decorators': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-class-properties': 7.29.7(@babel/core@7.29.7) '@babel/preset-typescript': 7.29.7(@babel/core@7.29.7) '@types/babel__core': 7.20.5 - babel-loader: 10.1.1(@babel/core@7.29.7)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)) + babel-loader: 10.1.1(@babel/core@7.29.7)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - supports-color @@ -39061,7 +39346,7 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-check-syntax@2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-check-syntax@2.0.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: acorn: 8.17.0 browserslist-to-es-version: 1.4.1 @@ -39069,7 +39354,7 @@ snapshots: picocolors: 1.1.1 source-map: 0.7.6 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-css-minimizer@1.1.1(@rsbuild/core@1.7.3)(esbuild@0.18.20)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4))': dependencies: @@ -39116,12 +39401,12 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: css-minimizer-webpack-plugin: 8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@parcel/css' - '@swc/css' @@ -39131,12 +39416,12 @@ snapshots: - lightningcss - webpack - '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@rsbuild/plugin-css-minimizer@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: css-minimizer-webpack-plugin: 8.0.0(esbuild@0.28.1)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@parcel/css' - '@swc/css' @@ -39152,26 +39437,26 @@ snapshots: deepmerge: 4.3.1 reduce-configs: 1.1.2 - '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': + '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4))': dependencies: deepmerge: 4.3.1 less: 4.6.4 - less-loader: 12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) + less-loader: 12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - webpack - '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': + '@rsbuild/plugin-less@1.6.4(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)))': dependencies: deepmerge: 4.3.1 less: 4.6.4 - less-loader: 12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) + less-loader: 12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))) reduce-configs: 1.1.2 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - webpack @@ -39257,83 +39542,83 @@ snapshots: transitivePeerDependencies: - webpack-hot-middleware - '@rsbuild/plugin-react@1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1)': + '@rsbuild/plugin-react@1.4.5(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(webpack-hot-middleware@2.26.1)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rspack/plugin-react-refresh': 1.6.1(react-refresh@0.18.0)(webpack-hot-middleware@2.26.1) react-refresh: 0.18.0 transitivePeerDependencies: - webpack-hot-middleware - '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))': + '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))': dependencies: - '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))': dependencies: - '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + '@rsbuild/plugin-react@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))': dependencies: - '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))': + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))': dependencies: - '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))': dependencies: - '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@0.7.5(@swc/helpers@0.5.23))': + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@0.7.5(@swc/helpers@0.5.23))': dependencies: '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@0.7.5(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))': + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))': dependencies: - '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))': + '@rsbuild/plugin-react@2.1.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))': dependencies: - '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' @@ -39344,12 +39629,12 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-rem@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-rem@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: deepmerge: 4.3.1 terser: 5.48.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-sass@1.5.0(@rsbuild/core@1.7.3)': dependencies: @@ -39360,7 +39645,7 @@ snapshots: reduce-configs: 1.1.2 sass-embedded: 1.100.0 - '@rsbuild/plugin-sass@1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-sass@1.5.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: deepmerge: 4.3.1 loader-utils: 2.0.4 @@ -39368,9 +39653,9 @@ snapshots: reduce-configs: 1.1.2 sass-embedded: 1.100.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) - '@rsbuild/plugin-sass@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-sass@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: deepmerge: 4.3.1 loader-utils: 2.0.4 @@ -39378,7 +39663,7 @@ snapshots: reduce-configs: 2.0.1 sass-embedded: 1.100.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-source-build@1.0.4(@rsbuild/core@1.7.3)': dependencies: @@ -39388,13 +39673,13 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-source-build@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-source-build@1.0.6(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: fast-glob: 3.3.3 json5: 2.2.3 yaml: 2.9.0 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@rsbuild/plugin-styled-components@1.6.0(@rsbuild/core@1.7.3)': dependencies: @@ -39417,31 +39702,31 @@ snapshots: - typescript - webpack-hot-middleware - '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(typescript@7.0.2)': + '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(typescript@7.0.2)': dependencies: - '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)) + '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)) '@svgr/core': 8.1.0(typescript@7.0.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@7.0.2))(typescript@7.0.2) deepmerge: 4.3.1 loader-utils: 3.3.1 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - supports-color - typescript - '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(typescript@7.0.2)': + '@rsbuild/plugin-svgr@2.0.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(typescript@7.0.2)': dependencies: - '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) + '@rsbuild/plugin-react': 2.1.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) '@svgr/core': 8.1.0(typescript@7.0.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@6.0.3))(typescript@7.0.2) deepmerge: 4.3.1 loader-utils: 3.3.1 optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - supports-color @@ -39479,40 +39764,40 @@ snapshots: - tslib - typescript - '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib - typescript - '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib - typescript - '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': + '@rsbuild/plugin-type-check@1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2)': dependencies: deepmerge: 4.3.1 json5: 2.2.3 reduce-configs: 1.1.2 - ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) + ts-checker-rspack-plugin: 1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - tslib @@ -39522,26 +39807,36 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - '@rsbuild/plugin-typed-css-modules@1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-typed-css-modules@1.2.3(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': optionalDependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) - '@rsbuild/plugin-vue-jsx@2.0.1(@babel/core@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))': + '@rsbuild/plugin-vue-jsx@2.0.1(@babel/core@7.29.7)(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))': dependencies: - '@rsbuild/plugin-babel': 1.2.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + '@rsbuild/plugin-babel': 1.2.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.7) babel-plugin-vue-jsx-hmr: 1.0.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@babel/core' - supports-color - '@rsbuild/plugin-vue@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2))': + '@rsbuild/plugin-vue@1.2.9(@rsbuild/core@1.7.3)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.0.4))': dependencies: - rspack-vue-loader: 17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) + rspack-vue-loader: 17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.0.4)) optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 1.7.3 + transitivePeerDependencies: + - '@rspack/core' + - '@vue/compiler-sfc' + - vue + + '@rsbuild/plugin-vue@2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2))': + dependencies: + rspack-vue-loader: 17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)) + optionalDependencies: + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) transitivePeerDependencies: - '@rspack/core' - '@vue/compiler-sfc' @@ -39625,10 +39920,10 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(typescript@6.0.3)': + '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(typescript@6.0.3)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1) - rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1))(typescript@6.0.3) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1) + rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1))(typescript@6.0.3) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) typescript: 6.0.3 @@ -39637,10 +39932,10 @@ snapshots: - '@typescript/native-preview' - core-js - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3)': + '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@6.0.3) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) typescript: 6.0.3 @@ -39649,10 +39944,10 @@ snapshots: - '@typescript/native-preview' - core-js - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@6.0.3)': + '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@6.0.3)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@6.0.3) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@22.19.15) typescript: 6.0.3 @@ -39661,10 +39956,10 @@ snapshots: - '@typescript/native-preview' - core-js - '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2)': + '@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@7.0.2) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + rsbuild-plugin-dts: 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@7.0.2) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) typescript: 7.0.2 @@ -40384,48 +40679,48 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.23 - '@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)': + '@rspack/core@2.0.0-beta.0(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)': dependencies: '@rspack/binding': 2.0.0-beta.0 '@rspack/lite-tapable': 1.1.0 optionalDependencies: - '@module-federation/runtime-tools': 2.7.0 + '@module-federation/runtime-tools': 2.8.0 '@swc/helpers': 0.5.23 - '@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)': + '@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)': dependencies: '@rspack/binding': 2.0.6 optionalDependencies: - '@module-federation/runtime-tools': 2.7.0 + '@module-federation/runtime-tools': 2.8.0 '@swc/helpers': 0.5.17 - '@rspack/core@2.0.8(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)': + '@rspack/core@2.0.8(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)': dependencies: '@rspack/binding': 2.0.8 optionalDependencies: - '@module-federation/runtime-tools': 2.7.0 + '@module-federation/runtime-tools': 2.8.0 '@swc/helpers': 0.5.23 - '@rspack/core@2.1.2(@module-federation/runtime-tools@0.21.6)(@swc/helpers@0.5.23)': + '@rspack/core@2.1.2(@module-federation/runtime-tools@2.2.2(node-fetch@2.7.0(encoding@0.1.13)))(@swc/helpers@0.5.23)': dependencies: '@rspack/binding': 2.1.2 optionalDependencies: - '@module-federation/runtime-tools': 0.21.6 + '@module-federation/runtime-tools': 2.2.2(node-fetch@2.7.0(encoding@0.1.13)) '@swc/helpers': 0.5.23 - '@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)': + '@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)': dependencies: '@rspack/binding': 2.1.2 optionalDependencies: - '@module-federation/runtime-tools': 2.7.0 + '@module-federation/runtime-tools': 2.8.0 '@swc/helpers': 0.5.17 optional: true - '@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)': + '@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)': dependencies: '@rspack/binding': 2.1.2 optionalDependencies: - '@module-federation/runtime-tools': 2.7.0 + '@module-federation/runtime-tools': 2.8.0 '@swc/helpers': 0.5.23 '@rspack/dev-server@1.1.1(@rspack/core@1.3.9(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack-cli@5.1.4)(webpack@5.104.1)': @@ -40466,17 +40761,17 @@ snapshots: optionalDependencies: webpack-hot-middleware: 2.26.1 - '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) - '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) '@rspack/plugin-react-refresh@2.0.2(@rspack/core@0.7.5(@swc/helpers@0.5.23))(react-refresh@0.18.0)': dependencies: @@ -40484,31 +40779,31 @@ snapshots: optionalDependencies: '@rspack/core': 0.7.5(@swc/helpers@0.5.23) - '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) - '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) - '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) - '@rspress/core@2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@18.3.28)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2)': + '@rspress/core@2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@18.3.28)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2)': dependencies: '@mdx-js/mdx': 3.1.1 '@mdx-js/react': 3.1.1(@types/react@18.3.28)(react@19.2.7) - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) - '@rspress/shared': 2.0.14(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@rspress/shared': 2.0.14(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@shikijs/rehype': 4.2.0 '@types/unist': 3.0.3 '@unhead/react': 2.1.15(react@19.2.7) @@ -40552,13 +40847,13 @@ snapshots: - micromark-util-types - supports-color - '@rspress/core@2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2)': + '@rspress/core@2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2)': dependencies: '@mdx-js/mdx': 3.1.1 '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.7) - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)) - '@rspress/shared': 2.0.14(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rsbuild/plugin-react': 2.0.1(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)) + '@rspress/shared': 2.0.14(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@shikijs/rehype': 4.2.0 '@types/unist': 3.0.3 '@unhead/react': 2.1.15(react@19.2.7) @@ -40602,18 +40897,18 @@ snapshots: - micromark-util-types - supports-color - '@rspress/shared@2.0.14(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)': + '@rspress/shared@2.0.14(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)': dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@shikijs/rehype': 4.2.0 unified: 11.0.5 transitivePeerDependencies: - '@module-federation/runtime-tools' - core-js - '@rstest/core@0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3)': + '@rstest/core@0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(jsdom@20.0.3)': dependencies: - '@rsbuild/core': 2.0.15(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1) + '@rsbuild/core': 2.0.15(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1) '@types/chai': 5.2.3 optionalDependencies: jsdom: 20.0.3 @@ -40621,9 +40916,9 @@ snapshots: - '@module-federation/runtime-tools' - core-js - '@rstest/core@0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(jsdom@20.0.3)': + '@rstest/core@0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(jsdom@20.0.3)': dependencies: - '@rsbuild/core': 2.0.15(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.0.15(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@types/chai': 5.2.3 optionalDependencies: jsdom: 20.0.3 @@ -41353,7 +41648,7 @@ snapshots: '@storybook/csf': 0.1.13 '@storybook/global': 5.0.0 '@storybook/types': 7.6.24 - '@types/qs': 6.15.0 + '@types/qs': 6.15.1 dequal: 2.0.3 lodash: 4.18.1 memoizerific: 1.11.3 @@ -42361,7 +42656,7 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: '@types/node': 20.19.5 - '@types/qs': 6.15.0 + '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -42369,7 +42664,7 @@ snapshots: dependencies: '@types/body-parser': 1.19.6 '@types/express-serve-static-core': 4.19.8 - '@types/qs': 6.15.0 + '@types/qs': 6.15.1 '@types/serve-static': 2.2.0 '@types/express@4.17.25': @@ -42515,10 +42810,6 @@ snapshots: dependencies: '@types/node': 20.19.5 - '@types/node-schedule@2.1.7': - dependencies: - '@types/node': 20.19.5 - '@types/node@12.20.55': {} '@types/node@14.18.33': {} @@ -42554,8 +42845,6 @@ snapshots: '@types/pug@2.0.10': {} - '@types/qs@6.15.0': {} - '@types/qs@6.15.1': {} '@types/range-parser@1.2.7': {} @@ -42583,7 +42872,7 @@ snapshots: '@types/react-router-dom@5.3.3': dependencies: '@types/history': 4.7.11 - '@types/react': 18.3.28 + '@types/react': 19.2.14 '@types/react-router': 5.1.20 '@types/react-router@5.1.20': @@ -43525,6 +43814,11 @@ snapshots: vite: 5.4.21(@types/node@20.19.5)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) vue: 3.5.30(typescript@7.0.2) + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@5.0.4))': + dependencies: + vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) + vue: 3.5.30(typescript@5.0.4) + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0))(vue@3.5.30(typescript@7.0.2))': dependencies: vite: 5.4.21(@types/node@26.1.0)(less@4.6.4)(sass-embedded@1.100.0)(sass@1.100.0)(terser@5.48.0) @@ -43823,6 +44117,20 @@ snapshots: optionalDependencies: typescript: 7.0.2 + '@vue/language-core@2.2.12(typescript@5.0.4)': + dependencies: + '@volar/language-core': 2.4.15 + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.30 + alien-signals: 1.0.13 + minimatch: 9.0.9 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.0.4 + optional: true + '@vue/language-core@2.2.12(typescript@6.0.3)': dependencies: '@volar/language-core': 2.4.15 @@ -43865,6 +44173,12 @@ snapshots: '@vue/shared': 3.5.30 csstype: 3.2.3 + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@5.0.4))': + dependencies: + '@vue/compiler-ssr': 3.5.30 + '@vue/shared': 3.5.30 + vue: 3.5.30(typescript@5.0.4) + '@vue/server-renderer@3.5.30(vue@3.5.30(typescript@6.0.3))': dependencies: '@vue/compiler-ssr': 3.5.30 @@ -45048,12 +45362,12 @@ snapshots: transitivePeerDependencies: - supports-color - babel-loader@10.1.1(@babel/core@7.29.7)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)): + babel-loader@10.1.1(@babel/core@7.29.7)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: '@babel/core': 7.29.7 find-up: 5.0.0 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) webpack: 5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.28.1)(webpack-cli@5.1.4) babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.19))(esbuild@0.18.20)(webpack-cli@5.1.4)): @@ -51954,18 +52268,18 @@ snapshots: less: 4.6.4 webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.25.5)(webpack-cli@5.1.4) - less-loader@12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)): + less-loader@12.3.3(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: less: 4.6.4 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.17))(esbuild@0.28.1)(webpack-cli@5.1.4) - less-loader@12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): + less-loader@12.3.3(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(less@4.6.4)(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1))): dependencies: less: 4.6.4 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) webpack: 5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4(webpack-dev-server@5.2.3)(webpack@5.104.1)) less@4.6.4: @@ -53830,12 +54144,6 @@ snapshots: optionalDependencies: encoding: 0.1.13 - node-fetch@3.3.0: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - node-fetch@3.3.2: dependencies: data-uri-to-buffer: 4.0.1 @@ -57176,16 +57484,6 @@ snapshots: react-dom: 19.2.4(react@19.2.4) react-is: 18.1.0 - react-error-boundary@4.1.2(react@18.3.1): - dependencies: - '@babel/runtime': 7.28.2 - react: 18.3.1 - - react-error-boundary@4.1.2(react@19.2.7): - dependencies: - '@babel/runtime': 7.28.2 - react: 19.2.7 - react-error-boundary@5.0.0(react@18.3.1): dependencies: '@babel/runtime': 7.28.2 @@ -57633,15 +57931,15 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) - react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -58451,34 +58749,34 @@ snapshots: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) typescript: 7.0.2 - rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1))(typescript@6.0.3): + rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1))(typescript@6.0.3): dependencies: '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) typescript: 6.0.3 - rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3): + rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@20.19.5))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@6.0.3): dependencies: '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@20.19.5) typescript: 6.0.3 - rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@6.0.3): + rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@22.19.15))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@6.0.3): dependencies: '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@22.19.15) typescript: 6.0.3 - rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(typescript@7.0.2): + rsbuild-plugin-dts@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(typescript@7.0.2): dependencies: '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) optionalDependencies: '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) typescript: 7.0.2 @@ -58495,12 +58793,12 @@ snapshots: '@microsoft/api-extractor': 7.57.7(@types/node@26.1.0) typescript: 5.9.3 - rsbuild-plugin-html-minifier-terser@1.1.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)): + rsbuild-plugin-html-minifier-terser@1.1.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)): dependencies: '@types/html-minifier-terser': 7.0.2 html-minifier-terser: 7.2.0 optionalDependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) rsbuild-plugin-publint@0.2.1(@rsbuild/core@1.7.3): dependencies: @@ -58509,15 +58807,15 @@ snapshots: optionalDependencies: '@rsbuild/core': 1.7.3 - rsbuild-plugin-rsc@0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + rsbuild-plugin-rsc@0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + react-server-dom-rspack: 0.0.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - rsbuild-plugin-rsc@0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + rsbuild-plugin-rsc@0.1.1(@rsbuild/core@2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(react-server-dom-rspack@0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: - '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rsbuild/core': 2.1.0(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + react-server-dom-rspack: 0.0.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) rslog@1.2.3: {} @@ -58535,29 +58833,37 @@ snapshots: optionalDependencies: '@rspack/core': 1.7.9(@swc/helpers@0.5.19) - rspack-manifest-plugin@5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17)): + rspack-manifest-plugin@5.2.2(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17)): dependencies: '@rspack/lite-tapable': 1.1.2 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) - rspack-manifest-plugin@5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23)): + rspack-manifest-plugin@5.2.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23)): dependencies: '@rspack/lite-tapable': 1.1.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) - rspack-vue-loader@17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)): + rspack-vue-loader@17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@5.0.4)): dependencies: - '@rspack/lite-tapable': 1.1.0 + '@rspack/lite-tapable': 1.1.2 + chalk: 4.1.2 + optionalDependencies: + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) + vue: 3.5.30(typescript@5.0.4) + + rspack-vue-loader@17.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(vue@3.5.30(typescript@7.0.2)): + dependencies: + '@rspack/lite-tapable': 1.1.2 chalk: 4.1.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) vue: 3.5.30(typescript@7.0.2) - rstest-fetch-mock@0.1.0(@rstest/core@0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3)): + rstest-fetch-mock@0.1.0(@rstest/core@0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(jsdom@20.0.3)): dependencies: - '@rstest/core': 0.10.6(@module-federation/runtime-tools@2.7.0)(core-js@3.36.1)(jsdom@20.0.3) + '@rstest/core': 0.10.6(@module-federation/runtime-tools@2.8.0)(core-js@3.36.1)(jsdom@20.0.3) run-applescript@7.1.0: {} @@ -59423,18 +59729,18 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - storybook-addon-rslib@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2): + storybook-addon-rslib@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rslib/core@0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2))(storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2))(typescript@7.0.2): dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rslib/core': 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)(typescript@7.0.2) - storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rslib/core': 0.23.2(@microsoft/api-extractor@7.57.7(@types/node@26.1.0))(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)(typescript@7.0.2) + storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) optionalDependencies: typescript: 7.0.2 - storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2): + storybook-builder-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2): dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + '@rsbuild/plugin-type-check': 1.5.0(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2) '@storybook/addon-docs': 8.6.18(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1)) '@storybook/core-webpack': 8.6.18(storybook@8.6.17(prettier@3.8.1)) browser-assert: 1.2.1 @@ -59446,7 +59752,7 @@ snapshots: magic-string: 0.30.21 path-browserify: 1.0.1 process: 0.11.10 - rsbuild-plugin-html-minifier-terser: 1.1.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0)) + rsbuild-plugin-html-minifier-terser: 1.1.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0)) sirv: 2.0.4 storybook: 8.6.17(prettier@3.8.1) ts-dedent: 2.2.0 @@ -59461,10 +59767,10 @@ snapshots: - '@typescript/native-preview' - tslib - storybook-react-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)): + storybook-react-rsbuild@1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@4.59.0)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.59.0) - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) '@storybook/react': 8.6.18(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.6.17(prettier@3.8.1))(typescript@7.0.2) '@storybook/react-docgen-typescript-plugin': 1.0.1(typescript@7.0.2)(webpack@5.104.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(esbuild@0.25.5)(webpack-cli@5.1.4)) '@types/node': 18.19.130 @@ -59476,7 +59782,7 @@ snapshots: react-dom: 18.3.1(react@18.3.1) resolve: 1.22.11 storybook: 8.6.17(prettier@3.8.1) - storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) + storybook-builder-rsbuild: 1.0.3(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/react@18.3.28)(storybook@8.6.17(prettier@3.8.1))(tslib@2.8.1)(typescript@7.0.2) tsconfig-paths: 4.2.0 optionalDependencies: typescript: 7.0.2 @@ -60615,7 +60921,7 @@ snapshots: transitivePeerDependencies: - tslib - ts-checker-rspack-plugin@1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2): + ts-checker-rspack-plugin@1.5.1(@rspack/core@2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17))(tslib@2.8.1)(typescript@7.0.2): dependencies: '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 @@ -60623,11 +60929,11 @@ snapshots: picocolors: 1.1.1 typescript: 7.0.2 optionalDependencies: - '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.17) + '@rspack/core': 2.0.6(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.17) transitivePeerDependencies: - tslib - ts-checker-rspack-plugin@1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2): + ts-checker-rspack-plugin@1.5.1(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(tslib@2.8.1)(typescript@7.0.2): dependencies: '@rspack/lite-tapable': 1.1.2 chokidar: 3.6.0 @@ -60635,7 +60941,7 @@ snapshots: picocolors: 1.1.1 typescript: 7.0.2 optionalDependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) transitivePeerDependencies: - tslib @@ -61186,6 +61492,8 @@ snapshots: typescript@4.9.5: {} + typescript@5.0.4: {} + typescript@5.8.2: optional: true @@ -62008,6 +62316,11 @@ snapshots: transitivePeerDependencies: - supports-color + vue-router@4.4.5(vue@3.5.30(typescript@5.0.4)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.30(typescript@5.0.4) + vue-router@4.4.5(vue@3.5.30(typescript@7.0.2)): dependencies: '@vue/devtools-api': 6.6.4 @@ -62032,6 +62345,13 @@ snapshots: semver: 7.6.3 typescript: 7.0.2 + vue-tsc@2.2.12(typescript@5.0.4): + dependencies: + '@volar/typescript': 2.4.15 + '@vue/language-core': 2.2.12(typescript@5.0.4) + typescript: 5.0.4 + optional: true + vue-tsc@2.2.12(typescript@6.0.3): dependencies: '@volar/typescript': 2.4.15 @@ -62044,6 +62364,16 @@ snapshots: '@vue/language-core': 2.2.12(typescript@7.0.2) typescript: 7.0.2 + vue@3.5.30(typescript@5.0.4): + dependencies: + '@vue/compiler-dom': 3.5.30 + '@vue/compiler-sfc': 3.5.30 + '@vue/runtime-dom': 3.5.30 + '@vue/server-renderer': 3.5.30(vue@3.5.30(typescript@5.0.4)) + '@vue/shared': 3.5.30 + optionalDependencies: + typescript: 5.0.4 + vue@3.5.30(typescript@6.0.3): dependencies: '@vue/compiler-dom': 3.5.30 @@ -63148,18 +63478,18 @@ snapshots: dependencies: tslib: 2.8.1 - zephyr-rsbuild-plugin@1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): + zephyr-rsbuild-plugin@1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: - '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0) - zephyr-rspack-plugin: 1.1.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) + '@rsbuild/core': 2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0) + zephyr-rspack-plugin: 1.1.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) transitivePeerDependencies: - '@rspack/core' - supports-color - webpack - zephyr-rspack-plugin@1.1.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): + zephyr-rspack-plugin@1.1.2(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: - '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23) + '@rspack/core': 2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23) tslib: 2.8.1 zephyr-agent: 1.1.2 zephyr-xpack-internal: 1.1.2(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) @@ -63167,13 +63497,13 @@ snapshots: - supports-color - webpack - zephyr-rspress-plugin@1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@rspress/core@2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): + zephyr-rspress-plugin@1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@rspress/core@2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)): dependencies: - '@rspress/core': 2.0.14(@module-federation/runtime-tools@2.7.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) + '@rspress/core': 2.0.14(@module-federation/runtime-tools@2.8.0)(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(@types/mdast@4.0.4)(@types/react@19.2.14)(core-js@3.49.0)(micromark-util-types@2.0.2)(micromark@4.0.2) tslib: 2.8.1 zephyr-agent: 1.1.2 zephyr-edge-contract: 1.1.2 - zephyr-rsbuild-plugin: 1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.7.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.7.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) + zephyr-rsbuild-plugin: 1.1.2(@rsbuild/core@2.1.4(@module-federation/runtime-tools@2.8.0)(core-js@3.49.0))(@rspack/core@2.1.2(@module-federation/runtime-tools@2.8.0)(@swc/helpers@0.5.23))(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) zephyr-xpack-internal: 1.1.2(webpack@5.104.1(@swc/core@1.15.41(@swc/helpers@0.5.23))(esbuild@0.28.1)(webpack-cli@5.1.4)) transitivePeerDependencies: - '@rsbuild/core' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 52cec333b83..b0ec56f2911 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -12,6 +12,7 @@ packages: - 'apps/manifest-demo/*' - 'apps/esbuild' - 'apps/*' + - 'apps/bridge-ssr-demo/*' - 'webpack' - 'assemble-release-plan' - 'packages/runtime-plugins/*' diff --git a/tools/scripts/ci-local.mjs b/tools/scripts/ci-local.mjs index 3a39eadfd4e..e9891bcb085 100644 --- a/tools/scripts/ci-local.mjs +++ b/tools/scripts/ci-local.mjs @@ -316,6 +316,27 @@ const jobs = [ ), ], }, + { + name: 'e2e-bridge-ssr', + env: SKIP_DEVTOOLS_POSTINSTALL_ENV, + steps: [ + installDependenciesStep(), + step('Build packages', (ctx) => runPackagesBuild(ctx)), + step('Bridge SSR development acceptance', (ctx) => + runCommand('pnpm', ['run', 'e2e:bridge:ssr'], ctx), + ), + step('Bridge SSR production acceptance', (ctx) => + runCommand('pnpm', ['run', 'e2e:bridge:ssr:production'], ctx), + ), + step('Bridge SSR Vite smoke (non-blocking)', async (ctx) => { + try { + await runCommand('pnpm', ['run', 'e2e:bridge:ssr:vite-smoke'], ctx); + } catch (error) { + console.warn('[ci:local] Non-blocking Vite smoke failed:', error); + } + }), + ], + }, { name: 'metro-affected-check', env: METRO_E2E_ENV, diff --git a/tools/scripts/run-bridge-ssr-e2e.mjs b/tools/scripts/run-bridge-ssr-e2e.mjs new file mode 100644 index 00000000000..479bd350c50 --- /dev/null +++ b/tools/scripts/run-bridge-ssr-e2e.mjs @@ -0,0 +1,212 @@ +#!/usr/bin/env node +import { spawn } from 'node:child_process'; +import { + DETACHED_PROCESS_GROUP, + shutdownServe, + spawnWithPromise, +} from './e2e-process-utils.mjs'; + +const viteSmoke = process.env.BRIDGE_SSR_REMOTE_BUNDLER === 'vite'; +const production = process.env.BRIDGE_SSR_MODE === 'production' || viteSmoke; +let stopping = false; + +function startOwned(label, command, args, env) { + const child = spawn(command, args, { + stdio: 'inherit', + detached: true, + env: { ...process.env, ...env }, + }); + child[DETACHED_PROCESS_GROUP] = true; + const exit = new Promise((resolve, reject) => { + child.once('exit', (code, signal) => { + if (stopping) resolve({ code, signal }); + else + reject(new Error(`${label} exited unexpectedly (${signal ?? code})`)); + }); + child.once('error', reject); + }); + return { child, exit }; +} + +async function run(command, args, env) { + await spawnWithPromise(command, args, { + env: { ...process.env, ...env }, + }).promise; +} + +async function build(env) { + if (viteSmoke) { + await run( + 'pnpm', + ['--filter', 'bridge-ssr-remote-vue', 'run', 'build:vite'], + env, + ); + await run( + 'pnpm', + [ + 'exec', + 'turbo', + 'run', + 'build', + '--filter=bridge-ssr-host', + '--force', + '--env-mode=loose', + ], + env, + ); + } else { + await run( + 'pnpm', + [ + 'exec', + 'turbo', + 'run', + 'build', + '--filter=bridge-ssr-host', + '--filter=bridge-ssr-host-vue', + '--filter=bridge-ssr-remote-react', + '--filter=bridge-ssr-remote-vue', + ], + env, + ); + } + await run( + process.execPath, + ['tools/scripts/verify-bridge-ssr-browser-bundles.mjs'], + env, + ); +} + +async function main() { + const env = { + HOST: process.env.HOST ?? 'localhost', + BRIDGE_SSR_REMOTE_BUNDLER: viteSmoke ? 'vite' : 'rsbuild', + ...(production ? { BRIDGE_SSR_MODE: 'production' } : {}), + }; + if (production) await build(env); + + const apps = []; + if (viteSmoke) { + apps.push( + startOwned( + 'Vue Vite remote', + process.execPath, + [ + 'apps/bridge-ssr-demo/shared/serveDist.mjs', + 'apps/bridge-ssr-demo/remote-vue/dist-vite', + '2402', + ], + env, + ), + startOwned( + 'React production host', + 'pnpm', + ['--filter', 'bridge-ssr-host', 'run', 'serve:production'], + env, + ), + ); + } else if (production) { + for (const [framework, port] of [ + ['react', '2301'], + ['vue', '2302'], + ]) { + apps.push( + startOwned( + `${framework} remote`, + process.execPath, + [ + 'apps/bridge-ssr-demo/shared/serveDist.mjs', + `apps/bridge-ssr-demo/remote-${framework}/dist`, + port, + ], + env, + ), + ); + } + apps.push( + startOwned( + 'React production host', + 'pnpm', + ['--filter', 'bridge-ssr-host', 'run', 'serve:production'], + env, + ), + startOwned( + 'Vue production host', + 'pnpm', + ['--filter', 'bridge-ssr-host-vue', 'run', 'serve:production'], + env, + ), + ); + } else { + apps.push( + startOwned( + 'React remote', + 'pnpm', + ['--filter', 'bridge-ssr-remote-react', 'run', 'dev'], + env, + ), + startOwned( + 'Vue remote', + 'pnpm', + ['--filter', 'bridge-ssr-remote-vue', 'run', 'dev'], + env, + ), + startOwned( + 'React host', + 'pnpm', + ['--filter', 'bridge-ssr-host', 'run', 'dev'], + env, + ), + startOwned( + 'Vue host', + 'pnpm', + ['--filter', 'bridge-ssr-host-vue', 'run', 'dev'], + env, + ), + ); + } + + try { + const ports = viteSmoke + ? ['tcp:2300', 'tcp:2402'] + : ['tcp:2300', 'tcp:2301', 'tcp:2302', 'tcp:2303']; + await Promise.race([ + spawnWithPromise('npx', ['wait-on', '--timeout=240000', ...ports]) + .promise, + Promise.race(apps.map((app) => app.exit)), + ]); + await Promise.race([ + run('pnpm', ['--filter', 'bridge-ssr-host', 'run', 'e2e:ssr:ci'], env), + Promise.race(apps.map((app) => app.exit)), + ]); + if (!viteSmoke) { + await Promise.race([ + run( + 'pnpm', + ['--filter', 'bridge-ssr-host-vue', 'run', 'e2e:ssr:ci'], + env, + ), + Promise.race(apps.map((app) => app.exit)), + ]); + } + } finally { + stopping = true; + await Promise.allSettled( + apps.map(({ child, exit }) => shutdownServe(child, exit)), + ); + } +} + +process.on('uncaughtException', (error) => { + console.error('[bridge-ssr-e2e] uncaught exception', error); + process.exitCode = 1; +}); +process.on('unhandledRejection', (error) => { + console.error('[bridge-ssr-e2e] unhandled rejection', error); + process.exitCode = 1; +}); + +main().catch((error) => { + console.error('[bridge-ssr-e2e] failed', error); + process.exitCode = 1; +}); diff --git a/tools/scripts/verify-bridge-ssr-browser-bundles.mjs b/tools/scripts/verify-bridge-ssr-browser-bundles.mjs new file mode 100644 index 00000000000..cd960b67689 --- /dev/null +++ b/tools/scripts/verify-bridge-ssr-browser-bundles.mjs @@ -0,0 +1,49 @@ +#!/usr/bin/env node +import { readFile, readdir, stat } from 'node:fs/promises'; +import path from 'node:path'; + +const roots = + process.env.BRIDGE_SSR_REMOTE_BUNDLER === 'vite' + ? [ + 'apps/bridge-ssr-demo/remote-vue/dist-vite/assets', + 'apps/bridge-ssr-demo/remote-vue/dist-vite/remoteEntry.js', + ] + : [ + 'apps/bridge-ssr-demo/remote-react/dist/static', + 'apps/bridge-ssr-demo/remote-vue/dist/static', + ]; +const forbidden = [ + 'react-dom/server', + '@vue/server-renderer', + 'export-app.server', +]; + +async function files(directory) { + if ((await stat(directory)).isFile()) return [directory]; + const entries = await readdir(directory, { withFileTypes: true }); + return ( + await Promise.all( + entries.map((entry) => { + const target = path.join(directory, entry.name); + return entry.isDirectory() ? files(target) : [target]; + }), + ) + ).flat(); +} + +for (const root of roots) { + for (const file of await files(root)) { + if (!/\.(?:js|mjs|cjs)$/.test(file)) continue; + const source = await readFile(file, 'utf8'); + for (const token of forbidden) { + if (source.includes(token)) { + throw new Error( + `Browser bundle ${file} contains server-only token ${token}`, + ); + } + } + } +} +console.log( + '[bridge-ssr] browser bundles exclude server-only renderers and preparation', +); From f46ac6db9f68907a3ac571b50e316bb7e6760811 Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Sat, 18 Jul 2026 15:53:53 +0200 Subject: [PATCH 32/37] fix(bridge): harden SSR hydration boundaries --- apps/website-new/docs/en/guide/bridge/ssr.mdx | 2 + packages/bridge/bridge-react/README.md | 15 +++++ .../bridge-react/__tests__/router.spec.tsx | 12 ++++ .../src/remote/RemoteAppWrapper.spec.tsx | 56 +++++++++++++++++++ .../src/remote/RemoteAppWrapper.tsx | 17 ++++-- .../bridge-react/src/router/default.tsx | 12 ++++ .../bridge-react/src/router/v6.spec.tsx | 17 ++++++ .../bridge/bridge-react/src/router/v6.tsx | 6 ++ packages/bridge/bridge-shared/src/index.ts | 1 + packages/bridge/bridge-shared/src/ssr.spec.ts | 26 +++++++++ packages/bridge/bridge-shared/src/ssr.ts | 17 ++++++ .../vue3-bridge/__tests__/remoteApp.test.ts | 1 + .../bridge/vue3-bridge/src/provider.spec.ts | 32 +++++++++++ packages/bridge/vue3-bridge/src/provider.ts | 7 ++- packages/bridge/vue3-bridge/src/remoteApp.tsx | 6 +- 15 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx create mode 100644 packages/bridge/bridge-react/src/router/v6.spec.tsx diff --git a/apps/website-new/docs/en/guide/bridge/ssr.mdx b/apps/website-new/docs/en/guide/bridge/ssr.mdx index bc78c0d62c0..1d47481ded9 100644 --- a/apps/website-new/docs/en/guide/bridge/ssr.mdx +++ b/apps/website-new/docs/en/guide/bridge/ssr.mdx @@ -11,6 +11,8 @@ Bridge SSR V1 lets a federated application provider return a buffered HTML islan React data routers and other React or Router versions keep their existing client-rendering support but are not supported for SSR in V1. +React Router v6 remotes must alias `react-router-dom$` to `@module-federation/bridge-react/dist/router-v6.es.js` in both their browser and Node builds. The default `router.es.js` adapter is CSR-only. Attempting to use the default adapter or `RouterProvider` during SSR throws a configuration error. + ## Remote provider Set `ssr: true` when no request preparation is needed. If preparation is required, map the same federated export key to separate browser and Node source files. The browser file supplies `hydrate`; the Node file supplies `prepare`. This keeps server renderers and request-only code out of browser chunks. diff --git a/packages/bridge/bridge-react/README.md b/packages/bridge/bridge-react/README.md index ee86f2bddea..b1cf3c2d80e 100644 --- a/packages/bridge/bridge-react/README.md +++ b/packages/bridge/bridge-react/README.md @@ -74,6 +74,21 @@ export default defineConfig({ }); ``` +For Bridge SSR V1 with declarative React Router v6, both the browser and Node +builds must alias `react-router-dom$` to the version-specific adapter instead: + +```js +alias: { + 'react-router-dom$': path.resolve( + __dirname, + 'node_modules/@module-federation/bridge-react/dist/router-v6.es.js', + ), +} +``` + +The default `router.es.js` adapter remains the multi-version CSR adapter. React +data routers and `RouterProvider` are not supported for Bridge SSR V1. + # 3. Load the module with routing ```js diff --git a/packages/bridge/bridge-react/__tests__/router.spec.tsx b/packages/bridge/bridge-react/__tests__/router.spec.tsx index 3892a863965..95f1cbfd0f0 100644 --- a/packages/bridge/bridge-react/__tests__/router.spec.tsx +++ b/packages/bridge/bridge-react/__tests__/router.spec.tsx @@ -13,6 +13,18 @@ import { RouterContext } from '../src/provider/context'; import { getHtml, getWindowImpl } from './util'; describe('react router proxy', () => { + it('fails clearly when the generic router adapter is used for SSR', () => { + expect(() => + render( + + +
+ + , + ), + ).toThrow(/router-v6 alias/); + }); + it('BrowserRouter not wraper context', async () => { let { container } = render( diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx new file mode 100644 index 00000000000..c4928f35b7d --- /dev/null +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { renderToStaticMarkup } from 'react-dom/server'; +import { describe, expect, it } from '@rstest/core'; +import { RemoteAppWrapper } from './RemoteAppWrapper'; + +const baseProps = { + moduleName: 'remote/app', + providerInfo: () => ({ render() {}, destroy() {} }), + exportName: 'default', + fallback: () => null, + loading: null, +}; + +describe('RemoteAppWrapper SSR payload boundary', () => { + it('injects only a valid result matching the mounted module and instance', () => { + const result = { + protocolVersion: 1 as const, + moduleName: 'remote/app', + instanceId: 'remote-1', + html: '

server remote

', + }; + const html = renderToStaticMarkup( + , + ); + expect(html).toContain('data-mf-bridge-instance="remote-1"'); + expect(html).toContain('

server remote

'); + + const mismatch = renderToStaticMarkup( + , + ); + expect(mismatch).not.toContain('data-mf-bridge-ssr'); + expect(mismatch).not.toContain('server remote'); + }); + + it('rejects malformed host-carried results', () => { + expect(() => + renderToStaticMarkup( + invalid

', + } as any + } + />, + ), + ).toThrow(/incompatible result/); + }); +}); diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx index ed6f85bd968..b4ad5eeac1a 100644 --- a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx @@ -7,7 +7,10 @@ import { LoggerInstance, getRootDomDefaultClassName } from '../utils'; import { federationRuntime } from '../provider/plugin'; import { RemoteComponentProps, RemoteAppParams } from '../types'; import type { RemoteAppSSRProps } from '../types'; -import { getBridgeSSRContainerAttrs } from '@module-federation/bridge-shared'; +import { + getBridgeSSRContainerAttrs, + getMatchingBridgeSSRResult, +} from '@module-federation/bridge-shared'; export const RemoteAppWrapper = forwardRef(function ( props: RemoteAppParams & RemoteComponentProps & RemoteAppSSRProps, @@ -26,8 +29,12 @@ export const RemoteAppWrapper = forwardRef(function ( instanceId: suppliedInstanceId, ...resProps } = props; - const instanceId = suppliedInstanceId || ssr?.instanceId; - const hasSSRPayload = Boolean(ssr && instanceId); + const ssrPayload = getMatchingBridgeSSRResult(ssr, { + moduleName, + instanceId: suppliedInstanceId, + }); + const instanceId = suppliedInstanceId || ssrPayload?.instanceId; + const hasSSRPayload = Boolean(ssrPayload && instanceId); const instance = federationRuntime.instance; const rootRef: React.MutableRefObject = @@ -92,7 +99,7 @@ export const RemoteAppWrapper = forwardRef(function ( memoryRoute, fallback, instanceId, - ssrState: ssr?.dehydratedState, + ssrState: ssrPayload?.dehydratedState, ...resProps, }; renderDom.current = rootRef.current; @@ -118,7 +125,7 @@ export const RemoteAppWrapper = forwardRef(function ( : {})} {...(hasSSRPayload ? { - dangerouslySetInnerHTML: { __html: ssr!.html }, + dangerouslySetInnerHTML: { __html: ssrPayload!.html }, suppressHydrationWarning: true, } : {})} diff --git a/packages/bridge/bridge-react/src/router/default.tsx b/packages/bridge/bridge-react/src/router/default.tsx index c986f7da74a..e29ec8f4a20 100644 --- a/packages/bridge/bridge-react/src/router/default.tsx +++ b/packages/bridge/bridge-react/src/router/default.tsx @@ -18,6 +18,12 @@ function WrapperRouter( WrapperRouterProps: props, }); + if (routerContextProps?.ssrLocation) { + throw new Error( + 'Bridge SSR V1 with React Router v6 requires the @module-federation/bridge-react/router-v6 alias', + ); + } + if (routerContextProps?.memoryRoute) { return ( { + it('fails clearly when a data router is used for SSR', () => { + expect(() => + renderToStaticMarkup( + + + , + ), + ).toThrow(/does not support React Router data routers/); + }); +}); diff --git a/packages/bridge/bridge-react/src/router/v6.tsx b/packages/bridge/bridge-react/src/router/v6.tsx index 52897ecdc6e..7a396973816 100644 --- a/packages/bridge/bridge-react/src/router/v6.tsx +++ b/packages/bridge/bridge-react/src/router/v6.tsx @@ -64,6 +64,12 @@ function WraperRouterProvider( 'create' + 'BrowserRouter' ]; + if (routerContextProps.ssrLocation) { + throw new Error( + 'Bridge SSR V1 does not support React Router data routers or RouterProvider', + ); + } + if (routerContextProps.memoryRoute) { const MemeoryRouterInstance = createMemoryRouter(routers, { initialEntries: [routerContextProps?.memoryRoute.entryPath], diff --git a/packages/bridge/bridge-shared/src/index.ts b/packages/bridge/bridge-shared/src/index.ts index 4c4886467f5..67c11c9b4e1 100644 --- a/packages/bridge/bridge-shared/src/index.ts +++ b/packages/bridge/bridge-shared/src/index.ts @@ -17,6 +17,7 @@ export { assertBridgeJSONValue, assertBridgeSSRIdentity, assertBridgeSSRResult, + getMatchingBridgeSSRResult, getBridgeSSRContainerAttrs, hasBridgeSSRMarkup, serializeBridgeJSON, diff --git a/packages/bridge/bridge-shared/src/ssr.spec.ts b/packages/bridge/bridge-shared/src/ssr.spec.ts index 4fa61a16d83..d7a0d5293f5 100644 --- a/packages/bridge/bridge-shared/src/ssr.spec.ts +++ b/packages/bridge/bridge-shared/src/ssr.spec.ts @@ -3,6 +3,7 @@ import { BRIDGE_SSR_PROTOCOL_VERSION, BridgeSSRError, assertBridgeJSONValue, + getMatchingBridgeSSRResult, renderRemoteBridge, serializeBridgeJSON, } from './index'; @@ -23,6 +24,31 @@ describe('Bridge SSR V1 contract', () => { ); }); + it('validates host-carried results before matching their identity', () => { + const result = { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: 'remote/app', + instanceId: 'remote-1', + html: '

remote

', + } as const; + + expect( + getMatchingBridgeSSRResult(result, { + moduleName: 'remote/app', + instanceId: 'remote-1', + }), + ).toBe(result); + expect( + getMatchingBridgeSSRResult(result, { moduleName: 'other/app' }), + ).toBeUndefined(); + expect(() => + getMatchingBridgeSSRResult( + { ...result, protocolVersion: 2 }, + { moduleName: 'remote/app' }, + ), + ).toThrow(/incompatible result/); + }); + it('loads, renders, and validates a remote provider', async () => { const renderServer = vi.fn(async (context) => ({ protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, diff --git a/packages/bridge/bridge-shared/src/ssr.ts b/packages/bridge/bridge-shared/src/ssr.ts index e295ae62b1e..090a555ee50 100644 --- a/packages/bridge/bridge-shared/src/ssr.ts +++ b/packages/bridge/bridge-shared/src/ssr.ts @@ -145,6 +145,23 @@ export function assertBridgeSSRResult( } } +export function getMatchingBridgeSSRResult( + value: unknown, + expected: { moduleName?: string; instanceId?: string }, +): BridgeSSRResult | undefined { + if (value === undefined) return undefined; + assertBridgeSSRResult(value); + if ( + (expected.moduleName !== undefined && + value.moduleName !== expected.moduleName) || + (expected.instanceId !== undefined && + value.instanceId !== expected.instanceId) + ) { + return undefined; + } + return value; +} + export function getBridgeSSRContainerAttrs(value: { moduleName: string; instanceId: string; diff --git a/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts b/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts index ffc10f60dfd..059d6ec431e 100644 --- a/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts +++ b/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts @@ -9,6 +9,7 @@ const { dispatchPopstateEnv } = rs.hoisted(() => ({ rs.mock('@module-federation/bridge-shared', () => ({ dispatchPopstateEnv, + getMatchingBridgeSSRResult: () => undefined, })); rs.mock('@module-federation/runtime', () => ({ diff --git a/packages/bridge/vue3-bridge/src/provider.spec.ts b/packages/bridge/vue3-bridge/src/provider.spec.ts index 9e34fec2006..27806cd484d 100644 --- a/packages/bridge/vue3-bridge/src/provider.spec.ts +++ b/packages/bridge/vue3-bridge/src/provider.spec.ts @@ -43,4 +43,36 @@ describe('Vue Bridge server provider', () => { }); expect(serverRenderer).toHaveBeenCalledOnce(); }); + + it('unmounts the previous app before rendering again into the same DOM node', async () => { + const provider = createBridgeComponentWithServerRenderer({ + rootComponent: defineComponent({ + props: { label: String }, + setup: (props) => () => h('p', props.label), + }), + appOptions: () => undefined, + })(); + const dom = document.createElement('div'); + + await provider.render({ + dom, + moduleName: 'vue/remote', + label: 'first', + } as any); + const firstApp = (dom as HTMLElement & { __vue_app__?: any }).__vue_app__; + const unmount = rs.spyOn(firstApp, 'unmount'); + + await provider.render({ + dom, + moduleName: 'vue/remote', + label: 'second', + } as any); + expect(unmount).toHaveBeenCalledOnce(); + expect(dom.textContent).toBe('second'); + expect((dom as HTMLElement & { __vue_app__?: any }).__vue_app__).not.toBe( + firstApp, + ); + + provider.destroy({ dom }); + }); }); diff --git a/packages/bridge/vue3-bridge/src/provider.ts b/packages/bridge/vue3-bridge/src/provider.ts index 0c2e6723aad..86f0777f1f5 100644 --- a/packages/bridge/vue3-bridge/src/provider.ts +++ b/packages/bridge/vue3-bridge/src/provider.ts @@ -143,6 +143,11 @@ export function createBridgeComponentWithServerRenderer( beforeBridgeRenderRes.extraProps ? beforeBridgeRenderRes.extraProps : {}; + const previousApp = roots.get(dom); + if (previousApp) { + previousApp.unmount(); + roots.delete(dom); + } const shouldHydrate = hasBridgeSSRMarkup(dom, { moduleName, instanceId, @@ -157,8 +162,8 @@ export function createBridgeComponentWithServerRenderer( shouldHydrate ? 'hydrate' : 'csr', ); if (signal?.aborted) return; - roots.set(dom, app); app.mount(dom, shouldHydrate); + roots.set(dom, app); runtime?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(info); LoggerInstance.debug('createBridgeComponent rendered', { moduleName }); }, diff --git a/packages/bridge/vue3-bridge/src/remoteApp.tsx b/packages/bridge/vue3-bridge/src/remoteApp.tsx index d32f5e4e947..9fcfbb60a71 100644 --- a/packages/bridge/vue3-bridge/src/remoteApp.tsx +++ b/packages/bridge/vue3-bridge/src/remoteApp.tsx @@ -12,6 +12,7 @@ import { import { dispatchPopstateEnv, getBridgeSSRContainerAttrs, + getMatchingBridgeSSRResult, type BridgeSSRResult, } from '@module-federation/bridge-shared'; import { useRoute } from 'vue-router'; @@ -41,7 +42,10 @@ export default defineComponent({ const route = useRoute(); const hostInstance = getInstance(); const componentAttrs = useAttrs(); - const ssrPayload = props.ssr as BridgeSSRResult | undefined; + const ssrPayload = getMatchingBridgeSSRResult(props.ssr, { + moduleName: props.moduleName, + instanceId: props.instanceId, + }) as BridgeSSRResult | undefined; const instanceId = props.instanceId || ssrPayload?.instanceId; const getBridgeRenderProps = () => ({ From 4f52759cde3626597e9ec204646e4cf8c252bf48 Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Sat, 18 Jul 2026 17:00:12 +0200 Subject: [PATCH 33/37] fix(bridge): hydrate SSR islands from document slots --- .../host-vue/src/entry.client.ts | 3 + .../host-vue/src/entry.server.ts | 7 +- .../host-vue/src/ssrContext.ts | 46 ++- .../host/e2e/bridge-ssr-browser.spec.ts | 23 +- .../host/e2e/bridge-ssr-nojs.spec.ts | 11 + .../bridge-ssr-demo/host/src/entry.client.tsx | 11 +- .../bridge-ssr-demo/host/src/entry.server.tsx | 2 + .../host/src/lib/hostSsrContext.ts | 8 +- .../host/src/lib/ssrContext.ts | 31 +- .../shared/createHostServer.mjs | 4 +- .../bridge-react/src/hydration.spec.tsx | 108 +++++++ .../bridge/bridge-react/src/hydration.tsx | 83 +++++ packages/bridge/bridge-react/src/index.ts | 3 + .../src/remote/RemoteAppWrapper.spec.tsx | 2 + .../src/remote/RemoteAppWrapper.tsx | 67 ++-- packages/bridge/bridge-react/src/types.ts | 7 +- packages/bridge/bridge-react/src/v18.ts | 1 + packages/bridge/bridge-shared/src/index.ts | 13 + packages/bridge/bridge-shared/src/ssr.spec.ts | 50 +++ packages/bridge/bridge-shared/src/ssr.ts | 302 ++++++++++++++++++ packages/bridge/bridge-shared/src/type.ts | 27 ++ .../vue3-bridge/__tests__/remoteApp.test.ts | 2 +- packages/bridge/vue3-bridge/src/create.ts | 9 + packages/bridge/vue3-bridge/src/hydration.ts | 17 + .../bridge/vue3-bridge/src/index.server.ts | 2 + packages/bridge/vue3-bridge/src/index.ts | 2 + packages/bridge/vue3-bridge/src/remoteApp.tsx | 83 ++++- 27 files changed, 867 insertions(+), 57 deletions(-) create mode 100644 packages/bridge/bridge-react/src/hydration.spec.tsx create mode 100644 packages/bridge/bridge-react/src/hydration.tsx create mode 100644 packages/bridge/vue3-bridge/src/hydration.ts diff --git a/apps/bridge-ssr-demo/host-vue/src/entry.client.ts b/apps/bridge-ssr-demo/host-vue/src/entry.client.ts index e83cec85dfa..3d95da30f37 100644 --- a/apps/bridge-ssr-demo/host-vue/src/entry.client.ts +++ b/apps/bridge-ssr-demo/host-vue/src/entry.client.ts @@ -1,5 +1,7 @@ import { createSSRApp } from 'vue'; import { createRouter, createWebHistory } from 'vue-router'; +import { createBridgeHydrationRegistry } from '@module-federation/bridge-shared'; +import { provideBridgeHydrationRegistry } from '@module-federation/bridge-vue3'; import App from './App.vue'; import { readHostSSRContext } from './ssrContext'; @@ -9,5 +11,6 @@ const router = createRouter({ }); const app = createSSRApp(App, { ssrContext: readHostSSRContext() }); app.use(router); +provideBridgeHydrationRegistry(app, createBridgeHydrationRegistry(document)); await router.isReady(); app.mount('#root'); diff --git a/apps/bridge-ssr-demo/host-vue/src/entry.server.ts b/apps/bridge-ssr-demo/host-vue/src/entry.server.ts index 5da8cd99a98..818631b00e9 100644 --- a/apps/bridge-ssr-demo/host-vue/src/entry.server.ts +++ b/apps/bridge-ssr-demo/host-vue/src/entry.server.ts @@ -2,6 +2,7 @@ import { createSSRApp } from 'vue'; import { renderToString } from '@vue/server-renderer'; import { createMemoryHistory, createRouter } from 'vue-router'; import App from './App.vue'; +import { toHostHydrationContext } from './ssrContext'; import { prepareSSRContext, type PrepareSSRContextOptions, @@ -25,5 +26,9 @@ export async function render( options: PrepareSSRContextOptions = {}, ) { const { app, ssrContext } = await createHostApp(url, options); - return { html: await renderToString(app), ssrContext }; + return { + html: await renderToString(app), + ssrContext, + hydrationContext: toHostHydrationContext(ssrContext), + }; } diff --git a/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts b/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts index 52d784a2610..b6a605f44d7 100644 --- a/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts +++ b/apps/bridge-ssr-demo/host-vue/src/ssrContext.ts @@ -1,18 +1,56 @@ -import type { BridgeSSRResult } from '@module-federation/bridge-shared'; +import { + assertBridgeSSRReference, + toBridgeSSRReference, + type BridgeSSRReference, + type BridgeSSRResult, +} from '@module-federation/bridge-shared'; + +export type RemoteSSRData = BridgeSSRResult | BridgeSSRReference; export type HostSSRContext = { url: string; - reactRemote?: BridgeSSRResult; - reactPair?: [BridgeSSRResult, BridgeSSRResult]; + reactRemote?: RemoteSSRData; + reactPair?: [RemoteSSRData, RemoteSSRData]; +}; + +export type HostHydrationContext = { + url: string; + reactRemote?: BridgeSSRReference; + reactPair?: [BridgeSSRReference, BridgeSSRReference]; }; +function toReference(data: RemoteSSRData): BridgeSSRReference { + if ('html' in data) return toBridgeSSRReference(data); + assertBridgeSSRReference(data); + return data; +} + +export function toHostHydrationContext( + context: HostSSRContext, +): HostHydrationContext { + return { + url: context.url, + ...(context.reactRemote + ? { reactRemote: toReference(context.reactRemote) } + : {}), + ...(context.reactPair + ? { + reactPair: context.reactPair.map(toReference) as [ + BridgeSSRReference, + BridgeSSRReference, + ], + } + : {}), + }; +} + export const HOST_SSR_CONTEXT_SCRIPT_ID = 'bridge-ssr-host-context'; export function readHostSSRContext() { const script = document.getElementById(HOST_SSR_CONTEXT_SCRIPT_ID); if (!script?.textContent) return undefined; try { - return JSON.parse(script.textContent) as HostSSRContext; + return JSON.parse(script.textContent) as HostHydrationContext; } catch { return undefined; } diff --git a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts index 113abff34e3..be739f4e1e5 100644 --- a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts +++ b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-browser.spec.ts @@ -40,7 +40,10 @@ test('server-renders a deep route and remote navigation updates the URL', async page, }, testInfo) => { const remote = direction(testInfo.project.name); - await page.goto(remote.detail); + await page.goto(`${remote.detail}?source=e2e#bridge-state`); + await expect(page).toHaveURL( + new RegExp(`${remote.detail}\\?source=e2e#bridge-state$`), + ); await expect( page.getByRole('heading', { name: remote.detailHeading }), ).toBeVisible(); @@ -77,6 +80,24 @@ test('host navigation enters, leaves, and returns through CSR without reload', a .toBe('alive'); }); +test('consumes direct-visit SSR once and revisits through CSR', async ({ + page, +}, testInfo) => { + const remote = direction(testInfo.project.name); + await page.goto(remote.route); + await expect(page.locator('[data-mf-bridge-ssr="true"]')).toHaveCount(1); + await expect( + page.getByRole('heading', { name: remote.homeHeading }), + ).toBeVisible(); + + await page.getByRole('link', { name: 'Home' }).first().click(); + await page.locator(remote.hostLink).first().click(); + await expect( + page.getByRole('heading', { name: remote.homeHeading }), + ).toBeVisible(); + await expect(page.locator('[data-mf-bridge-ssr="true"]')).toHaveCount(0); +}); + test('two instances of one React remote hydrate independently', async ({ page, }, testInfo) => { diff --git a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts index 5628de49bbd..db31282b8c9 100644 --- a/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts +++ b/apps/bridge-ssr-demo/host/e2e/bridge-ssr-nojs.spec.ts @@ -12,7 +12,18 @@ test('raw response contains the cross-framework remote route', async ({ expect(response.ok()).toBeTruthy(); expect(html).toContain(heading); expect(html).toContain('data-mf-bridge-ssr="true"'); + expect(html).toContain('data-mf-bridge-slot="true"'); + expect(html).toContain('data-mf-bridge-state="true"'); expect(html).toContain('bridge-ssr-host-context'); + expect(html.match(new RegExp(heading, 'g'))).toHaveLength(1); + + const contextMatch = html.match( + /
', + 'unexpected', + ); + expect(() => + createBridgeHydrationRegistry(document).peek('remote/app', 'remote-1'), + ).toThrow(/only its direct mount and state children/); + + document.body.innerHTML = original.replace( + '"state":', + '"html":"duplicate","state":', + ); + expect(() => + createBridgeHydrationRegistry(document).peek('remote/app', 'remote-1'), + ).toThrow(/incompatible state envelope/); + }); +}); diff --git a/packages/bridge/bridge-react/src/hydration.tsx b/packages/bridge/bridge-react/src/hydration.tsx new file mode 100644 index 00000000000..b131dfe162f --- /dev/null +++ b/packages/bridge/bridge-react/src/hydration.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { + BRIDGE_SSR_PROTOCOL_VERSION, + MF_BRIDGE_STATE_ATTR, + getBridgeSSRContainerAttrs, + getBridgeSSRSlotAttrs, + serializeBridgeSSRStateEnvelope, + type BridgeHydrationRegistry, + type BridgeHydrationSnapshot, + type BridgeSSRResult, +} from '@module-federation/bridge-shared'; +import { getRootDomDefaultClassName } from './utils'; + +const BridgeHydrationContext = React.createContext< + BridgeHydrationRegistry | undefined +>(undefined); + +export function BridgeHydrationProvider({ + registry, + children, +}: { + registry: BridgeHydrationRegistry; + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} + +export function useBridgeHydrationRegistry() { + return React.useContext(BridgeHydrationContext); +} + +export function BridgeRemoteSlot({ + moduleName, + instanceId, + payload, + snapshot, + className, + style, + mountRef, +}: { + moduleName: string; + instanceId: string; + payload?: BridgeSSRResult; + snapshot?: BridgeHydrationSnapshot; + className?: string; + style?: React.CSSProperties; + mountRef?: React.Ref; +}) { + const html = payload?.html ?? snapshot?.html ?? ''; + const state = payload?.dehydratedState ?? snapshot?.state; + const rootClassName = + `${getRootDomDefaultClassName(moduleName)} ${className || ''}`.trim(); + + return ( +
+
+ \u2028\u2029' }, + }), + ).toBe( + '{"protocolVersion":1,"moduleName":"remote/app","instanceId":"remote-1","state":{"value":"\\u003c/script>\\u2028\\u2029"}}', + ); + expect(() => + serializeBridgeSSRStateEnvelope({ + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: 'remote/app', + instanceId: 'remote-1', + html: '

must not be serialized

', + } as any), + ).toThrow(/state envelope is incompatible/); + }); + it('loads, renders, and validates a remote provider', async () => { const renderServer = vi.fn(async (context) => ({ protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, diff --git a/packages/bridge/bridge-shared/src/ssr.ts b/packages/bridge/bridge-shared/src/ssr.ts index 090a555ee50..586f70659a6 100644 --- a/packages/bridge/bridge-shared/src/ssr.ts +++ b/packages/bridge/bridge-shared/src/ssr.ts @@ -1,14 +1,21 @@ import { BRIDGE_SSR_PROTOCOL_VERSION, BridgeSSRError, + type BridgeHydrationRegistry, + type BridgeHydrationSnapshot, type BridgeJSONValue, + type BridgeSSRReference, type BridgeSSRResult, + type BridgeSSRStateEnvelope, } from './type'; export const MF_BRIDGE_SSR_ATTR = 'data-mf-bridge-ssr'; export const MF_BRIDGE_VERSION_ATTR = 'data-mf-bridge-version'; export const MF_BRIDGE_MODULE_ATTR = 'data-mf-bridge-module'; export const MF_BRIDGE_INSTANCE_ATTR = 'data-mf-bridge-instance'; +export const MF_BRIDGE_SLOT_ATTR = 'data-mf-bridge-slot'; +export const MF_BRIDGE_MOUNT_ATTR = 'data-mf-bridge-mount'; +export const MF_BRIDGE_STATE_ATTR = 'data-mf-bridge-state'; function assertPrintable(value: string, label: string) { if (!value || /[\u0000-\u001f\u007f]/.test(value)) { @@ -111,6 +118,72 @@ export function serializeBridgeSSRResult(result: BridgeSSRResult): string { .replace(/\u2029/g, '\\u2029'); } +export function toBridgeSSRReference( + result: BridgeSSRResult, +): BridgeSSRReference { + assertBridgeSSRResult(result); + return Object.freeze({ + protocolVersion: result.protocolVersion, + moduleName: result.moduleName, + instanceId: result.instanceId, + }); +} + +export function assertBridgeSSRReference( + value: unknown, +): asserts value is BridgeSSRReference { + if (!value || typeof value !== 'object') { + throw new BridgeSSRError('Bridge SSR reference is invalid'); + } + const reference = value as Partial; + if ( + Object.keys(reference).some( + (key) => + key !== 'protocolVersion' && + key !== 'moduleName' && + key !== 'instanceId', + ) || + reference.protocolVersion !== BRIDGE_SSR_PROTOCOL_VERSION || + typeof reference.moduleName !== 'string' || + typeof reference.instanceId !== 'string' + ) { + throw new BridgeSSRError('Bridge SSR reference is incompatible'); + } + assertBridgeSSRIdentity({ + moduleName: reference.moduleName, + instanceId: reference.instanceId, + }); +} + +export function serializeBridgeSSRStateEnvelope( + envelope: BridgeSSRStateEnvelope, +): string { + const allowedKeys = new Set([ + 'protocolVersion', + 'moduleName', + 'instanceId', + 'state', + ]); + if ( + !envelope || + typeof envelope !== 'object' || + Array.isArray(envelope) || + Object.keys(envelope).some((key) => !allowedKeys.has(key)) + ) { + throw new BridgeSSRError('Bridge SSR state envelope is incompatible'); + } + assertBridgeSSRReference({ + protocolVersion: envelope.protocolVersion, + moduleName: envelope.moduleName, + instanceId: envelope.instanceId, + }); + if (envelope.state !== undefined) assertBridgeJSONValue(envelope.state); + return JSON.stringify(envelope) + .replace(/ { + assertBridgeSSRIdentity(value); + return { + [MF_BRIDGE_SLOT_ATTR]: 'true', [MF_BRIDGE_VERSION_ATTR]: String(BRIDGE_SSR_PROTOCOL_VERSION), [MF_BRIDGE_MODULE_ATTR]: value.moduleName, [MF_BRIDGE_INSTANCE_ATTR]: value.instanceId, @@ -190,3 +298,197 @@ export function hasBridgeSSRMarkup( dom.hasChildNodes() ); } + +function directChildrenWithAttribute( + parent: Element, + attribute: string, +): T[] { + return Array.from(parent.children).filter( + (child) => child.getAttribute(attribute) === 'true', + ) as T[]; +} + +function freezeJSONValue( + value: BridgeJSONValue | undefined, +): BridgeJSONValue | undefined { + if (!value || typeof value !== 'object' || Object.isFrozen(value)) { + return value; + } + if (Array.isArray(value)) value.forEach((item) => freezeJSONValue(item)); + else Object.values(value).forEach((item) => freezeJSONValue(item)); + Object.freeze(value); + return value; +} + +function hydrationError(message: string, cause?: unknown) { + return new BridgeSSRError(message, cause); +} + +function readSlotSnapshot(slot: HTMLElement): BridgeHydrationSnapshot { + const protocolVersion = Number(slot.getAttribute(MF_BRIDGE_VERSION_ATTR)); + const moduleName = slot.getAttribute(MF_BRIDGE_MODULE_ATTR) || ''; + const instanceId = slot.getAttribute(MF_BRIDGE_INSTANCE_ATTR) || ''; + assertBridgeSSRIdentity({ moduleName, instanceId }); + if (protocolVersion !== BRIDGE_SSR_PROTOCOL_VERSION) { + throw hydrationError( + `Bridge SSR slot ${instanceId} uses unsupported protocol version ${protocolVersion}`, + ); + } + + const mounts = directChildrenWithAttribute( + slot, + MF_BRIDGE_MOUNT_ATTR, + ); + const scripts = directChildrenWithAttribute( + slot, + MF_BRIDGE_STATE_ATTR, + ); + if (mounts.length !== 1 || scripts.length !== 1) { + throw hydrationError( + `Bridge SSR slot ${instanceId} must contain exactly one direct mount and state child`, + ); + } + + const [mount] = mounts; + const [script] = scripts; + if ( + slot.children.length !== 2 || + slot.children[0] !== mount || + slot.children[1] !== script || + script.tagName !== 'SCRIPT' + ) { + throw hydrationError( + `Bridge SSR slot ${instanceId} must contain only its direct mount and state children in order`, + ); + } + if ( + mount.getAttribute(MF_BRIDGE_MODULE_ATTR) !== moduleName || + mount.getAttribute(MF_BRIDGE_INSTANCE_ATTR) !== instanceId || + mount.getAttribute(MF_BRIDGE_VERSION_ATTR) !== String(protocolVersion) + ) { + throw hydrationError( + `Bridge SSR slot ${instanceId} mount metadata does not match its slot`, + ); + } + if (script.type !== 'application/json' || !script.textContent) { + throw hydrationError( + `Bridge SSR slot ${instanceId} has an invalid state envelope`, + ); + } + + let envelope: BridgeSSRStateEnvelope; + try { + envelope = JSON.parse(script.textContent) as BridgeSSRStateEnvelope; + } catch (error) { + throw hydrationError( + `Bridge SSR slot ${instanceId} state envelope is not valid JSON`, + error, + ); + } + const envelopeKeys = Object.keys(envelope); + if ( + !envelope || + typeof envelope !== 'object' || + Array.isArray(envelope) || + envelopeKeys.some( + (key) => + key !== 'protocolVersion' && + key !== 'moduleName' && + key !== 'instanceId' && + key !== 'state', + ) + ) { + throw hydrationError( + `Bridge SSR slot ${instanceId} has an incompatible state envelope`, + ); + } + if ( + envelope.protocolVersion !== protocolVersion || + envelope.moduleName !== moduleName || + envelope.instanceId !== instanceId + ) { + throw hydrationError( + `Bridge SSR slot ${instanceId} state metadata does not match its slot`, + ); + } + if (envelope.state !== undefined) assertBridgeJSONValue(envelope.state); + + return Object.freeze({ + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName, + instanceId, + html: mount.innerHTML, + state: freezeJSONValue(envelope.state), + }); +} + +export function createBridgeHydrationRegistry( + root?: ParentNode, +): BridgeHydrationRegistry { + const hydrationRoot = + root ?? (typeof document === 'undefined' ? undefined : document); + if (!hydrationRoot) { + throw hydrationError( + 'createBridgeHydrationRegistry requires a document root on the server', + ); + } + const snapshots = new Map(); + const errors = new Map(); + + for (const slot of Array.from( + hydrationRoot.querySelectorAll( + `[${MF_BRIDGE_SLOT_ATTR}="true"]`, + ), + )) { + const instanceId = slot.getAttribute(MF_BRIDGE_INSTANCE_ATTR) || ''; + if (snapshots.has(instanceId) || errors.has(instanceId)) { + snapshots.delete(instanceId); + errors.set( + instanceId, + hydrationError(`Duplicate Bridge SSR instanceId ${instanceId}`), + ); + continue; + } + try { + const snapshot = readSlotSnapshot(slot); + snapshots.set(snapshot.instanceId, snapshot); + } catch (error) { + errors.set( + instanceId, + error instanceof BridgeSSRError + ? error + : hydrationError( + `Unable to read Bridge SSR slot ${instanceId}`, + error, + ), + ); + } + } + + return { + peek(moduleName, instanceId) { + const error = errors.get(instanceId); + if (error) throw error; + const snapshot = snapshots.get(instanceId); + if (!snapshot) return undefined; + if (snapshot.moduleName !== moduleName) { + throw hydrationError( + `Bridge SSR instance ${instanceId} belongs to ${snapshot.moduleName}, not ${moduleName}`, + ); + } + return snapshot; + }, + consume(moduleName, instanceId) { + const snapshot = this.peek(moduleName, instanceId); + snapshots.delete(instanceId); + errors.delete(instanceId); + return snapshot; + }, + fail(moduleName, instanceId) { + const snapshot = snapshots.get(instanceId); + if (snapshot && snapshot.moduleName !== moduleName) return; + snapshots.delete(instanceId); + errors.delete(instanceId); + }, + }; +} diff --git a/packages/bridge/bridge-shared/src/type.ts b/packages/bridge/bridge-shared/src/type.ts index 29bfe5af306..65205b4ccba 100644 --- a/packages/bridge/bridge-shared/src/type.ts +++ b/packages/bridge/bridge-shared/src/type.ts @@ -45,6 +45,33 @@ export type BridgeSSRResult = { dehydratedState?: BridgeJSONValue; }; +/** Identity-only payload safe to serialize into a host hydration context. */ +export type BridgeSSRReference = Pick< + BridgeSSRResult, + 'protocolVersion' | 'moduleName' | 'instanceId' +>; + +export type BridgeSSRStateEnvelope = BridgeSSRReference & { + state?: BridgeJSONValue; +}; + +export type BridgeHydrationSnapshot = BridgeSSRReference & { + html: string; + state?: BridgeJSONValue; +}; + +export interface BridgeHydrationRegistry { + peek( + moduleName: string, + instanceId: string, + ): BridgeHydrationSnapshot | undefined; + consume( + moduleName: string, + instanceId: string, + ): BridgeHydrationSnapshot | undefined; + fail(moduleName: string, instanceId: string): void; +} + export class BridgeSSRError extends Error { override readonly cause?: unknown; diff --git a/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts b/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts index 059d6ec431e..2f7bf27991d 100644 --- a/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts +++ b/packages/bridge/vue3-bridge/__tests__/remoteApp.test.ts @@ -9,7 +9,7 @@ const { dispatchPopstateEnv } = rs.hoisted(() => ({ rs.mock('@module-federation/bridge-shared', () => ({ dispatchPopstateEnv, - getMatchingBridgeSSRResult: () => undefined, + getMatchingBridgeSSRPayload: () => undefined, })); rs.mock('@module-federation/runtime', () => ({ diff --git a/packages/bridge/vue3-bridge/src/create.ts b/packages/bridge/vue3-bridge/src/create.ts index 9fe415acee8..2c3033220dd 100644 --- a/packages/bridge/vue3-bridge/src/create.ts +++ b/packages/bridge/vue3-bridge/src/create.ts @@ -2,9 +2,18 @@ import { type AsyncComponentOptions, defineAsyncComponent, h } from 'vue'; import { useRoute } from 'vue-router'; import RemoteApp from './remoteApp.jsx'; import { LoggerInstance } from './utils.js'; +import type { + BridgeSSRReference, + BridgeSSRResult, +} from '@module-federation/bridge-shared'; declare const __APP_VERSION__: string; +export type RemoteAppSSRProps = { + ssr?: BridgeSSRResult | BridgeSSRReference; + instanceId?: string; +}; + export function createRemoteAppComponent(info: { loader: () => Promise; export?: string; diff --git a/packages/bridge/vue3-bridge/src/hydration.ts b/packages/bridge/vue3-bridge/src/hydration.ts new file mode 100644 index 00000000000..1375ac12bff --- /dev/null +++ b/packages/bridge/vue3-bridge/src/hydration.ts @@ -0,0 +1,17 @@ +import { inject, type App, type InjectionKey } from 'vue'; +import type { BridgeHydrationRegistry } from '@module-federation/bridge-shared'; + +export const BridgeHydrationRegistryKey: InjectionKey = + Symbol.for('mf.bridge.hydration-registry'); + +export function provideBridgeHydrationRegistry( + app: App, + registry: BridgeHydrationRegistry, +) { + app.provide(BridgeHydrationRegistryKey, registry); + return app; +} + +export function useBridgeHydrationRegistry() { + return inject(BridgeHydrationRegistryKey, undefined); +} diff --git a/packages/bridge/vue3-bridge/src/index.server.ts b/packages/bridge/vue3-bridge/src/index.server.ts index a260a91227a..9743a3fb20a 100644 --- a/packages/bridge/vue3-bridge/src/index.server.ts +++ b/packages/bridge/vue3-bridge/src/index.server.ts @@ -13,4 +13,6 @@ export function createBridgeComponent(bridgeInfo: ProviderFnParams) { export type { ProviderFnParams } from './provider'; export { createRemoteComponent, createRemoteAppComponent } from './create'; +export type { RemoteAppSSRProps } from './create'; +export { provideBridgeHydrationRegistry } from './hydration'; export type { RenderFnParams } from '@module-federation/bridge-shared'; diff --git a/packages/bridge/vue3-bridge/src/index.ts b/packages/bridge/vue3-bridge/src/index.ts index fbf7a554075..1de0572548e 100644 --- a/packages/bridge/vue3-bridge/src/index.ts +++ b/packages/bridge/vue3-bridge/src/index.ts @@ -1,4 +1,6 @@ export { createBridgeComponent } from './provider'; export type { ProviderFnParams } from './provider'; export { createRemoteComponent, createRemoteAppComponent } from './create'; +export type { RemoteAppSSRProps } from './create'; +export { provideBridgeHydrationRegistry } from './hydration'; export type { RenderFnParams } from '@module-federation/bridge-shared'; diff --git a/packages/bridge/vue3-bridge/src/remoteApp.tsx b/packages/bridge/vue3-bridge/src/remoteApp.tsx index 9fcfbb60a71..82e832e4f54 100644 --- a/packages/bridge/vue3-bridge/src/remoteApp.tsx +++ b/packages/bridge/vue3-bridge/src/remoteApp.tsx @@ -10,14 +10,19 @@ import { nextTick, } from 'vue'; import { + BRIDGE_SSR_PROTOCOL_VERSION, dispatchPopstateEnv, getBridgeSSRContainerAttrs, - getMatchingBridgeSSRResult, + getBridgeSSRSlotAttrs, + getMatchingBridgeSSRPayload, + serializeBridgeSSRStateEnvelope, + type BridgeSSRReference, type BridgeSSRResult, } from '@module-federation/bridge-shared'; import { useRoute } from 'vue-router'; import { LoggerInstance } from './utils'; import { getInstance } from '@module-federation/runtime'; +import { useBridgeHydrationRegistry } from './hydration'; export default defineComponent({ name: 'RemoteApp', @@ -42,11 +47,25 @@ export default defineComponent({ const route = useRoute(); const hostInstance = getInstance(); const componentAttrs = useAttrs(); - const ssrPayload = getMatchingBridgeSSRResult(props.ssr, { + const ssrPayload = getMatchingBridgeSSRPayload(props.ssr, { moduleName: props.moduleName, instanceId: props.instanceId, - }) as BridgeSSRResult | undefined; + }); const instanceId = props.instanceId || ssrPayload?.instanceId; + const serverPayload = + ssrPayload && 'html' in ssrPayload + ? (ssrPayload as BridgeSSRResult) + : undefined; + const reference = + ssrPayload && !('html' in ssrPayload) + ? (ssrPayload as BridgeSSRReference) + : undefined; + const registry = useBridgeHydrationRegistry(); + const snapshot = + reference && instanceId + ? registry?.peek(reference.moduleName, instanceId) + : undefined; + const hasSSRPayload = Boolean((serverPayload || snapshot) && instanceId); const getBridgeRenderProps = () => ({ name: props.moduleName, @@ -71,7 +90,7 @@ export default defineComponent({ memoryRoute: props.memoryRoute, hashRoute: props.hashRoute, instanceId, - ssrState: ssrPayload?.dehydratedState, + ssrState: serverPayload?.dehydratedState ?? snapshot?.state, }; LoggerInstance.debug( `createRemoteAppComponent LazyComponent render >>>`, @@ -84,8 +103,14 @@ export default defineComponent({ )) || {}; renderProps = { ...renderProps, ...beforeBridgeRenderRes.extraProps }; - providerReturn.render(renderProps); + await providerReturn.render(renderProps); isRendered.value = true; + if (snapshot && instanceId) { + registry?.consume( + props.moduleName || reference!.moduleName, + instanceId, + ); + } hostInstance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit(renderProps); }; @@ -163,18 +188,42 @@ export default defineComponent({ destroyComponent(); }); - return () => ( -
{ + const mount = ( +
+ ); + if (!hasSSRPayload || !instanceId) return mount; + const moduleName = props.moduleName || ssrPayload!.moduleName; + return ( +
+ {mount} +
', @@ -105,4 +105,34 @@ describe('Bridge hydration registry', () => { createBridgeHydrationRegistry(document).peek('remote/app', 'remote-1'), ).toThrow(/incompatible state envelope/); }); + + it('allows the same instanceId across different module names', () => { + const second = { + ...result, + moduleName: 'other/app', + html: '

other remote

', + }; + document.body.innerHTML = + renderToStaticMarkup( + , + ) + + renderToStaticMarkup( + , + ); + const registry = createBridgeHydrationRegistry(document); + expect(registry.peek('remote/app', 'remote-1')?.html).toBe( + '

server remote

', + ); + expect(registry.peek('other/app', 'remote-1')?.html).toBe( + '

other remote

', + ); + }); }); diff --git a/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx b/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx index ab3839cdcbb..58ad7d952a8 100644 --- a/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx +++ b/packages/bridge/bridge-react/src/provider/versions/bridge-server.tsx @@ -34,6 +34,7 @@ export function createServerBridgeComponent( const config = typeof bridgeInfo.ssr === 'object' ? bridgeInfo.ssr : undefined; const preparedValue = await config?.prepare?.(context); + if (context.signal.aborted) throw context.signal.reason; const prepared = (preparedValue || {}) as BridgeSSRPrepareResult; const renderInfo = (prepared.props ?? context.props) as T & ProviderParams; diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx index 45b07332dd8..047f99fc6a0 100644 --- a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx @@ -14,6 +14,7 @@ import { federationRuntime } from '../provider/plugin'; import { RemoteComponentProps, RemoteAppParams } from '../types'; import type { RemoteAppSSRProps } from '../types'; import { + BridgeSSRError, getMatchingBridgeSSRPayload, type BridgeSSRReference, type BridgeSSRResult, @@ -35,6 +36,25 @@ function scheduleBridgeDestroy(destroy: () => void) { else void Promise.resolve().then(destroy); } +function destroyProviderRoot( + provider: { destroy?: (info: { dom: HTMLElement }) => void } | null, + dom: HTMLElement | null, + destroyInfo: Record, +) { + if (!provider?.destroy || !dom) return; + try { + federationRuntime.instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit( + destroyInfo, + ); + provider.destroy({ dom }); + federationRuntime.instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit( + destroyInfo, + ); + } catch (error) { + LoggerInstance.error('Bridge remote destroy failed', error); + } +} + export const RemoteAppWrapper = forwardRef(function ( props: RemoteAppParams & RemoteComponentProps & RemoteAppSSRProps, ref, @@ -66,6 +86,11 @@ export const RemoteAppWrapper = forwardRef(function ( ? (ssrPayload as BridgeSSRReference) : undefined; const registry = useBridgeHydrationRegistry(); + if (reference && !registry) { + throw new BridgeSSRError( + 'Bridge SSR references require BridgeHydrationProvider before hydrateRoot', + ); + } const hydrationSnapshotRef = useRef<{ identity: string; snapshot: ReturnType['peek']>; @@ -78,7 +103,7 @@ export const RemoteAppWrapper = forwardRef(function ( ) { hydrationSnapshotRef.current = { identity: hydrationIdentity, - snapshot: registry?.peek(reference!.moduleName, instanceId!), + snapshot: registry!.peek(reference!.moduleName, instanceId!), }; } const snapshot = hydrationIdentity @@ -132,17 +157,7 @@ export const RemoteAppWrapper = forwardRef(function ( ...resProps, }; scheduleBridgeDestroy(() => { - try { - instance?.bridgeHook?.lifecycle?.beforeBridgeDestroy?.emit( - destroyInfo, - ); - provider.destroy({ dom }); - instance?.bridgeHook?.lifecycle?.afterBridgeDestroy?.emit( - destroyInfo, - ); - } catch (error) { - LoggerInstance.error('Bridge remote destroy failed', error); - } + destroyProviderRoot(provider, dom, destroyInfo); }); }; }, [moduleName, providerInfo]); @@ -171,6 +186,21 @@ export const RemoteAppWrapper = forwardRef(function ( if (areRenderInputsEqual(lastRenderInputsRef.current, renderInputs)) return; lastRenderInputsRef.current = renderInputs; + const previousDom = renderDom.current; + if (previousDom && previousDom !== dom) { + // SSR slot <-> CSR mount transitions replace the ref target. Destroy the + // previous provider root before rendering into the new DOM node. + destroyProviderRoot(provider, previousDom, { + moduleName, + dom: previousDom, + basename, + memoryRoute, + fallback, + ...resProps, + }); + } + renderDom.current = dom; + const renderProps = { moduleName, dom, @@ -182,7 +212,6 @@ export const RemoteAppWrapper = forwardRef(function ( signal, ...resProps, }; - renderDom.current = dom; renderQueueRef.current = renderQueueRef.current .then(async () => { @@ -192,12 +221,16 @@ export const RemoteAppWrapper = forwardRef(function ( renderProps, ) || {}, )) as { extraProps?: Record }; + if (signal.aborted || !dom.isConnected) return; const currentRenderProps = { ...renderProps, ...beforeBridgeRenderRes.extraProps, }; await provider.render(currentRenderProps); - if (signal.aborted || !dom.isConnected) return; + if (signal.aborted || !dom.isConnected) { + provider.destroy?.({ dom }); + return; + } if ( snapshot && instanceId && diff --git a/packages/bridge/bridge-shared/src/renderRemoteBridge.ts b/packages/bridge/bridge-shared/src/renderRemoteBridge.ts index 556ad8ba6b8..4bab133046c 100644 --- a/packages/bridge/bridge-shared/src/renderRemoteBridge.ts +++ b/packages/bridge/bridge-shared/src/renderRemoteBridge.ts @@ -43,6 +43,13 @@ export async function renderRemoteBridge

>( ); } + if (options.request.signal.aborted) { + throw new BridgeSSRError( + `Bridge SSR request for ${options.moduleName} was aborted`, + options.request.signal.reason, + ); + } + const exportName = options.export ?? 'default'; const factory = remoteModule[exportName]; if (typeof factory !== 'function') { diff --git a/packages/bridge/bridge-shared/src/ssr.spec.ts b/packages/bridge/bridge-shared/src/ssr.spec.ts index 18feaea2968..b26786a207f 100644 --- a/packages/bridge/bridge-shared/src/ssr.spec.ts +++ b/packages/bridge/bridge-shared/src/ssr.spec.ts @@ -25,6 +25,29 @@ describe('Bridge SSR V1 contract', () => { expect(() => assertBridgeJSONValue({ value: Number.NaN })).toThrow( /finite/, ); + expect(() => + assertBridgeJSONValue(JSON.parse('{"__proto__":{"polluted":true}}')), + ).toThrow(/__proto__/); + }); + + it('treats empty SSR markup as hydration-eligible when markers match', async () => { + const { hasBridgeSSRMarkup, getBridgeSSRContainerAttrs } = + await import('./ssr'); + const attrs = getBridgeSSRContainerAttrs({ + moduleName: 'remote/app', + instanceId: 'remote-1', + }); + const dom = { + getAttribute(name: string) { + return attrs[name] ?? null; + }, + } as HTMLElement; + expect( + hasBridgeSSRMarkup(dom, { + moduleName: 'remote/app', + instanceId: 'remote-1', + }), + ).toBe(true); }); it('validates host-carried results before matching their identity', () => { diff --git a/packages/bridge/bridge-shared/src/ssr.ts b/packages/bridge/bridge-shared/src/ssr.ts index 586f70659a6..9ec952d9759 100644 --- a/packages/bridge/bridge-shared/src/ssr.ts +++ b/packages/bridge/bridge-shared/src/ssr.ts @@ -77,6 +77,11 @@ function validateJSON( for (const [key, descriptor] of Object.entries( Object.getOwnPropertyDescriptors(value), )) { + if (key === '__proto__' || key === 'prototype' || key === 'constructor') { + throw new BridgeSSRError( + `Bridge SSR value at ${path} must not contain ${key}`, + ); + } if ( !descriptor.enumerable || !Object.prototype.hasOwnProperty.call(descriptor, 'value') @@ -287,6 +292,8 @@ export function hasBridgeSSRMarkup( dom: HTMLElement, value?: { moduleName?: string; instanceId?: string }, ) { + // Empty SSR output is still hydration-eligible: trust markers/identity, not + // child presence. Remotes may render null/empty fragments with state only. return ( dom.getAttribute(MF_BRIDGE_SSR_ATTR) === 'true' && dom.getAttribute(MF_BRIDGE_VERSION_ATTR) === @@ -294,8 +301,7 @@ export function hasBridgeSSRMarkup( (!value?.moduleName || dom.getAttribute(MF_BRIDGE_MODULE_ATTR) === value.moduleName) && (!value?.instanceId || - dom.getAttribute(MF_BRIDGE_INSTANCE_ATTR) === value.instanceId) && - dom.hasChildNodes() + dom.getAttribute(MF_BRIDGE_INSTANCE_ATTR) === value.instanceId) ); } @@ -324,16 +330,21 @@ function hydrationError(message: string, cause?: unknown) { return new BridgeSSRError(message, cause); } +function hydrationIdentityKey(moduleName: string, instanceId: string) { + return `${moduleName}\0${instanceId}`; +} + function readSlotSnapshot(slot: HTMLElement): BridgeHydrationSnapshot { - const protocolVersion = Number(slot.getAttribute(MF_BRIDGE_VERSION_ATTR)); + const versionAttr = slot.getAttribute(MF_BRIDGE_VERSION_ATTR); const moduleName = slot.getAttribute(MF_BRIDGE_MODULE_ATTR) || ''; const instanceId = slot.getAttribute(MF_BRIDGE_INSTANCE_ATTR) || ''; assertBridgeSSRIdentity({ moduleName, instanceId }); - if (protocolVersion !== BRIDGE_SSR_PROTOCOL_VERSION) { + if (versionAttr !== String(BRIDGE_SSR_PROTOCOL_VERSION)) { throw hydrationError( - `Bridge SSR slot ${instanceId} uses unsupported protocol version ${protocolVersion}`, + `Bridge SSR slot ${moduleName}:${instanceId} uses unsupported protocol version ${versionAttr}`, ); } + const protocolVersion = BRIDGE_SSR_PROTOCOL_VERSION; const mounts = directChildrenWithAttribute( slot, @@ -429,7 +440,7 @@ export function createBridgeHydrationRegistry( root ?? (typeof document === 'undefined' ? undefined : document); if (!hydrationRoot) { throw hydrationError( - 'createBridgeHydrationRegistry requires a document root on the server', + 'createBridgeHydrationRegistry requires a document root', ); } const snapshots = new Map(); @@ -440,55 +451,58 @@ export function createBridgeHydrationRegistry( `[${MF_BRIDGE_SLOT_ATTR}="true"]`, ), )) { + const moduleName = slot.getAttribute(MF_BRIDGE_MODULE_ATTR) || ''; const instanceId = slot.getAttribute(MF_BRIDGE_INSTANCE_ATTR) || ''; - if (snapshots.has(instanceId) || errors.has(instanceId)) { - snapshots.delete(instanceId); + const key = hydrationIdentityKey(moduleName, instanceId); + if (snapshots.has(key) || errors.has(key)) { + snapshots.delete(key); errors.set( - instanceId, - hydrationError(`Duplicate Bridge SSR instanceId ${instanceId}`), + key, + hydrationError( + `Duplicate Bridge SSR identity ${moduleName}:${instanceId}`, + ), ); continue; } try { const snapshot = readSlotSnapshot(slot); - snapshots.set(snapshot.instanceId, snapshot); + snapshots.set( + hydrationIdentityKey(snapshot.moduleName, snapshot.instanceId), + snapshot, + ); } catch (error) { errors.set( - instanceId, + key, error instanceof BridgeSSRError ? error : hydrationError( - `Unable to read Bridge SSR slot ${instanceId}`, + `Unable to read Bridge SSR slot ${moduleName}:${instanceId}`, error, ), ); } } + const peek = (moduleName: string, instanceId: string) => { + const key = hydrationIdentityKey(moduleName, instanceId); + const error = errors.get(key); + if (error) throw error; + return snapshots.get(key); + }; + return { - peek(moduleName, instanceId) { - const error = errors.get(instanceId); - if (error) throw error; - const snapshot = snapshots.get(instanceId); - if (!snapshot) return undefined; - if (snapshot.moduleName !== moduleName) { - throw hydrationError( - `Bridge SSR instance ${instanceId} belongs to ${snapshot.moduleName}, not ${moduleName}`, - ); - } - return snapshot; - }, + peek, consume(moduleName, instanceId) { - const snapshot = this.peek(moduleName, instanceId); - snapshots.delete(instanceId); - errors.delete(instanceId); + const key = hydrationIdentityKey(moduleName, instanceId); + const snapshot = peek(moduleName, instanceId); + snapshots.delete(key); + errors.delete(key); return snapshot; }, fail(moduleName, instanceId) { - const snapshot = snapshots.get(instanceId); - if (snapshot && snapshot.moduleName !== moduleName) return; - snapshots.delete(instanceId); - errors.delete(instanceId); + const key = hydrationIdentityKey(moduleName, instanceId); + snapshots.delete(key); + errors.delete(key); }, }; } diff --git a/packages/bridge/bridge-shared/src/type.ts b/packages/bridge/bridge-shared/src/type.ts index 65205b4ccba..4e1c86874ea 100644 --- a/packages/bridge/bridge-shared/src/type.ts +++ b/packages/bridge/bridge-shared/src/type.ts @@ -41,6 +41,7 @@ export type BridgeSSRResult = { protocolVersion: typeof BRIDGE_SSR_PROTOCOL_VERSION; moduleName: string; instanceId: string; + /** Trusted remote HTML. Remotes are treated as trusted HTML producers. */ html: string; dehydratedState?: BridgeJSONValue; }; diff --git a/packages/bridge/vue3-bridge/src/provider.spec.ts b/packages/bridge/vue3-bridge/src/provider.spec.ts index 3071d4540d2..0979d3afc28 100644 --- a/packages/bridge/vue3-bridge/src/provider.spec.ts +++ b/packages/bridge/vue3-bridge/src/provider.spec.ts @@ -149,4 +149,38 @@ describe('Vue Bridge server provider', () => { expect(dom.textContent).toBe('updated'); provider.destroy({ dom }); }); + + it('ignores apps created before an aborted client mount', async () => { + const controller = new AbortController(); + const provider = createBridgeComponentWithServerRenderer({ + rootComponent: defineComponent(() => () => h('p', 'remote')), + appOptions: () => { + queueMicrotask(() => controller.abort(new Error('cancelled'))); + return { + router: createRouter({ + history: createMemoryHistory(), + routes: [ + { + path: '/', + component: defineComponent(() => () => h('p')), + }, + ], + }), + }; + }, + })(); + const dom = document.createElement('div'); + document.body.appendChild(dom); + await expect( + provider.render({ + dom, + moduleName: 'vue/remote', + memoryRoute: { entryPath: '/' }, + signal: controller.signal, + }), + ).resolves.toBeUndefined(); + expect( + (dom as HTMLElement & { __vue_app__?: any }).__vue_app__, + ).toBeUndefined(); + }); }); diff --git a/packages/bridge/vue3-bridge/src/provider.ts b/packages/bridge/vue3-bridge/src/provider.ts index 8f33db17afa..2e68ac3e6f7 100644 --- a/packages/bridge/vue3-bridge/src/provider.ts +++ b/packages/bridge/vue3-bridge/src/provider.ts @@ -181,13 +181,22 @@ export function createBridgeComponentWithServerRenderer( roots.delete(dom); } const reactiveProps = Vue.shallowReactive(nextProps); - const { app } = await setupBridgeApp( - bridgeInfo, - { basename, memoryRoute, hashRoute, instanceId, signal }, - reactiveProps, - shouldHydrate ? 'hydrate' : 'csr', - ); - if (signal?.aborted) return; + let app: Vue.App | undefined; + try { + ({ app } = await setupBridgeApp( + bridgeInfo, + { basename, memoryRoute, hashRoute, instanceId, signal }, + reactiveProps, + shouldHydrate ? 'hydrate' : 'csr', + )); + } catch (error) { + if (signal?.aborted) return; + throw error; + } + if (signal?.aborted) { + // Never mounted: drop the request-local app without unmount warnings. + return; + } app.mount(dom, shouldHydrate); if (signal?.aborted || !dom.isConnected) { app.unmount(); @@ -211,6 +220,7 @@ export function createBridgeComponentWithServerRenderer( provider.renderServer = async (context) => { if (context.signal.aborted) throw context.signal.reason; const preparedValue = await config?.prepare?.(context); + if (context.signal.aborted) throw context.signal.reason; const prepared = (preparedValue || {}) as BridgeSSRPrepareResult< Record >; @@ -235,6 +245,7 @@ export function createBridgeComponentWithServerRenderer( applicationProps, 'ssr', ); + if (context.signal.aborted) throw context.signal.reason; const ssrContext: Record = {}; const html = await serverRenderer(app, ssrContext); if (context.signal.aborted) throw context.signal.reason; diff --git a/packages/bridge/vue3-bridge/src/remoteApp.tsx b/packages/bridge/vue3-bridge/src/remoteApp.tsx index e5b2094c044..7a3fc5e5451 100644 --- a/packages/bridge/vue3-bridge/src/remoteApp.tsx +++ b/packages/bridge/vue3-bridge/src/remoteApp.tsx @@ -69,14 +69,19 @@ export default defineComponent({ ? (ssrPayload as BridgeSSRReference) : undefined; const registry = useBridgeHydrationRegistry(); + if (reference && !registry) { + throw new Error( + 'Bridge SSR references require provideBridgeHydrationRegistry before mount', + ); + } const snapshot = reference && instanceId - ? registry?.peek(reference.moduleName, instanceId) + ? registry!.peek(reference.moduleName, instanceId) : undefined; const hasSSRPayload = Boolean((serverPayload || snapshot) && instanceId); const getBridgeRenderProps = () => ({ - name: props.moduleName, + moduleName: props.moduleName, dom: rootRef.value, basename: props.basename, memoryRoute: props.memoryRoute, @@ -128,9 +133,12 @@ export default defineComponent({ wasDeactivated.value || !dom.isConnected ) { - providerReturn.destroy?.({ dom }); + // Only destroy if this provider is still the active one. A newer + // providerInfo watch may already have destroyed and replaced it. if (providerInfoRef.value === providerReturn) { + providerReturn.destroy?.({ dom }); providerInfoRef.value = null; + isRendered.value = false; } return; } @@ -158,7 +166,9 @@ export default defineComponent({ const destroyComponent = () => { const providerReturn = providerInfoRef.value as any; - if (!providerReturn || !isRendered.value) { + // Destroy whenever a provider was obtained. A failed/aborted render may + // still have mounted an app before rejecting, so do not gate on isRendered. + if (!providerReturn) { return; } LoggerInstance.debug( From 8813e9704e0a71b29e0ef2e443f3c9ccf7b02204 Mon Sep 17 00:00:00 2001 From: Kevin Beier Date: Sat, 18 Jul 2026 22:42:44 +0200 Subject: [PATCH 37/37] fix(bridge): invalidate unconsumed SSR hydration snapshots Claim registry snapshots before provider.render and fail them on cancel so SPA revisits cannot hydrate stale request-time state. KeepAlive reactivation falls back to CSR, and demo hosts stop re-seeding SSR refs after navigation. Co-authored-by: Cursor --- .husky/commit-msg | 3 +- apps/bridge-ssr-demo/host-vue/src/App.vue | 15 +- .../host/src/lib/useHostSsrContext.ts | 24 +- .../bridge-react/src/hydration.spec.tsx | 9 + .../src/remote/RemoteAppWrapper.spec.tsx | 120 ++++++++++ .../src/remote/RemoteAppWrapper.tsx | 67 +++++- .../__tests__/remoteApp.ssr.test.ts | 221 ++++++++++++++++++ packages/bridge/vue3-bridge/src/remoteApp.tsx | 83 +++++-- 8 files changed, 508 insertions(+), 34 deletions(-) create mode 100644 packages/bridge/vue3-bridge/__tests__/remoteApp.ssr.test.ts diff --git a/.husky/commit-msg b/.husky/commit-msg index 693dbea0ca6..087d40d63ce 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,5 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" - -pnpm run commitlint ${1} +pnpm run commitlint --edit "${1}" diff --git a/apps/bridge-ssr-demo/host-vue/src/App.vue b/apps/bridge-ssr-demo/host-vue/src/App.vue index aaa0d334d81..7df3e1cc223 100644 --- a/apps/bridge-ssr-demo/host-vue/src/App.vue +++ b/apps/bridge-ssr-demo/host-vue/src/App.vue @@ -1,5 +1,5 @@ diff --git a/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts b/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts index 89873221f46..14f955c61ed 100644 --- a/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts +++ b/apps/bridge-ssr-demo/host/src/lib/useHostSsrContext.ts @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import { useMemo, useRef } from 'react'; import { useLocation } from 'react-router-dom'; import { readHostSSRContextFromDocument } from './hostSsrContext'; import { resolveHostSsrContextForLocation } from './remoteRoutes'; @@ -8,20 +8,36 @@ function getLocationUrl(pathname: string, search: string) { return `${pathname}${search}`; } +function seedPathname(context?: HostSSRContext) { + return context?.url?.split('?')[0]?.split('#')[0]; +} + /** * Nuxt-style SSR takeover: * - Direct visit / hard refresh: use SSR payload embedded in the document (or passed from server render). * - Client-side navigations: no document reload; remotes mount via federated CSR + bridge hydrate. + * + * After the user navigates away from the seeded path, never re-attach the + * document SSR reference — even if they return to the same URL. */ export function useHostSsrContext(initialContext?: HostSSRContext) { const location = useLocation(); const locationUrl = getLocationUrl(location.pathname, location.search); const documentContext = useMemo(() => readHostSSRContextFromDocument(), []); + const seedPathRef = useRef( + seedPathname(initialContext) ?? seedPathname(documentContext), + ); + const seedConsumedRef = useRef(false); + + if (seedPathRef.current && location.pathname !== seedPathRef.current) { + seedConsumedRef.current = true; + } - const seedContext = - initialContext?.url?.split('?')[0]?.split('#')[0] === location.pathname + const seedContext = seedConsumedRef.current + ? undefined + : seedPathname(initialContext) === location.pathname ? initialContext - : documentContext?.url?.split('?')[0]?.split('#')[0] === location.pathname + : seedPathname(documentContext) === location.pathname ? documentContext : undefined; diff --git a/packages/bridge/bridge-react/src/hydration.spec.tsx b/packages/bridge/bridge-react/src/hydration.spec.tsx index 4154aad18f8..d12b97a35a4 100644 --- a/packages/bridge/bridge-react/src/hydration.spec.tsx +++ b/packages/bridge/bridge-react/src/hydration.spec.tsx @@ -135,4 +135,13 @@ describe('Bridge hydration registry', () => { '

other remote

', ); }); + + it('fail clears a peeked snapshot so later peeks miss', () => { + installSlot(); + const registry = createBridgeHydrationRegistry(document); + expect(registry.peek('remote/app', 'remote-1')).toBeDefined(); + registry.fail('remote/app', 'remote-1'); + expect(registry.peek('remote/app', 'remote-1')).toBeUndefined(); + expect(registry.consume('remote/app', 'remote-1')).toBeUndefined(); + }); }); diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx index 9fa426e84ab..00795890271 100644 --- a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.spec.tsx @@ -2,8 +2,13 @@ import React, { createRef } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { act, render, waitFor } from '@testing-library/react'; import { afterEach, describe, expect, it, rs } from '@rstest/core'; +import { + createBridgeHydrationRegistry, + toBridgeSSRReference, +} from '@module-federation/bridge-shared'; import { RemoteAppWrapper } from './RemoteAppWrapper'; import { ErrorBoundary } from '../error-boundary'; +import { BridgeHydrationProvider, BridgeRemoteSlot } from '../hydration'; const baseProps = { moduleName: 'remote/app', @@ -62,6 +67,7 @@ describe('RemoteAppWrapper SSR payload boundary', () => { describe('RemoteAppWrapper lifecycle', () => { afterEach(() => { rs.restoreAllMocks(); + document.body.innerHTML = ''; }); it('supports changing between object, callback, and absent forwarded refs', async () => { @@ -153,4 +159,118 @@ describe('RemoteAppWrapper lifecycle', () => { await act(async () => queued[0]()); expect(provider.destroy).toHaveBeenCalledOnce(); }); + + it('claims the registry snapshot before render and clears it on cancel', async () => { + const queued: Array<() => void> = []; + rs.spyOn(globalThis, 'queueMicrotask').mockImplementation((callback) => { + queued.push(callback as () => void); + }); + + const result = { + protocolVersion: 1 as const, + moduleName: 'remote/app', + instanceId: 'remote-1', + html: '

server remote

', + dehydratedState: { ready: true }, + }; + document.body.innerHTML = renderToStaticMarkup( + , + ); + const registry = createBridgeHydrationRegistry(document); + let finishRender!: () => void; + const provider = { + render: rs.fn( + () => + new Promise((resolve) => { + finishRender = resolve; + }), + ), + destroy: rs.fn(), + }; + + const view = render( + + provider} + /> + , + ); + + await waitFor(() => expect(provider.render).toHaveBeenCalledOnce()); + expect(registry.peek('remote/app', 'remote-1')).toBeUndefined(); + expect( + (provider.render.mock.calls[0] as unknown as [{ ssrState?: unknown }])[0] + .ssrState, + ).toEqual({ ready: true }); + + view.unmount(); + finishRender(); + for (const task of queued.splice(0)) { + await act(async () => task()); + } + expect(registry.peek('remote/app', 'remote-1')).toBeUndefined(); + }); + + it('forces CSR when a second consumer loses the snapshot claim', async () => { + const result = { + protocolVersion: 1 as const, + moduleName: 'remote/app', + instanceId: 'remote-1', + html: '

server remote

', + dehydratedState: { ready: true }, + }; + document.body.innerHTML = renderToStaticMarkup( + , + ); + const registry = createBridgeHydrationRegistry(document); + const first = { + render: rs.fn((info: { ssrState?: unknown }) => info), + destroy: rs.fn(), + }; + const second = { + render: rs.fn((info: { ssrState?: unknown }) => info), + destroy: rs.fn(), + }; + + render( + + first} + /> + second} + /> + , + ); + + await waitFor(() => expect(first.render).toHaveBeenCalledOnce()); + await waitFor(() => expect(second.render).toHaveBeenCalledOnce()); + + const states = [first, second].map((provider) => { + const call = provider.render.mock.calls[0] as unknown as [ + { ssrState?: { ready?: boolean } }, + ]; + return call[0].ssrState; + }); + expect(states.filter((state) => state?.ready === true)).toHaveLength(1); + expect(states.filter((state) => state === undefined)).toHaveLength(1); + }); }); diff --git a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx index 047f99fc6a0..0ce4293fae5 100644 --- a/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx +++ b/packages/bridge/bridge-react/src/remote/RemoteAppWrapper.tsx @@ -16,6 +16,11 @@ import type { RemoteAppSSRProps } from '../types'; import { BridgeSSRError, getMatchingBridgeSSRPayload, + MF_BRIDGE_INSTANCE_ATTR, + MF_BRIDGE_MODULE_ATTR, + MF_BRIDGE_MOUNT_ATTR, + MF_BRIDGE_SSR_ATTR, + MF_BRIDGE_VERSION_ATTR, type BridgeSSRReference, type BridgeSSRResult, } from '@module-federation/bridge-shared'; @@ -36,6 +41,14 @@ function scheduleBridgeDestroy(destroy: () => void) { else void Promise.resolve().then(destroy); } +function clearBridgeSSRMountAttrs(dom: HTMLElement) { + dom.removeAttribute(MF_BRIDGE_SSR_ATTR); + dom.removeAttribute(MF_BRIDGE_MOUNT_ATTR); + dom.removeAttribute(MF_BRIDGE_VERSION_ATTR); + dom.removeAttribute(MF_BRIDGE_MODULE_ATTR); + dom.removeAttribute(MF_BRIDGE_INSTANCE_ATTR); +} + function destroyProviderRoot( provider: { destroy?: (info: { dom: HTMLElement }) => void } | null, dom: HTMLElement | null, @@ -136,16 +149,26 @@ export const RemoteAppWrapper = forwardRef(function ( mountControllerRef.current = new AbortController(); setProviderReady(true); } catch (error) { - if (snapshot && instanceId) registry?.fail(moduleName, instanceId); + if (snapshot && instanceId) + registry?.fail(reference?.moduleName || moduleName, instanceId); setRenderError(error); } return () => { const provider = providerInfoRef.current; const dom = renderDom.current; + const releaseUnclaimedSnapshot = + Boolean(snapshot && instanceId) && + consumedIdentityRef.current !== hydrationIdentity; mountControllerRef.current?.abort(); providerInfoRef.current = null; mountControllerRef.current = null; + // Drop unclaimed snapshots synchronously so a fast SPA remount cannot + // peek the same identity. StrictMode remounts keep the peeked snapshot in + // this instance's ref and can still hydrate after a lost registry claim. + if (releaseUnclaimedSnapshot) { + registry?.fail(reference?.moduleName || moduleName, instanceId!); + } if (!provider?.destroy || !dom || destroyedRef.current) return; destroyedRef.current = true; const destroyInfo = { @@ -201,6 +224,30 @@ export const RemoteAppWrapper = forwardRef(function ( } renderDom.current = dom; + // Claim the registry snapshot before any await so a cancelled mount cannot + // leave it peekable for a later SPA visit. This instance may still hydrate + // from the peeked snapshot object after a StrictMode remount. + let ssrState = serverPayload?.dehydratedState; + if (snapshot && instanceId && registry) { + if (consumedIdentityRef.current !== hydrationIdentity) { + const claimed = registry.consume( + reference?.moduleName || moduleName, + instanceId, + ); + if (Object.is(claimed, snapshot)) { + consumedIdentityRef.current = hydrationIdentity; + ssrState = snapshot.state; + } else { + // Another consumer already claimed this identity — force CSR. + consumedIdentityRef.current = hydrationIdentity; + ssrState = undefined; + clearBridgeSSRMountAttrs(dom); + } + } else { + ssrState = snapshot.state; + } + } + const renderProps = { moduleName, dom, @@ -208,7 +255,7 @@ export const RemoteAppWrapper = forwardRef(function ( memoryRoute, fallback, instanceId, - ssrState: serverPayload?.dehydratedState ?? snapshot?.state, + ssrState, signal, ...resProps, }; @@ -231,22 +278,18 @@ export const RemoteAppWrapper = forwardRef(function ( provider.destroy?.({ dom }); return; } - if ( - snapshot && - instanceId && - consumedIdentityRef.current !== hydrationIdentity - ) { - registry?.consume(moduleName, instanceId); - consumedIdentityRef.current = hydrationIdentity; - } instance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit( currentRenderProps, ); }) .catch((error) => { if (signal.aborted) return; - if (snapshot && instanceId) { - registry?.fail(moduleName, instanceId); + if ( + snapshot && + instanceId && + consumedIdentityRef.current !== hydrationIdentity + ) { + registry?.fail(reference?.moduleName || moduleName, instanceId); } setRenderError(error); }); diff --git a/packages/bridge/vue3-bridge/__tests__/remoteApp.ssr.test.ts b/packages/bridge/vue3-bridge/__tests__/remoteApp.ssr.test.ts new file mode 100644 index 00000000000..7c7b5368351 --- /dev/null +++ b/packages/bridge/vue3-bridge/__tests__/remoteApp.ssr.test.ts @@ -0,0 +1,221 @@ +import { afterEach, beforeEach, describe, expect, it, rs } from '@rstest/core'; +import { createApp, defineComponent, h, KeepAlive, nextTick } from 'vue'; +import { createMemoryHistory, createRouter, RouterView } from 'vue-router'; +import { + BRIDGE_SSR_PROTOCOL_VERSION, + createBridgeHydrationRegistry, + MF_BRIDGE_SSR_ATTR, + toBridgeSSRReference, +} from '@module-federation/bridge-shared'; +import RemoteApp from '../src/remoteApp'; +import { provideBridgeHydrationRegistry } from '../src/hydration'; + +rs.mock('@module-federation/runtime', () => ({ + getInstance: () => ({ + bridgeHook: { + lifecycle: { + beforeBridgeRender: { emit: rs.fn(async () => ({})) }, + afterBridgeRender: { emit: rs.fn() }, + beforeBridgeDestroy: { emit: rs.fn() }, + afterBridgeDestroy: { emit: rs.fn() }, + }, + }, + }), +})); + +const flushBridgeRender = async () => { + await nextTick(); + await Promise.resolve(); + await nextTick(); +}; + +const installSlot = () => { + document.body.innerHTML = + '
' + + '

server remote

' + + '' + + '
'; +}; + +describe('RemoteApp SSR lifecycle', () => { + let root: HTMLDivElement; + + beforeEach(() => { + document.body.innerHTML = ''; + root = document.createElement('div'); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + const mountApp = (app: ReturnType) => { + document.body.appendChild(root); + app.mount(root); + }; + + it('claims the registry snapshot before provider render', async () => { + const result = { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: 'ecApp', + instanceId: 'ec:1', + html: '

server remote

', + dehydratedState: { ready: true }, + }; + installSlot(); + const registry = createBridgeHydrationRegistry(document); + expect(registry.peek('ecApp', 'ec:1')).toBeDefined(); + + const providerReturn = { + render: rs.fn(), + destroy: rs.fn(), + }; + const App = defineComponent({ + setup: () => () => + h(RemoteApp, { + moduleName: 'ecApp', + instanceId: 'ec:1', + ssr: toBridgeSSRReference(result), + providerInfo: () => providerReturn, + }), + }); + const app = createApp(App); + provideBridgeHydrationRegistry(app, registry); + // RemoteApp calls useRoute(); give it a router even for the non-route case. + const router = createRouter({ + history: createMemoryHistory(), + routes: [{ path: '/', component: { template: '
' } }], + }); + app.use(router); + await router.isReady(); + mountApp(app); + await flushBridgeRender(); + + expect(providerReturn.render).toHaveBeenCalledTimes(1); + expect(providerReturn.render.mock.calls[0][0].ssrState).toEqual({ + ready: true, + }); + expect(registry.peek('ecApp', 'ec:1')).toBeUndefined(); + app.unmount(); + }); + + it('claims SSR once under KeepAlive and reactivates through CSR', async () => { + const result = { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: 'ecApp', + instanceId: 'ec:1', + html: '

server remote

', + dehydratedState: { ready: true }, + }; + installSlot(); + const registry = createBridgeHydrationRegistry(document); + const providerReturn = { + render: rs.fn(), + destroy: rs.fn(), + }; + const RemoteRoute = defineComponent({ + setup() { + return () => + h(RemoteApp, { + moduleName: 'ecApp', + basename: '/ec', + instanceId: 'ec:1', + ssr: toBridgeSSRReference(result), + providerInfo: () => providerReturn, + }); + }, + }); + + const router = createRouter({ + history: createMemoryHistory(), + routes: [ + { path: '/', component: { template: '
home
' } }, + { path: '/ec/:pathMatch(.*)*', component: RemoteRoute }, + ], + }); + + const App = defineComponent({ + setup() { + return () => + h(RouterView, null, { + default: ({ Component }) => + h(KeepAlive, null, () => (Component ? h(Component) : null)), + }); + }, + }); + + const app = createApp(App); + provideBridgeHydrationRegistry(app, registry); + app.use(router); + + await router.push('/ec'); + await router.isReady(); + mountApp(app); + await flushBridgeRender(); + + expect(providerReturn.render).toHaveBeenCalledTimes(1); + expect(providerReturn.render.mock.calls[0][0].ssrState).toEqual({ + ready: true, + }); + expect(registry.peek('ecApp', 'ec:1')).toBeUndefined(); + + await router.push('/'); + await flushBridgeRender(); + expect(providerReturn.destroy).toHaveBeenCalledTimes(1); + + await router.push('/ec'); + await flushBridgeRender(); + expect(providerReturn.render).toHaveBeenCalledTimes(2); + expect(providerReturn.render.mock.calls[1][0].ssrState).toBeUndefined(); + const remountDom = providerReturn.render.mock.calls[1][0] + .dom as HTMLElement; + expect(remountDom.getAttribute(MF_BRIDGE_SSR_ATTR)).toBeNull(); + + app.unmount(); + }); + + it('releases an unclaimed SSR snapshot when unmounted before render settles', async () => { + const result = { + protocolVersion: BRIDGE_SSR_PROTOCOL_VERSION, + moduleName: 'ecApp', + instanceId: 'ec:1', + html: '

server remote

', + dehydratedState: { ready: true }, + }; + installSlot(); + const registry = createBridgeHydrationRegistry(document); + expect(registry.peek('ecApp', 'ec:1')).toBeDefined(); + + const providerReturn = { + render: rs.fn( + () => + new Promise(() => { + /* never settles */ + }), + ), + destroy: rs.fn(), + }; + const App = defineComponent({ + setup: () => () => + h(RemoteApp, { + moduleName: 'ecApp', + instanceId: 'ec:1', + ssr: toBridgeSSRReference(result), + providerInfo: () => providerReturn, + }), + }); + const app = createApp(App); + provideBridgeHydrationRegistry(app, registry); + const router = createRouter({ + history: createMemoryHistory(), + routes: [{ path: '/', component: { template: '
' } }], + }); + app.use(router); + await router.isReady(); + mountApp(app); + // Unmount before the render queue microtask claims the snapshot. + app.unmount(); + await flushBridgeRender(); + expect(registry.peek('ecApp', 'ec:1')).toBeUndefined(); + }); +}); diff --git a/packages/bridge/vue3-bridge/src/remoteApp.tsx b/packages/bridge/vue3-bridge/src/remoteApp.tsx index 7a3fc5e5451..63660c01c24 100644 --- a/packages/bridge/vue3-bridge/src/remoteApp.tsx +++ b/packages/bridge/vue3-bridge/src/remoteApp.tsx @@ -17,6 +17,11 @@ import { getBridgeSSRContainerAttrs, getBridgeSSRSlotAttrs, getMatchingBridgeSSRPayload, + MF_BRIDGE_INSTANCE_ATTR, + MF_BRIDGE_MODULE_ATTR, + MF_BRIDGE_MOUNT_ATTR, + MF_BRIDGE_SSR_ATTR, + MF_BRIDGE_VERSION_ATTR, serializeBridgeSSRStateEnvelope, type BridgeSSRReference, type BridgeSSRResult, @@ -26,6 +31,14 @@ import { LoggerInstance } from './utils'; import { getInstance } from '@module-federation/runtime'; import { useBridgeHydrationRegistry } from './hydration'; +function clearBridgeSSRMountAttrs(dom: HTMLElement) { + dom.removeAttribute(MF_BRIDGE_SSR_ATTR); + dom.removeAttribute(MF_BRIDGE_MOUNT_ATTR); + dom.removeAttribute(MF_BRIDGE_VERSION_ATTR); + dom.removeAttribute(MF_BRIDGE_MODULE_ATTR); + dom.removeAttribute(MF_BRIDGE_INSTANCE_ATTR); +} + export default defineComponent({ name: 'RemoteApp', props: { @@ -50,6 +63,8 @@ export default defineComponent({ const controller = new AbortController(); let renderQueue = Promise.resolve(); let consumedSnapshot = false; + let hydratedOnce = false; + let csrOnly = false; let providerGeneration = 0; const route = useRoute(); const hostInstance = getInstance(); @@ -79,6 +94,14 @@ export default defineComponent({ ? registry!.peek(reference.moduleName, instanceId) : undefined; const hasSSRPayload = Boolean((serverPayload || snapshot) && instanceId); + const registryModuleName = + props.moduleName || reference?.moduleName || ssrPayload?.moduleName || ''; + + const releaseUnclaimedSnapshot = () => { + if (!snapshot || !instanceId || consumedSnapshot || !registry) return; + registry.fail(registryModuleName, instanceId); + consumedSnapshot = true; + }; const getBridgeRenderProps = () => ({ moduleName: props.moduleName, @@ -103,6 +126,33 @@ export default defineComponent({ const providerReturn = providerInfoRef.value || props.providerInfo?.(); providerInfoRef.value = providerReturn; const wasRendered = isRendered.value; + + // Claim before any await so cancel cannot leave a peekable snapshot. + // After a claim (even if render aborts), never hydrate again — CSR only. + let ssrState = + wasRendered || hydratedOnce || consumedSnapshot + ? undefined + : serverPayload?.dehydratedState; + if ( + !wasRendered && + !hydratedOnce && + !consumedSnapshot && + snapshot && + instanceId && + registry + ) { + const claimed = registry.consume(registryModuleName, instanceId); + if (Object.is(claimed, snapshot)) { + consumedSnapshot = true; + ssrState = snapshot.state; + } else { + consumedSnapshot = true; + hydratedOnce = true; + ssrState = undefined; + clearBridgeSSRMountAttrs(dom); + } + } + let renderProps = { ...componentAttrs, moduleName: props.moduleName, @@ -111,9 +161,7 @@ export default defineComponent({ memoryRoute: props.memoryRoute, hashRoute: props.hashRoute, instanceId, - ssrState: wasRendered - ? undefined - : (serverPayload?.dehydratedState ?? snapshot?.state), + ssrState, signal: controller.signal, }; LoggerInstance.debug( @@ -143,12 +191,10 @@ export default defineComponent({ return; } isRendered.value = true; - if (!consumedSnapshot && snapshot && instanceId) { - registry?.consume( - props.moduleName || reference!.moduleName, - instanceId, - ); - consumedSnapshot = true; + // One-shot hydrate for this instance. Keep SSR markers in the DOM so + // hosts/tests can observe them; strip only on KeepAlive deactivate. + if (snapshot || serverPayload) { + hydratedOnce = true; } hostInstance?.bridgeHook?.lifecycle?.afterBridgeRender?.emit( renderProps, @@ -156,8 +202,9 @@ export default defineComponent({ }); renderQueue = pending.catch((error) => { if (controller.signal.aborted || wasDeactivated.value) return; - if (snapshot && instanceId) { - registry?.fail(props.moduleName || reference!.moduleName, instanceId); + if (snapshot && instanceId && !consumedSnapshot) { + registry?.fail(registryModuleName, instanceId); + consumedSnapshot = true; } renderError.value = error; }); @@ -264,12 +311,18 @@ export default defineComponent({ onDeactivated(() => { isActive.value = false; wasDeactivated.value = true; + releaseUnclaimedSnapshot(); + if (consumedSnapshot) hydratedOnce = true; + csrOnly = true; + const dom = rootRef.value as HTMLElement | null; + if (dom) clearBridgeSSRMountAttrs(dom); destroyComponent(); }); onBeforeUnmount(() => { controller.abort(); watchStopHandle(); + releaseUnclaimedSnapshot(); destroyComponent(); }); @@ -278,17 +331,19 @@ export default defineComponent({ const mount = (
); - if (!hasSSRPayload || !instanceId) return mount; + if (!hasSSRPayload || !instanceId || csrOnly) return mount; const moduleName = props.moduleName || ssrPayload!.moduleName; return (