关于 makepad-2.0-migration
供将 Makepad 1.x 应用迁移到 Makepad 2.0 的开发者参考,列出语法和 API 的对应变化,并说明迁移步骤、破坏性变更与常见错误。
主要功能
- 011.x 到 2.0 语法映射
- 02宏和 derive 更新
- 03生命周期方法变更
- 04运行时更新方式调整
- 05常见迁移错误及修复方法
适用场景
- 01将 live_design! 替换为 script_mod!
- 02更新控件 derive 和注册方式
- 03转换现有界面定义
- 04排查编译和布局问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ zhanghandong/ makepad-skills --skill makepad-2.0-migration安装后在 Claude Code 中输入/makepad-2.0-migration确认已加载。
附带文件references/migration-guide.md
详细介绍
Makepad 1.x 到 2.0 迁移技能
版本: makepad-widgets(dev 分支)| 最后更新: 2026-03-03
概述
Makepad 2.0 从编译时静态 DSL 转向运行时脚本,是一次根本性的架构变革。迁移涉及语法变更、derive 宏更新、生命周期方法重命名以及新的状态管理模式。
文档
详细文档请参阅本地文件:
./references/migration-guide.md- 包含示例的完整迁移参考
快速语法映射表
| Makepad 1.x | Makepad 2.0 | 说明 |
|---|---|---|
live_design! { ... } | script_mod! { ... } | 核心宏变更 |
<Widget> { ... } | Widget{ ... } | 不再使用尖括号 |
Key = Value | Key: value | 使用冒号,而非等号 |
(THEME_COLOR) | theme.color_* | 主题命名空间 |
live_body: { ... } | body +: { ... } | 合并运算符 |
#[derive(Live)] | #[derive(Script)] | derive 宏 |
#[derive(LiveHook)] | #[derive(ScriptHook)] | 生命周期钩子 |
#[derive(Widget)] | #[derive(Widget)] | 不变 |
before_apply() | on_before_apply() | 方法重命名 |
after_apply() | on_after_apply() | 方法重命名 |
apply_over!() | script_apply_eval!() | 运行时更新 |
DefaultNone | Default | 枚举默认值 |
LiveRegister | WidgetRegister | Widget 注册 |
live_register() | register_widget(vm) | 注册方法 |
LiveId | LiveId | 不变 |
分步迁移
第 1 步:替换宏
// OLD
live_design! {
import makepad_widgets::base::*;
import makepad_widgets::theme_desktop_dark::*;
App = {{App}} {
ui: <Root> { ... }
}
}
// NEW
script_mod! {
use mod.prelude.widgets.*
startup() do #(App::script_component(vm)){
ui: Root{
// ... UI definition
}
}
}
第 2 步:更新 Derive
// OLD
#[derive(Live, LiveHook, Widget)]
pub struct MyWidget { ... }
// NEW
#[derive(Script, ScriptHook, Widget)]
pub struct MyWidget { ... }
第 3 步:更新 App::run
// OLD
impl LiveRegister for App {
fn live_register(cx: &mut Cx) {
makepad_widgets::live_design(cx);
}
}
// NEW
impl App {
fn run(vm: &mut ScriptVm) -> Self {
crate::makepad_widgets::script_mod(vm);
App::from_script_mod(vm, self::script_mod)
}
}
第 4 步:重命名生命周期方法
// OLD
impl LiveHook for MyWidget {
fn before_apply(&mut self, cx: &mut Cx, ...) { ... }
fn after_apply(&mut self, cx: &mut Cx, ...) { ... }
}
// NEW
impl ScriptHook for MyWidget {
fn on_before_apply(&mut self, cx: &mut Cx, ...) { ... }
fn on_after_apply(&mut self, cx: &mut Cx, ...) { ... }
}
第 5 步:更新 DSL 语法
// OLD - angle brackets, equals signs
<View> {
width: Fill, height: Fill
show_bg: true
draw_bg: { color: (THEME_BG) }
title = <Label> {
text: "Hello"
draw_text: { color: #fff }
}
}
// NEW - curly braces, colons, theme namespace
View{
width: Fill height: Fill
show_bg: true
draw_bg.color: theme.color_bg_app
title := Label{
text: "Hello"
draw_text.color: #fff
}
}
第 6 步:将 apply_over 替换为 script_eval
// OLD
self.label(id!(title)).apply_over(cx, live! {
text: "New text"
});
// NEW
script_eval!(cx, {
ui.title.set_text("New text")
});
// OR
script_apply_eval!(cx, self.ui, {
title.text: "New text"
});
关键破坏性变更
- 属性之间不使用逗号(以空白分隔)
- Splash 中任何地方都不使用分号
- Widget 类型不使用尖括号
- 主题常量使用
theme.*前缀,而非(THEME_*)语法 - 命名子项使用
:=运算符,而非= - 合并运算符是
+:,而不是用于扩展父属性的: - 容器上必须设置
height: Fit(默认值为 0px,而不是 auto) - 注册发生在
App::run中,而不是live_register - 字段属性
#[source]链接到脚本对象(某些 Widget 必须设置) - 旧的
old/目录包含归档的 1.x 代码,可供参考
常见迁移错误
| 错误 | 现象 | 修复方法 |
|---|---|---|
仍在使用 live_design! | 编译错误 | 替换为 script_mod! |
使用 <Widget> 语法 | 解析错误 | 使用 Widget{} |
使用 Key = Value | 属性未生效 | 使用 Key: value |
使用 (THEME_COLOR) | 未知令牌 | 使用 theme.color_* |
缺少 height: Fit | 容器不可见(0px) | 添加 height: Fit |
使用 Live derive | 编译错误 | 使用 Script |
使用 before_apply | 找不到方法 | 使用 on_before_apply |
| 属性之间使用逗号 | 解析错误 | 删除逗号 |
迁移最佳实践
- 从示例开始 - 学习
examples/counter和examples/todo中的 2.0 模式 - 一次迁移一个 Widget - 不要试图一次性转换所有内容
- 检查 old/ 目录 - 对比新旧 Widget 实现
- 检查
height: Fit- 大多数 UI 不可见的问题都是由缺少高度导致的 - 使用主题变量 - 将所有硬编码的主题颜色替换为
theme.* - 添加
new_batch: true- 任何包含show_bg和文本子项的 View 都需要此设置
评论
支持 Markdown