Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(router): add basename #570

Merged
merged 4 commits into from
Dec 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { IRenderViewOptions, IHtmlDocument } from './types';
export class SpaRenderer extends BaseRenderer {
renderDocument({ req, app }: IRenderViewOptions) {
const assets = this._getMainAssetTags(req);
const {
router: { basename }
} = this._serverPluginContext.appConfig;
const appData: AppData = {
ssr: false,
pageData: {}
pageData: {},
basename
};
const document: IHtmlDocument = {
htmlAttrs: {},
Expand Down
7 changes: 3 additions & 4 deletions packages/platform-web/src/shuvi-app/app/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ export const createApp: CreateAppClient = ({
const { appState, ssr, basename } = appData;
let history: History;
if (historyMode === 'hash') {
history = createHashHistory();
history = createHashHistory({ basename });
} else {
history = createBrowserHistory();
history = createBrowserHistory({ basename });
}

const router = createRouter({
history,
routes: getRoutes(routes),
basename
routes: getRoutes(routes)
});

app = application({
Expand Down
6 changes: 3 additions & 3 deletions packages/platform-web/src/shuvi-app/app/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export const createApp: CreateAppServer = options => {
const { req, ssr, basename } = options;
const history = createMemoryHistory({
initialEntries: [(req && req.url) || '/'],
initialIndex: 0
initialIndex: 0,
basename
});
const router = createRouter({
history,
routes: getRoutes(routes),
basename
routes: getRoutes(routes)
}) as IRouter;
let app: InternalApplication;
if (ssr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class ReactServerView implements IReactServerView {
);
}
// handle router internal redirect
return redirect(pathname);
return redirect(router.resolve(router.current).href);
}

const loadableModules: string[] = [];
Expand Down
3 changes: 1 addition & 2 deletions packages/router-react/src/MemoryRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ export function MemoryRouter({
let routerRef = React.useRef<IRouter>();
if (routerRef.current == null) {
routerRef.current = createRouter({
basename,
routes: routes || [],
history: createMemoryHistory({ initialEntries, initialIndex })
history: createMemoryHistory({ initialEntries, initialIndex, basename })
}).init();
}

Expand Down
18 changes: 9 additions & 9 deletions packages/router-react/src/__tests__/useHref-basename.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/app');
expect(href).toBe('/app/');
});

describe('when the URL has a trailing slash', () => {
Expand All @@ -214,7 +214,7 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/app');
expect(href).toBe('/app/');
});
});

Expand Down Expand Up @@ -250,7 +250,7 @@ describe('useHref under a <Routes basename>', () => {
it('returns the correct href', () => {
let href;
function Admin() {
href = useHref('../../../dashboard');
href = useHref('../../dashboard');
return <h1>Admin</h1>;
}

Expand All @@ -269,7 +269,7 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/dashboard');
expect(href).toBe('/app/dashboard');
});

describe('and no additional segments', () => {
Expand All @@ -295,15 +295,15 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/');
expect(href).toBe('/app/');
});
});

describe('when the URL has a trailing slash', () => {
it('returns the correct href', () => {
let href;
function Admin() {
href = useHref('../../../dashboard');
href = useHref('../../dashboard');
return <h1>Admin</h1>;
}

Expand All @@ -322,15 +322,15 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/dashboard');
expect(href).toBe('/app/dashboard');
});
});

describe('when the href has a trailing slash', () => {
it('returns the correct href', () => {
let href;
function Admin() {
href = useHref('../../../dashboard/');
href = useHref('../../dashboard/');
return <h1>Admin</h1>;
}

Expand All @@ -349,7 +349,7 @@ describe('useHref under a <Routes basename>', () => {
</Router>
);

expect(href).toBe('/dashboard/');
expect(href).toBe('/app/dashboard/');
});
});
});
Expand Down
100 changes: 100 additions & 0 deletions packages/router-react/src/__tests__/useHref.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,56 @@ describe('useHref', () => {
expect(href).toBe('/courses/');
});
});

describe('when up to root route, href should always be root /', () => {
it('when href has no trailing slash', () => {
let href;
function AdvancedReact() {
href = useHref('..');
return <h1>Advanced React</h1>;
}

createTestRenderer(
<Router
initialEntries={['/courses']}
routes={[
{
path: 'courses',
component: AdvancedReact
}
]}
>
<RouterView />
</Router>
);

expect(href).toBe('/');
});

it('when href has a trailing slash', () => {
let href;
function AdvancedReact() {
href = useHref('../');
return <h1>Advanced React</h1>;
}

createTestRenderer(
<Router
initialEntries={['/courses']}
routes={[
{
path: 'courses',
component: AdvancedReact
}
]}
>
<RouterView />
</Router>
);

expect(href).toBe('/');
});
});
});

describe('with a to value that has more .. segments than are in the URL', () => {
Expand Down Expand Up @@ -277,6 +327,56 @@ describe('useHref', () => {
expect(href).toBe('/courses');
});

describe('when up to root route, href should always be root /', () => {
it('when href has no trailing slash', () => {
let href;
function AdvancedReact() {
href = useHref('../..');
return <h1>Advanced React</h1>;
}

createTestRenderer(
<Router
initialEntries={['/courses/some-path']}
routes={[
{
path: 'courses/some-path',
component: AdvancedReact
}
]}
>
<RouterView />
</Router>
);

expect(href).toBe('/');
});

it('when href has a trailing slash', () => {
let href;
function AdvancedReact() {
href = useHref('../../');
return <h1>Advanced React</h1>;
}

createTestRenderer(
<Router
initialEntries={['/courses/some-path']}
routes={[
{
path: 'courses/some-path',
component: AdvancedReact
}
]}
>
<RouterView />
</Router>
);

expect(href).toBe('/');
});
});

describe('and no additional segments', () => {
it('links to the root /', () => {
let href;
Expand Down
4 changes: 3 additions & 1 deletion packages/router/src/__tests__/matchRoutes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ describe('path matching', () => {
expect(pickPaths(routes, '/groups/main')).toEqual(['/groups/main']);
expect(pickPaths(routes, '/groups/123')).toEqual(['/groups/:groupId']);
expect(pickPaths(routes, '/groups')).toEqual(['/groups']);
expect(pickPaths(routes, '/files/some/long/path')).toEqual(['/files/:_other(.*)']);
expect(pickPaths(routes, '/files/some/long/path')).toEqual([
'/files/:_other(.*)'
]);
expect(pickPaths(routes, '/files')).toEqual(['/files']);
expect(pickPaths(routes, '/one/two/three/four/five')).toEqual([
'/:one/:two/:three/:four/:five'
Expand Down
Loading
Loading