Modern.js 项目中的页面入口(Entry)机制详解
前言
在现代前端开发中,项目的入口管理是一个基础但至关重要的环节。Modern.js 作为一款现代化的前端开发框架,提供了一套灵活且强大的入口管理机制。本文将深入解析 Modern.js 中的页面入口概念、类型以及自定义配置方法,帮助开发者更好地理解和运用这一核心功能。
什么是页面入口?
页面入口(Entry)是指一个页面的起始模块,它决定了页面的加载方式和初始行为。在 Modern.js 项目中:
- 每个入口对应一个独立的页面
- 每个入口对应一个服务端路由
- 许多配置选项都是按入口划分的,如页面标题、HTML模板、页面元信息、是否启用SSR/SSG等
Modern.js 默认会根据目录约定自动确定页面的入口,同时也支持通过配置选项自定义入口。
单入口与多入口项目
单入口项目
Modern.js 初始化的项目默认是单入口(SPA)项目,结构如下:
.
├── src
│ └── routes
│ ├── index.css
│ ├── layout.tsx
│ └── page.tsx
├── package.json
├── modern.config.ts
└── tsconfig.json
转换为多入口项目
通过简单的命令操作,可以轻松将单入口项目转换为多入口项目:
pnpm run new
选择创建新入口后,项目结构会变为:
.
├── myapp # 原入口
│ └── routes
│ ├── index.css
│ ├── layout.tsx
│ └── page.tsx
└── new-entry # 新入口
└── routes
├── index.css
├── layout.tsx
└── page.tsx
注意:Modern.js 会使用与 package.json 中 name 字段同名的入口作为主入口。主入口的路由是 /
,其他入口的路由是 /{entryName}
。
入口类型详解
Modern.js 支持多种入口类型,每种类型有不同的编译和运行时行为。主要分为两大类:
1. 框架模式入口
框架模式需要使用 Modern.js 提供的框架能力,如嵌套路由、SSR、集成 BFF 等。在这种模式下,开发者定义的入口并不是实际的编译入口,Modern.js 在启动时会生成一个包装后的入口。
(1) 约定式路由
当入口中存在 routes/
目录时,Modern.js 会在启动时扫描该目录下的文件,并根据文件约定自动生成客户端路由(react-router)。
示例结构:
.
├── src
│ └── routes
│ ├── layout.tsx
│ └── page.tsx
layout.tsx
导出的组件是最外层组件page.tsx
导出的组件是/
路由的组件
(2) 自控式路由
当入口中存在 App.[jt]sx?
文件时,开发者可以在此文件中通过代码设置客户端路由,或者不设置客户端路由。
示例代码:
import { BrowserRouter, Route, Routes } from '@modern-js/runtime/router';
export default () => {
return (
<BrowserRouter>
<Routes>
<Route index element={<div>index</div>} />
<Route path="about" element={<div>about</div>} />
</Routes>
</BrowserRouter>
);
};
(3) 自定义入口
当入口中存在 entry.[jt]sx
文件时,开发者需要在此文件中调用 createRoot
和 render
函数来完成项目的入口逻辑。
示例代码:
import { createRoot } from '@modern-js/runtime/react';
import { render } from '@modern-js/runtime/browser';
const ModernRoot = createRoot();
render(<ModernRoot />);
(4) 自定义引导(即将废弃)
当入口中存在 index.[jt]sx
文件且默认导出一个函数时,Modern.js 会将默认的 bootstrap
函数作为参数传入,并用导出的函数替换默认的 bootstrap
。
2. 构建模式入口
构建模式不使用 Modern.js 提供的 Runtime 能力,而是完全由开发者自己定义页面的入口。
当入口目录中存在 index.[jt]sx
且没有通过 export default
导出函数,或者存在 entry.[jt]sx
文件但没有安装 @modern-js/runtime
依赖时,对应的文件会被识别为 webpack 或 Rspack 的入口模块。
示例代码:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
注意:这种模式下无法使用 Modern.js 框架的运行时能力。
自定义入口配置
在某些情况下,开发者可能需要自定义入口配置而非使用 Modern.js 提供的入口约定。Modern.js 提供了以下配置选项:
source.entries
:用于设置自定义入口对象source.disableDefaultEntries
:用于禁用 Modern.js 默认的入口扫描行为
配置示例
export default defineConfig({
source: {
entries: {
'my-entry': {
entry: './src/my-page/index.tsx',
disableMount: true,
},
},
disableDefaultEntries: true,
},
});
重要提示:当启用 disableMount
时,将无法使用 Modern.js 框架的运行时能力。
最佳实践建议
- 新项目:建议使用 Modern.js 的约定式路由,可以最大程度地利用框架提供的便利功能
- 迁移项目:如果是从其他框架迁移的项目,可以先使用自定义入口配置,逐步迁移
- 复杂项目:大型项目推荐使用多入口结构,可以更好地组织代码和实现按需加载
- 性能优化:对于不需要框架能力的简单页面,可以考虑使用构建模式入口减少运行时开销
通过本文的详细解析,相信开发者能够更好地理解和运用 Modern.js 的入口机制,构建出更加灵活高效的前端应用。