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

Conversation

Repraance
Copy link
Contributor

What kind of change does this PR introduce?

Did you add tests(unit,e2e) for your changes?

Does this PR introduce a breaking change?

What needs to be documented once your changes are merged?

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

expect(href).toBe('/app/');
expect(href).toBe('/app');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用.. 或者 ../ 这种向上一级的相对路径,如果达到根路由(如果有basename,则basename 即为根路由)时,不再区分根路由是否带trailing slash。

因为此时没办法判断了。href 是使用当前pathname 计算的。
当pathname 不为根路由时,pathname 可以带 trailing slash,比如 /about 或者 /about/,因此最终的href的traling slash 也是带或者不带。

但是,当达到根路由时,pathname 变成了 /,此时带不带traling slash 都一样。

此外,我调查了vue-router 和react-router,他们使用向上相对路径达到根路由时,也是不再区分到底带不带 traling slash。

vue-router 在向上达到根路由时,总是带trailing slash(相当于此处为/app/
react-router 在向上达到根路由时,总是不带traling slash(相当于此处为/app

shuvi 此处选择了 react-router 的做法

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

和 vue-router 对齐,总是带上 /

@@ -194,57 +196,3 @@ describe('path matching', () => {
expect(pickPaths(routes, '/page')).toEqual(['page']);
});
});

describe('path matching with a basename', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

router 中basename的逻辑 被完全移除,因此matchRoutes 的basename 参数也被移除了。
新版中,使用createLocation 把basename 剪掉,得到pathname,然后再matchRoutes

? window.location.href
: window.location.href.slice(0, hashIndex);

it('should ignore base tag', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

干掉了base tag,因为他跟新的hash basename 行为不符。
新版hash basename 采用了比较容易理解的react-router 做法
而旧版base tag,是把base加在#前面。因此索性移除了base tag feature。
react-router 也未支持base tag

this._history.replaceState(
{ ...this._history.state, idx: this._index },
''
'',
notMatchBasename ? this.resolve(this.location).href : undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果初始url无法匹配basename,直接进行一个redirect,此处参考了vue-router的逻辑

}

function createHref(to: PathRecord) {
return (
getBaseHref() +
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上。
干掉了base tag,因为他跟新的hash basename 行为不符。
新版hash basename 采用了比较容易理解的react-router 做法
而旧版base tag,是把base加在#前面。因此索性移除了base tag feature。
react-router 也未支持base tag

this._history.replaceState(
{ ...this._history.state, idx: this._index },
''
'',
notMatchBasename ? this.resolve(this.location).href : undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同browserHistory
如果初始url无法匹配basename,直接进行一个redirect,此处参考了vue-router的逻辑

@@ -349,7 +346,7 @@ class Router<RouteRecord extends IRouteRecord> implements IRouter<RouteRecord> {
hash: location.hash,
query: location.query,
state: location.state,
redirected: !!location.redirectedFrom,
redirected: Boolean(location.redirectedFrom) || location.notMatchBasename,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果 当前url不匹配basename,需要redirect 302。
因为ReactServerView中,我们是根据 redirected 字段来重定向的。

因此,这里如果notMatchBasename为true,会被标记为 redirected: true

// current.redirected means the initial url does not match basename and should redirect
// so we just skip all guards
// this logic only applies to memory history
skipGuards: Boolean(current.redirected)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果 当前url不匹配basename,current.redirected 会是true(看下面 redirected 的改动)
并且skipGuards,这样,到ReactServerView 的 renderApp 中时,会被redirect到 加上basename 的url

@liximomo
Copy link
Contributor

matchRoutes API 接口和以前保持一致

@liximomo liximomo merged commit 3f301b7 into shuvijs:main Dec 26, 2023
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants