Platforms
ESBoot 支持两种模式:MP(多平台)和 SP(单平台),可以通过 isSP 来切换。
模式对比
| 特性 | MP(Multi Platforms) | SP(Single Platform) |
|---|---|---|
| 全称 | Multi Platforms(多平台) | Single Platform(单平台) |
| 适用场景 | 需要同时支持多个平台的前端业务 | 只需要在一个平台运行的中台/微信平台业务 |
| 支持平台 | 4 个平台:pc-browser、pc-native、mobile-browser、mobile-native | 单一平台(可以是 browser 或 native) |
| 代码复用 | 共用业务逻辑,根据平台生成不同代码 | 普通项目结构,无需平台区分 |
| 目录结构 | 复杂的平台目录结构 | 简单的 src 根目录结构 |
| 配置复杂度 | 每个平台独立配置 | 单一配置 |
MP(Multi Platforms)
MP 模式多用于前端业务,适用于页面需要同时放在多个平台下运行的情况。
支持的平台
目前默认支持 4 个平台:
pc-browser- PC 端浏览器pc-native- PC 端嵌入式(CEF)mobile-browser- 移动端浏览器mobile-native- 移动端嵌入式(Webview)
目录结构
MP 模式下的基本目录结构如下:
# 配置根目录
config/
├── mobile
│ ├── _browser
│ │ └── config.js
│ ├── _native
│ │ └── config.js
│ ├── bridge
│ │ ├── bridge-mock-sample.js
│ │ └── bridge-mock.js
│ └── template
│ └── index.html
└── pc
├── _browser
│ └── config.js
├── _native
│ └── config.js
├── bridge
│ ├── bridge-mock-sample.js
│ └── bridge-mock.js
└── template
├── disable-rem.html
├── index.html
└── test-pc-flash-screen.html
# 多平台共用代码
src/
└── helpers
└── multi-platforms.ts
# 业务逻辑(平台特定代码)
src/platforms/
├── mobile
│ ├── _browser
│ │ ├── helper
│ │ │ └── multi-platforms.ts
│ │ └── index.ts
│ └── _native
│ ├── helper
│ │ └── multi-platforms.ts
│ └── index.ts
└── pc
├── _browser
│ ├── helper
│ │ └── multi-platforms.ts
│ └── index.ts
└── _native
├── helper
│ └── multi-platforms.ts
└── index.ts
设计理念
MP 模式的最大好处是可以共用一份业务逻辑,然后根据不同的平台生成不同的代码。
一个合理的业务设计:
- 在
mobile和pc下,除了 UI 不一样,其他应该都是高度类似的 - 在
browser和native下,UI 也是高度类似的,只是宿主环境不一样,所以只有交互方法不一样,其他都是一样的
这样的特性就决定了四个平台,可以共用一份业务逻辑,两套 UI。
代码组织原则
MP 模式下,目录结构会比较复杂,你可能会看到多个 helper 目录。这里提供一个代码组织原则,以 helper 举例:
遵循从通用到特定的原则,将代码放在最合适的层级:
- 平台无关代码:如果
helper是平台无关的,也就是 4 个平台都可以使用,放在src/helpers/下 - 平台特定代码:如果
helper只在pc下使用,放在src/platforms/pc/helper/下 - 设备类型特定代码:如果
helper只在mobile下使用,放在src/platforms/mobile/helper/下 - 宿主环境特定代码:如果
helper只能在某一个宿主环境使用,比如cef中使用,放在src/platforms/pc/_native/helper/下。其他平台同理
这个原则同样适用于其他类型的代码文件(如 components、utils、hooks 等)。
平台差异代码
虽然可以复用大部分代码,但还是会有一些差异。比如宿主环境不一样,交互方法就不一样。
例如,一个页面失去焦点的生命周期:
- 在浏览器端需要监听
visibilitychange事件 - 在
native端需要监听原生客户端提供的生命周期
但我们的业务代码可能只有一份,所以 ESBoot 提供了 multi-platforms.ts,让你在 MP 模式下编写平台差异的代码。
示例:sayHello 方法
假设有一个 sayHello 方法,在 browser 端和 native 端的实现不一样:
浏览器端实现:
// src/platforms/mobile/_browser/helper/multi-platforms.ts
export default {
sayHello: (name: string) => {
console.log(`Hello, ${name}`);
}
};
Native 端实现:
import { log } from 'native-helper';
// src/platforms/mobile/_native/helper/multi-platforms.ts
export default {
sayHello: (name: string) => {
log(`Hello, ${name}`);
}
};
自动生成的统一导出:
在 src/helpers/multi-platforms.ts 中,ESBoot 会自动导出当前平台下的差异代码:
// 📢 Do not manually modify, automatically generated by ESBoot.
export * from '@pc-native/helpers/multi-platforms';
业务代码中使用:
import { sayHello } from '@/helpers/multi-platforms';
sayHello('world');
固定只引用 @/helpers/multi-platforms,这样在编译时,ESBoot 会根据当前的平台自动生成对应的代码。
Config 目录
在 MP 模式下,config 目录结构也比较复杂。4 个平台,每个平台都有自己的 config。
遵循从小到大的原则:
- 当前平台目录下的配置只能被当前平台使用
- 再往上就是共享配置,比如
config/mobile/下的配置,就是mobile平台下所有宿主环境共享的配置
config.js
config/
├── mobile
│ ├── _browser
│ │ └── config.js
│ ├── _native
│ │ └── config.js
└── pc
├── _browser
│ └── config.js
└── _native
└── config.js
config.js 是配置文件,项目启动后会自动加载。在这里可以设置一些运行时的配置,比如页面中使用的接口地址等。
bridge
bridge 目录是给 bridge-mock 使用的。
config/mobile/bridge/- 给mobile平台使用config/pc/bridge/- 给pc平台使用
template
这是页面的模板目录,会根据这个目录下的文件生成页面。参考 template 配置。
SP(Single Platform)
SP 模式多用于中台/微信平台业务,适用于页面只需要在一个平台下运行的情况(这个平台可以是 browser,也可以是 native)。
适用场景
- 中台管理系统
- 微信小程序/H5 页面
- 单一平台的业务应用
- 不需要跨平台复用的项目
SP 目录结构
SP 模式的目录结构就是普通项目的目录,src 即是根目录:
src/
├── components/
├── helpers/
├── hooks/
├── utils/
└── *.entry.tsx
配置结构
SP 模式下的配置结构也相对简单:
config/
├── config.js
├── bridge/
└── template/
└── index.html
与 MP 模式的区别
- 目录结构:
SP模式没有src/platforms/目录,所有代码都在src/下 - 配置复杂度:
SP模式只有一个config.js,不需要区分平台 - 代码复用:
SP模式不需要考虑平台差异,代码结构更简单 - 构建产物:
SP模式只生成单一平台的构建产物