从 Laravel 迁移到 Node.js:用 Sutando 无缝切换
如果你是 Laravel 开发者,考虑转向 Node.js,最大的顾虑通常是离开 Eloquent。有了 Sutando,你不必放弃。本指南将带你逐步迁移 Laravel 应用到 Node.js,将 Eloquent 的每个概念映射到 Sutando。
如果你是 Laravel 开发者,考虑转向 Node.js,最大的顾虑通常是离开 Eloquent。有了 Sutando,你不必放弃。本指南将带你逐步迁移 Laravel 应用到 Node.js,将 Eloquent 的每个概念映射到 Sutando。
为什么从 Laravel 迁移到 Node.js?
常见原因:
- 实时功能:WebSocket、SSE、流式传输——Node.js 的事件循环原生支持
- 全栈 TypeScript:前后端共享类型
- Serverless/Edge:部署到 Cloudflare Workers、Vercel Edge 或 AWS Lambda
- 团队能力:团队更熟悉 JavaScript 而非 PHP
- 生态:npm 生态在某些领域比 Composer 更丰富
概念映射:Laravel → Node.js + Sutando
| Laravel | Node.js + Sutando |
|---|---|
| Eloquent Model | Sutando Model 类 |
| Migration | Sutando Schema Builder |
| Seeder | 不支持 |
| Factory | 不支持 |
| Route | Express / Fastify 路由 |
| Middleware | Express 中间件 |
| Blade | React / Vue / 纯 API |
| Artisan CLI | 自定义 npm 脚本 |
Eloquent Model → Sutando Model
Laravel (PHP)
class User extends Model {
protected $table = 'users';
protected $casts = ['is_admin' => 'boolean', 'metadata' => 'array'];
protected $fillable = ['name', 'email', 'password'];
public function posts(): HasMany {
return $this->hasMany(Post::class);
}
public function scopeActive($query) {
return $query->where('active', true);
}
}
Sutando (TypeScript)
class User extends Model {
table = 'users';
casts = { is_admin: 'boolean', metadata: 'json' };
relationPosts() {
return this.hasMany(Post, 'user_id');
}
scopeActive(query) {
return query.where('active', true);
}
}
映射几乎是 1:1 的。主要区别:
protected $table→table =protected $casts→casts =- 关联方法使用
relation前缀 - 作用域使用
scope前缀
查询对比
预加载
// Laravel
$users = User::with('posts.comments')->get();
// Sutando
const users = await User.query().with('posts.comments').get();
模型事件
// Laravel
User::creating(function ($user) {
$user->password = bcrypt($user->password);
});
// Sutando
User.creating(async (user) => {
user.password = await bcrypt.hash(user.password, 10);
});
Migration: Laravel → Sutando Schema Builder
// Laravel
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
});
// Sutando
await sutando.schema().createTable('users', table => {
table.increments('id').primary();
table.string('name');
table.string('email').unique();
table.timestamps();
});
路由:Laravel → Express
// Laravel
Route::get('/posts', [PostController::class, 'index']);
// Express
app.get('/posts', async (req, res) => {
const posts = await Post.query().with('user').get();
res.json(posts);
});
无法直接映射的部分
一些 Laravel 功能需要在 Node.js 中手动实现:
- 认证:Laravel 内置认证 → 使用 JWT、Passport.js 或自定义中间件
- 验证:Laravel FormRequest → 使用 Zod、Joi 或 express-validator
- 队列/任务:Laravel Queue → 使用 BullMQ 或 Cloudflare Queues
- 邮件:Laravel Mail → 使用 Nodemailer 或 Cloudflare Email
- Artisan 命令 → 自定义 npm 脚本或 Commander 等 CLI 框架
迁移策略
- 保持同一个数据库——Sutando 可以直接操作现有的 MySQL/PostgreSQL schema
- 逐路由迁移——用 Nginx 做反向代理分流
- 从只读路由开始——风险最低
- Session 放 Redis——PHP 和 Node 都能读取
- 不要一次性全部重写——绞杀者模式(strangler fig)是好方法
总结
从 Laravel 迁移到 Node.js 不意味着放弃 Eloquent。Sutando 带来了几乎相同的 Active Record 体验。你可以保持现有数据库 schema,逐路由迁移,团队从第一天就能高效工作。
从 npm install sutando 开始,查看文档。