diff --git a/.changeset/beige-pears-jog.md b/.changeset/beige-pears-jog.md
new file mode 100644
index 000000000000..68f9d0846350
--- /dev/null
+++ b/.changeset/beige-pears-jog.md
@@ -0,0 +1,5 @@
+---
+'@modern-js/plugin-garfish': patch
+---
+
+fix(plugin-garfish): basename calculation polish
diff --git a/packages/document/main-doc/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx b/packages/document/main-doc/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx
index ac05269681b2..f46e8b40877f 100644
--- a/packages/document/main-doc/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx
+++ b/packages/document/main-doc/docs/en/guides/topic-detail/micro-frontend/c02-development.mdx
@@ -151,8 +151,9 @@ import { Tab, Tabs } from 'rspress/theme';
```tsx
import { useLocation, useHref } from 'react-router-dom';
const App = () => {
+ const basename = useHref('/table');
const { Table } = useModuleApps();
- return
;
+ return ;
};
```
@@ -160,16 +161,8 @@ const App = () => {
```tsx
import { useLocation, useHistory } from 'react-router-dom';
const App = () => {
- const { Table } = useModuleApps();
- return ;
-};
-```
-
-
-```tsx
-import { useLocation, useHref } from 'react-router-dom';
-const App = () => {
- const basename = useHref('/table');
+ const history = useHistory();
+ const basename = history.createHref({ pathname: '/table' });
const { Table } = useModuleApps();
return ;
};
diff --git a/packages/document/main-doc/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx b/packages/document/main-doc/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx
index 4a3b7f5ccc96..bca453bf839d 100644
--- a/packages/document/main-doc/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx
+++ b/packages/document/main-doc/docs/zh/guides/topic-detail/micro-frontend/c02-development.mdx
@@ -155,8 +155,9 @@ import { Tab, Tabs } from 'rspress/theme';
```tsx
import { useLocation, useHref } from 'react-router-dom';
const App = () => {
+ const basename = useHref('/table');
const { Table } = useModuleApps();
- return ;
+ return ;
};
```
@@ -164,16 +165,8 @@ const App = () => {
```tsx
import { useLocation, useHistory } from 'react-router-dom';
const App = () => {
- const { Table } = useModuleApps();
- return ;
-};
-```
-
-
-```tsx
-import { useLocation, useHref } from 'react-router-dom';
-const App = () => {
- const basename = useHref('/table');
+ const history = useHistory();
+ const basename = history.createHref({ pathname: '/table' });
const { Table } = useModuleApps();
return ;
};
diff --git a/packages/runtime/plugin-garfish/src/runtime/loadable.tsx b/packages/runtime/plugin-garfish/src/runtime/loadable.tsx
index d4165e883b76..2dad2ea7c07a 100644
--- a/packages/runtime/plugin-garfish/src/runtime/loadable.tsx
+++ b/packages/runtime/plugin-garfish/src/runtime/loadable.tsx
@@ -20,9 +20,11 @@ export interface MicroProps {
[key: string]: any;
// just for type hint to users
- useHref?: any;
useLocation?: any;
+ useHref?: any;
useHistory?: any;
+ useRouteMatch?: any;
+ useMatches?: any;
}
const DEFAULT_LOADABLE = {
diff --git a/packages/runtime/plugin-garfish/src/runtime/utils/apps.tsx b/packages/runtime/plugin-garfish/src/runtime/utils/apps.tsx
index 09454fc23a85..063df39eb9ec 100644
--- a/packages/runtime/plugin-garfish/src/runtime/utils/apps.tsx
+++ b/packages/runtime/plugin-garfish/src/runtime/utils/apps.tsx
@@ -48,11 +48,14 @@ function getAppInstance(
React.ComponentType | undefined
>();
const context = useContext(RuntimeReactContext);
-
+ const useRouteMatch = props.useRouteMatch ?? context?.router?.useRouteMatch;
+ const useMatches = props.useMatches ?? context?.router?.useMatches;
const useLocation = props.useLocation ?? context?.router?.useLocation;
- const useHref = props.useHref ?? context?.router?.useHref;
const useHistory = props.useHistory ?? context?.router?.useHistory;
- const isRouterV5 = Boolean(useHistory);
+ const useHref = props.useHistory ?? context?.router?.useHref;
+
+ const match = useRouteMatch?.();
+ const matchs = useMatches?.();
if (!useLocation) {
console.warn(
@@ -68,37 +71,51 @@ or directly pass the "basename":
`,
);
}
- const location = useLocation();
- let basename = '';
- const activeWhen = appInfo.activeWhen as string;
+ const location = useLocation();
- // 1. options.basename in edenx.config.ts
/**
- * e.g:
- masterApp: {
- basename: '/main-app-basename'
- },
+ * main-app basename: /main-basename
+ * sub-app basename: /main-basename/sub-active-path
*/
- if (options?.basename && typeof options.basename === 'string') {
- basename = pathJoin(options.basename, activeWhen);
- }
- // 2. use hooks to calculate the basename automatically
- if (isRouterV5) {
+ // 1. handle the main-app basename
+ /**
+ * `options?.basename` comes from
+ * masterApp: {
+ * basename: '/main-app-basename'
+ * },
+ */
+ let basename = options?.basename || '/';
+ if (useHistory /* react-router@5 */) {
// there is no dynamic switching of the router version in the project
// so hooks can be used in conditional judgment
// eslint-disable-next-line react-hooks/rules-of-hooks
const history = useHistory?.();
// To be compatible to history@4.10.1 and @5.3.0 we cannot write like this `history.createHref(pathname)`
- basename = history?.createHref?.({ pathname: activeWhen });
- } else if (useHref) {
+ basename = history?.createHref?.({ pathname: '/' });
+ } else if (useHref /* react-router@6 */) {
// eslint-disable-next-line react-hooks/rules-of-hooks
- basename = useHref?.(activeWhen);
+ basename = useHref?.('/');
+ }
+
+ // 2. handle the subActivePath and `pathJoin(mainBasename, subActivePath)`
+ if (matchs && matchs.length > 0 /* react-router@6 */) {
+ const matchItem = {
+ ...matchs[matchs.length - 1],
+ };
+ for (const key in matchItem.params) {
+ matchItem.pathname = matchItem.pathname.replace(
+ new RegExp(`/${matchItem.params[key]}$`),
+ '',
+ );
+ }
+ basename = pathJoin(basename, matchItem.pathname || '/');
+ } else if (match /* react-router@5 */) {
+ basename = pathJoin(basename, match?.path || '/');
}
- // 3. props.basename
- // props.basename has the highest priority
+ // 3. props.basename has the highest priority
// e.g:
if (props.basename && typeof props.basename === 'string') {
// eslint-disable-next-line prefer-destructuring
diff --git a/packages/runtime/plugin-garfish/tests/index.test.tsx b/packages/runtime/plugin-garfish/tests/index.test.tsx
index 18b3a91d0bee..5d29c4a84d6a 100644
--- a/packages/runtime/plugin-garfish/tests/index.test.tsx
+++ b/packages/runtime/plugin-garfish/tests/index.test.tsx
@@ -14,6 +14,7 @@ import {
useHistory,
BrowserRouter,
MemoryRouter,
+ useRouteMatch,
} from '@modern-js/plugin-router-v5/runtime';
import garfishPlugin from '../src/runtime';
import { useModuleApps } from '../src';
@@ -185,7 +186,7 @@ describe('plugin-garfish', () => {
unmount();
});
- test('useModuleApps hook should set basename for sub-app automatically by createHref', async () => {
+ test('useModuleApps hook should set basename for sub-app by props.basename', async () => {
const basenameTest = {
name: 'BasenameTest',
activeWhen: '/basename-test',
@@ -240,7 +241,7 @@ describe('plugin-garfish', () => {
@@ -258,17 +259,14 @@ describe('plugin-garfish', () => {
render(, {});
});
- // expect(screen.getByTestId('home-title')).not.toBeInTheDocument();
-
expect(
- await screen.findByText('sub-app basename: /main-app/basename-test'),
+ await screen.findByText('sub-app basename: /main-app/basename-props-has-highest-priority'),
).toBeInTheDocument();
});
- test('useModuleApps sub-app basename can be set by user defineConfig masterApp.apps options', async () => {
+ test('useModuleApps should set basename for sub-app based on last RouterMatch when no activeWhen', async () => {
const basenameTest = {
name: 'BasenameTest',
- activeWhen: '/basename-appInfo-options',
entry: basenameTestPath,
// Each test does not affect with each other.
@@ -286,7 +284,7 @@ describe('plugin-garfish', () => {
},
basename: '/main-app',
};
- window.location.assign('/main-app/basename-appInfo-options/some-test');
+ window.location.assign('/main-app/no-active-when/some-test');
const App = () => {
const { BasenameTest } = useModuleApps();
@@ -297,7 +295,14 @@ describe('plugin-garfish', () => {
return (
-
+
+
+
+
+
);
@@ -311,9 +316,7 @@ describe('plugin-garfish', () => {
});
expect(
- await screen.findByText(
- 'sub-app basename: /main-app/basename-appInfo-options',
- ),
+ await screen.findByText('sub-app basename: /main-app/no-active-when'),
).toBeInTheDocument();
});
});