Skip to content

Commit

Permalink
fix(plugin-garfish): basename calculation polish (#5346)
Browse files Browse the repository at this point in the history
  • Loading branch information
SoonIter authored Jan 31, 2024
1 parent f1d333c commit 29e297f
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-pears-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modern-js/plugin-garfish': patch
---

fix(plugin-garfish): basename calculation polish
Original file line number Diff line number Diff line change
Expand Up @@ -151,25 +151,18 @@ import { Tab, Tabs } from 'rspress/theme';
```tsx
import { useLocation, useHref } from 'react-router-dom';
const App = () => {
const basename = useHref('/table');
const { Table } = useModuleApps();
return <Table useLocation={useLocation} useHref={useHref} />;
return <Table useLocation={useLocation} basename={basename} />;
};
```
</Tab>
<Tab label="react-router-dom@5">
```tsx
import { useLocation, useHistory } from 'react-router-dom';
const App = () => {
const { Table } = useModuleApps();
return <Table useLocation={useLocation} useHistory={useHistory} />;
};
```
</Tab>
<Tab label="pass props.basename manually">
```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 <Table useLocation={useLocation} basename={basename} />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,18 @@ import { Tab, Tabs } from 'rspress/theme';
```tsx
import { useLocation, useHref } from 'react-router-dom';
const App = () => {
const basename = useHref('/table');
const { Table } = useModuleApps();
return <Table useLocation={useLocation} useHref={useHref} />;
return <Table useLocation={useLocation} basename={basename} />;
};
```
</Tab>
<Tab label="react-router-dom@5">
```tsx
import { useLocation, useHistory } from 'react-router-dom';
const App = () => {
const { Table } = useModuleApps();
return <Table useLocation={useLocation} useHistory={useHistory} />;
};
```
</Tab>
<Tab label="手动传入 props.basename">
```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 <Table useLocation={useLocation} basename={basename} />;
};
Expand Down
4 changes: 3 additions & 1 deletion packages/runtime/plugin-garfish/src/runtime/loadable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
59 changes: 38 additions & 21 deletions packages/runtime/plugin-garfish/src/runtime/utils/apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ function getAppInstance(
React.ComponentType<any> | 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(
Expand All @@ -68,37 +71,51 @@ or directly pass the "basename":
<Component basename={basename} useLocation={useLocation} />`,
);
}
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 [email protected] 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: <Component basename={basename} useLocation={useLocation} />
if (props.basename && typeof props.basename === 'string') {
// eslint-disable-next-line prefer-destructuring
Expand Down
27 changes: 15 additions & 12 deletions packages/runtime/plugin-garfish/tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -240,7 +241,7 @@ describe('plugin-garfish', () => {
<Route path="/basename-test">
<BasenameTest
useLocation={useLocation}
useHistory={useHistory}
basename="/main-app/basename-props-has-highest-priority"
/>
</Route>
</Switch>
Expand All @@ -258,17 +259,14 @@ describe('plugin-garfish', () => {
render(<AppWrapper />, {});
});

// 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.
Expand All @@ -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();
Expand All @@ -297,7 +295,14 @@ describe('plugin-garfish', () => {

return (
<BrowserRouter basename="/main-app" forceRefresh>
<BasenameTest useLocation={useLocation} />
<Switch>
<Route path="/no-active-when">
<BasenameTest
useLocation={useLocation}
useRouteMatch={useRouteMatch}
/>
</Route>
</Switch>
<LocationDisplay />
</BrowserRouter>
);
Expand All @@ -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();
});
});

0 comments on commit 29e297f

Please sign in to comment.