创建项目
Oak 项目的推荐创建方式,是直接使用 oak-cli 生成一个完整的工程骨架。这样生成出来的目录结构、脚本、依赖配置和多端入口都是符合 Oak 规范的,后续再去阅读本书中的其它章节时,也更容易一一对应起来。
如果你是第一次接触 Oak,建议先从新手入门:从零完成一个任务清单应用开始。那一章会从本命令开始,连续完成安装依赖、定义实体、生成领域代码、编写页面 CRUD、初始化数据库和添加其它端;本页适合在完成第一次实践后回来查阅创建选项。
创建命令
在你准备放置项目的目录下执行:
oak-cli create my-first-oak-app
oak-cli 在源码中的入口定义位于 oak-cli/src/index.ts,创建项目的实现位于 oak-cli/src/create,其中核心命令是:
program
.command('create <name>')
.option('-d, --dev', 'dev')
.option('-m, --module', 'module')
.action(create);
其中:
create <name>:创建一个完整的 Oak 应用工程;--dev:按 Oak 家族仓库的本地联调方式生成依赖,适合你当前这种直接维护框架源码的开发环境;--module:只创建一个 Oak 模块,而不是完整应用。模块模式下不会生成web、wechatMp等前端工程骨架,适合编写一个可复用的业务包。
创建过程中会询问什么
执行创建命令后,oak-cli/src/create/index.ts 会进一步询问一些信息:
- 项目显示名
title - 版本号
version - 项目描述
description - 应用需要的数据库驱动:MySQL、PostgreSQL、SQLite,至少选择一个,默认 MySQL
- 是否默认依赖
oak-general-business - 是否还依赖其它 Oak 家族模块
- 是否加载一个示例工程
其中最值得新手注意的是 oak-general-business。它是 Oak 官方抽象出来的一套通用业务逻辑,包含了用户、应用、会话、文件、微信、OAuth 等大量基础能力。绝大多数业务项目在一开始都应该勾选它,后面本书最后一章也会专门介绍它。
创建命令不会再询问平台多选。完整应用默认只生成 Web workspace;微信小程序、React Native、Desktop 在项目创建后按需通过 oak-cli add 添加。数据库驱动选择只出现在应用模式,模块模式不会生成数据库配置。
--dev 和普通模式的区别
如果使用 --dev,生成出来的 package.json 会把 Oak 家族依赖指向本地相邻目录,例如:
"oak-domain": "file:../oak-domain",
"oak-frontend-base": "file:../oak-frontend-base",
"oak-cli": "file:../oak-cli"
这正是当前 Oak 仓库的常见开发方式。也就是说,如果你要在本地同时修改 oak-domain、oak-frontend-base、oak-general-business 等库,那么项目目录最好和这些仓库处在同一级目录下,否则这些本地依赖路径就无法正确解析。
如果不使用 --dev,oak-cli 会从 npm 上读取 Oak 家族包的最新版本,并写入 semver 版本号。此时后续 make:domain 读取的是发布包实体产物,优先级为 es/entities -> lib/entities -> src/entities。
新发布的 Oak 模块不应该靠发布 src 解决编译问题。发布包应带上 es/entities/*.d.ts 和同名 .js,编译器会自动合并类型声明和运行时值。
创建命令实际做了什么
oak-cli/src/create/index.ts 会完成下面这些事情:
- 检查目标目录是否已经存在;
- 复制模板目录;
- 在完整应用模式下生成默认
webworkspace;小程序、React Native 和 Desktop workspace 留给后续oak-cli add; - 生成
oak.config.json和oak.config.ts,前者保存项目运行/检查配置,后者保存当前 Vite / webpack / alias / CDN 等编译配置; - 生成
tsconfig.lib.json、tsconfig.es.json、src/tsconfig.json、tsconfig/paths.*.json和web/tsconfig.json;新增平台时再生成对应 workspace 配置; - 生成
package.json、Oak 默认脚本、推荐 Web CDN 配置、可选build:bundle和升级脚本入口; - 把你选择的依赖写入
src/configuration/dependency.ts; - 在页面、组件和 Web 命名空间目录中放置
index.config.ts,作为新项目的结构化配置入口; - 将模板中的默认项目名统一重命名为你输入的名字;
- 根据数据库选择只保留对应驱动依赖和
configuration/mysql.json、postgres.json、sqlite.json; - 如果勾选示例,额外复制一套示例业务代码。
因此,Oak 的“创建项目”并不是单纯地拷贝几份空文件,而是顺手把后续最关键的开发基础设施一起准备好了。
新项目里的配置入口
当前模板已经不再建议把页面、组件和命名空间配置继续散落在 index.json 里。新项目应优先使用同目录下的 index.config.ts:
import { CreatePageConfig } from '@oak-frontend-base/config';
import { CreateComponentConfig } from '@oak-frontend-base/config';
import { CreateNamespaceConfig } from '@oak-frontend-base/config';
三类配置入口的职责不同:
src/pages/**/index.config.ts:页面配置,使用CreatePageConfig。这里声明 Web 路由、菜单、访问控制以及小程序页面 JSON 能力。src/components/**/index.config.ts:组件配置,使用CreateComponentConfig。这里声明小程序组件 JSON 能力,例如usingComponents、componentGenerics、styleIsolation。web/src/app/namespaces/<namespace>/index.config.ts:Web 命名空间配置,使用CreateNamespaceConfig。这里声明命名空间路由入口、菜单分组、默认访问策略和控制台上下文实体范围。
index.json 仍然是兼容入口,旧项目可以继续读取;但新页面、新组件和新命名空间都应该把配置写进 index.config.ts。小程序相关 JSON 字段放在 mp 字段下,由 oak-cli 在构建时生成最终的页面或组件 JSON。
命名空间目录还会配合一个生成文件:
web/src/app/namespaces/
├── console/
│ └── index.config.ts
├── frontend/
│ └── index.config.ts
├── allNamespaceConfigs.ts
└── index.ts
其中 allNamespaceConfigs.ts 由 oak-cli 根据命名空间配置和页面菜单配置生成,不应该手工维护;index.ts 负责重新导出聚合结果;web/src/index.tsx 会把它传给 oak-frontend-base/platforms/web/initialize 的 namespaceConfigs 参数。
创建完成后的第一步
项目创建完成后,建议按下面的顺序继续:
npm install
npm run dev
这三步分别对应:
- 安装依赖,并由
postinstall顺序执行project:init、make:domain、make:dep; - 同时启动后端
server:start和 web 端start:web进行联调。
当前模板的普通应用会把 postinstall 配成 npm run project:init && npm run make:domain && npm run make:dep。因此首次 npm install 后通常已经完成依赖模板初始化、领域代码和依赖装配生成。后续如果增删 Oak 依赖模块,仍应显式按这个顺序重新执行,保证依赖模板先落盘、领域类型包含最终实体、装配代码最后生成。
创建应用和创建模块
很多初学者一开始会分不清 Oak 应用和 Oak 模块。
二者的区别可以先简单理解为:
- Oak 应用:最终可以独立运行,有自己的前端入口、后端入口、数据库配置和部署流程;
- Oak 模块:只提供实体、逻辑、特性、页面或组件,供别的 Oak 应用依赖。模块保留跨端源码和类型基线,但不生成可独立运行的平台 workspace。
例如 oak-general-business 就是一个典型的模块,而 bm-smart 是一个完整应用。Oak 的依赖编译能力,正是为了把这两种代码组织方式统一起来。
所以如果你的目标是“做一个业务系统”,请优先创建完整应用;如果你的目标是“沉淀一套可复用业务包”,再考虑使用 --module。
一个推荐的最小起步方式
如果你是第一次接触 Oak,最推荐的起步方式其实非常简单:
- 在 Oak 家族仓库同级目录下执行
oak-cli create xxx --dev; - 依赖
oak-general-business; - 执行
npm install;当前模板会在postinstall中完成project:init、make:domain和make:dep; - 用
npm run dev同时启动后端和 web; - 编写一个最小的
Entity和一个最小的页面。
这样学习曲线是最平缓的,也符合当前 Oak “开发时就使用真实后端运行态”的默认模板。旧的纯前台模式已经移除,不要再按 start:web 单独替代后端来理解。
需要其它平台时,再按多平台工作区添加,不必在创建当天把所有原生工具链一并安装。