跳到主要内容

快速开始

创建新项目

npx @evjs/create-app my-app
cd my-app && npm install

两个参数都是可选的 —— 省略时 CLI 会交互式提示。

可用模板

模板描述
basic路由 + 服务端函数
mpa多页面应用模板
api-routes通过 createRoute() 构建程序化 REST API
complex-routing参数、搜索、根布局、加载器、嵌套路径
with-tailwind通过 PostCSS 使用 Tailwind CSS
with-trpctRPC 互操作示例
with-sqlite基于 SQLite 的全栈 CRUD
custom-ws-transport自定义 WebSocket 传输层
plugin-authoring插件生命周期与构建器钩子示例

开发

ev dev

浏览器将自动打开 http://localhost:3000,支持热模块替换。显式 app/page/server 根下的 "use server" 模块会被自动发现。

生产构建

ev build

项目结构

my-app/
├── .gitignore # 忽略 evjs 生成类型文件
├── index.html # HTML 模板(必须包含 <div id="app">)
├── ev.config.ts # 可选配置
├── src/
│ ├── layout/
│ │ └── index.tsx # 可选 SPA 根布局
│ ├── pages/ # 文件路由
│ │ ├── index.tsx # /
│ │ └── users/$id.tsx # /users/$id
│ └── api/ # 服务端模块
│ ├── users.server.ts # "use server" 函数
│ └── health.routes.ts
├── package.json
└── tsconfig.json

页面

// src/pages/users/$id.tsx
import { usePageParams, useQuery } from "@evjs/client";
import { getUser } from "../../api/users.server";

export default function UserPage() {
const { id } = usePageParams();
const { data } = useQuery(getUser, id);
return <main>{data?.name}</main>;
}

当项目存在 src/pages,且项目没有声明显式的 apppagesremote 配置时,evjs 会自动基于文件树构建一个 SPA。用户不需要创建 路由胶水;这些内容由框架生成和托管。SPA 模式只会为 TypeScript 写入 src/evjs-route-types.d.ts,脚手架应用默认忽略它。

SPA 根布局发现是可选的。可以在路由目录旁边使用 src/layout/index.tsx, 也可以通过 routing.layout 指向其他模块;如果应用不需要框架根布局,设置 routing.layout: false

MPA 模式

MPA 使用同一套 src/pages 文件,只需要切换 routing 模式:

// ev.config.ts
import { defineConfig } from "@evjs/ev";

export default defineConfig({
routing: {
mode: "mpa",
},
});

每个页面都会生成独立 HTML 文档和客户端 entry,不引入客户端路由器配置。 layout/index.tsx 约定只用于 SPA,并且以精确路径放在页面路由目录旁边;MPA 页面需要公共外框时, 应像普通 React 代码一样组合共享组件,且不支持 routing.layout

包列表

用途
@evjs/ev框架 API、配置、插件、构建编排和 deployment helpers
@evjs/cli注入默认构建器的轻量 CLI 包装 (ev dev, ev build, ev inspect)
@evjs/create-app项目脚手架 (npx @evjs/create-app)
@evjs/clientpage hooks、导航、transport、remotes 和 RSC 浏览器运行时 API
@evjs/serverserver functions、routes、渲染和部署相关的 Hono/fetch 服务端运行时 API

Manifest schema、build tools、page runtime 和 shell 内部实现都位于上述公开包中。 应用的 config/build 代码从 @evjs/ev 导入;运行时代码从 @evjs/client@evjs/server@evjs/server/react 导入。 @evjs/cli@evjs/create-app 应作为工具使用,不应被应用模块 import。 @evjs/bundler-utoopack 这类 bundler adapter 以及 @evjs/shared 这类共享契约模块, 只面向自定义框架工具或 adapter 开发。

应用源码或生成的 SPA entry 需要浏览器运行时时声明 @evjs/client。应用使用 server functions、server routes、框架渲染或部署运行时包装时声明 @evjs/server

必需依赖

{
"dependencies": {
"@evjs/client": "<same version>",
"@evjs/ev": "<same version>",
"@evjs/server": "<same version>",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@evjs/cli": "<same version>",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"typescript": "^6.0.2"
}
}
important

应用中的所有 @evjs/* 包必须保持相同版本。多数应用只需要 @evjs/ev@evjs/cli;如果额外添加直接 runtime 包或 adapter 包,升级时也要一起升级。

重要规则

  • 配置文件:ev.config.ts(不是 evjs.config.ts
  • @evjs/ev 导入 defineConfig,不是从 @evjs/server
  • HTML 必须包含 <div id="app"> 作为渲染目标
  • 不要在你的项目 package.json 中添加 "type": "module" —— 服务端 bundle 使用 CJS 格式
  • 优先使用 src/pages 作为路由事实来源
  • 保持 src/evjs-route-types.d.ts 为生成且被忽略的文件;不要在应用代码里导入它
  • 独立页面且不需要客户端路由器时,使用 routing.mode: "mpa"