UNPKG

rerumaccusamus

Version:

The meta-framework suite designed from scratch for frontend-focused modern web development.

133 lines (97 loc) 5.3 kB
--- sidebar_position: 1 title: 定义路由 --- Modern.js 在运行时是一个 **Universal App(大统一应用)**——— 既有客户端部分,又有服务端部分。但是开发者对服务端部分是无感知的,不需要专门去为 Server 部分编写代码,只需要专注产品本身的业务逻辑开发即可。 使用 Modern.js,开发者无需像传统的以服务端为中心的框架那样,手动定义路由映射关系。Modern.js 会自动为每一个[入口](/docs/guides/tutorials/c07-app-entry/7.1-intro) 生成一个 **服务端路由**。同时,在每一个入口下,开发者还可以定义 **客户端路由**,使每一个入口都成为一个独立的单页 Web 应用( SPA )。 ## 服务端路由 服务端路由是由 Modern.js 根据入口以及配置生成的路由。Modern.js 会根据基于文件约定的**标识**,自动生成入口。Modern.js 支持3种**标识**: - [`App.[tj]sx` 文件](/docs/apis/hooks/mwa/src/app) - [`pages/` 目录](/docs/apis/hooks/mwa/src/pages) - [`index.[tj]sx` 文件](/docs/apis/hooks/mwa/src/index) 当 `src/` 目录下有**入口标识**,就认为这个应用是单入口的,`src/` 下的其他文件和目录,都会被视为入口内部的文件。 如果 `src/` 目录下没有**入口标识**,那么 `src/` 目录的**下一级**目录里,如果有**入口标识**,这个目录就会被视为一个应用入口,这个目录下的其他文件和目录,都会被视为入口内部的文件。 例如,以下目录结构: ``` . ├── src/ │ ├── .eslintrc.json │ ├── App.css │ └── App.tsx ``` `src/` 目录下包含 `App.tsx` 这个**入口标识**,将会生成一个单入口应用,对应的服务端路由为根路径 `/`。 而以下目录结构: ``` . ├── src/ │ ├── contacts/ │ │ ├── App.css │ │ └── App.tsx │ ├── landing-page/ │ │ ├── App.css │ │ └── App.tsx │ └── .eslintrc.json ``` `src/contacts/``src/landing-page/` 目录下包含 `App.tsx` 这个**入口标识**,将会生成由入口名为 `contacts``landing-page` 组成的多入口应用,两个入口对应的服务端路由分别为 `/contacts``/landing-page`。 :::note 注 当**入口名**和**项目名**(`package.json` 里的 `name`)相同时,会被认为是应用主入口,对应的服务端路由为根路径 `/`,即主入口对应的服务端路由不需要包含**入口名**这部分路径。 ::: :::info 补充信息 可以通过配置项【[server.routes](/docs/apis/config/server/routes)】来修改默认生成的服务端路由。 ::: ## 客户端路由 Modern.js 的客户端路由基于 [React Router](https://reactrouter.com/) 实现,支持**自控式路由**和**约定式路由**两种写法。 :::tip 提示 使用客户端路由,需要先确认 [`runtime.state`](/docs/apis/config/runtime/state) 配置已开启。 ::: ### 自控式路由 使用 `App.jsx` 作为**入口标识**的入口,需要使用**自控式路由**。此时,开发人员需要手动引入 `Route` 等路由组件定义路由,下面是一个示例: ```tsx title="App.tsx" import { Switch, Route } from '@modern-js/runtime/router' export default () => ( <Switch> <Route path="/" exact={true}> <div>Hello Modern.js</div> </Route> <Route path="/info" exact={true}> <div>User info</div> </Route> <Route path="*"> <div>404</div> </Route> </Switch> ) ``` 上述代码将会生成两条客户端路由 `/``/info`,其余所有未匹配的 URL 都会返回 404。 :::tip 提示 和直接使用 React Router 不同,这里不需要在 `Route` 组件外包裹 `Router` 组件,因为 Modern.js 会自动在根组件包裹 `Router` 组件。 ::: ### 约定式路由 使用 `pages/` 目录作为**入口标识**的入口,客户端路由采用的是**约定式路由**:基于 `pages/` 目录下的文件名及文件路径自动生成路由信息。 例如,下面的目录结构: ``` . ├── src/ │   ├── pages/ │ │ ├── _app.tsx │ │ ├── docs.tsx │ │ └── index.tsx │   └── .eslintrc.json ``` 将会自动生成 `/``/docs` 两条客户端路由,`/` 对应渲染的组件为 `index.tsx` 默认导出的组件,`/docs` 对应渲染的组件为 `docs.tsx` 默认导出的组件。`_app.tsx` 是下划线开头的文件,代表**约定式路由**中的一个特殊文件,为整个入口提供根组件,可以用于实现全局布局、公共 UI 等,详细使用请参考[这里](/docs/apis/hooks/mwa/src/pages#全局-layout)。 又例如以下多入口的情况: ``` ├── src/ │ ├── contacts/ │ │ └── pages/ │ │ ├── _app.tsx │ │ ├── docs.tsx │ │ └── home.tsx │ ├── landing-page/ │ │ └── pages/ │ │ ├── _app.tsx │ │ ├── docs.tsx │ │ └── index.tsx │ ├── .eslintrc.json ``` `contacts` 入口生成 `/contacts/home``/contacts/docs` 两条路由;`landing-page` 入口生成 `/landing-page``/landing-page/docs` 两条路由。