关于 frappe-ops-app-lifecycle
面向 Frappe 应用开发者的应用生命周期操作参考,涵盖从脚手架创建到安装、调试、迁移、发布和更新的流程。内容也说明开发与生产模式的差异及版本相关做法。
主要功能
- 01创建应用脚手架
- 02从 Git 获取并安装应用
- 03迁移数据模型与构建资源
- 04使用控制台调试
- 05管理补丁与应用版本
适用场景
- 01启动新的 Frappe 应用项目
- 02将应用安装到目标站点
- 03代码变更后迁移并构建
- 04准备应用更新或发布
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ impertio-studio/ frappe_claude_skill_package --skill frappe-ops-app-lifecycle安装后在 Claude Code 中输入/frappe-ops-app-lifecycle确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/.gitkeepanti-patterns.mdexamples.mdmodule-workspace-shipping.mdworkflows.md详细介绍
应用生命周期管理
快速参考
| 命令 | 用途 | 使用时机 |
|---|---|---|
bench new-app | 搭建新应用框架 | 启动新项目时 |
bench get-app URL | 从 Git 克隆 | 安装现有应用时 |
bench --site SITE install-app | 在站点上安装 | 执行 get-app 或 new-app 后 |
bench --site SITE remove-app | 从站点卸载 | 从站点移除应用时 |
bench remove-app | 从 bench 移除 | 完全移除应用时 |
bench --site SITE migrate | 运行补丁并同步 | 代码变更后 |
bench build | 编译资源 | JS/CSS 变更后 |
bench --site SITE console | Python REPL | 调试时 |
bench start | 启动开发服务器 | 开发时 |
bench setup production | 配置 nginx+supervisor | 部署到生产环境时 |
1. 搭建框架:bench new-app
bench new-app my_custom_app
交互式提示:
- App Title → 易读的名称
- App Description → 单行简介
- App Publisher → 公司/作者名称
- App Email → 联系邮箱
- App Icon → 默认值:
octicon octicon-file-directory - App Color → 默认值:
grey - App License → 默认值:
MIT
生成的目录结构
apps/my_custom_app/
├── MANIFEST.in # Files included in Python package
├── README.md # Project readme
├── license.txt # License file
├── requirements.txt # Python dependencies
├── dev-requirements.txt # Dev-only Python deps (v15+)
├── package.json # Node.js dependencies
├── setup.py # Python package config (v14)
├── pyproject.toml # Python package config (v15+)
├── my_custom_app/
│ ├── __init__.py # App version string
│ ├── hooks.py # Framework integration hooks
│ ├── modules.txt # List of app modules
│ ├── patches.txt # Migration patches list
│ ├── config/
│ │ ├── __init__.py
│ │ ├── desktop.py # Desktop/workspace config
│ │ └── docs.py # Documentation config
│ ├── public/ # Static assets → /assets/my_custom_app/
│ │ ├── css/
│ │ └── js/
│ ├── templates/ # Jinja templates
│ └── www/ # Portal pages (URL = path)
各核心文件的作用
| 文件 | 用途 | 千万别忘 |
|---|---|---|
__init__.py | 定义 __version__ | 发布前务必更新 |
hooks.py | 所有框架集成 | 一切功能的入口 |
modules.txt | 声明应用模块 | 务必在此添加新模块 |
patches.txt | 迁移补丁注册表 | 务必按顺序添加补丁 |
requirements.txt | 安装时安装的 Python 依赖 | 在此添加 pip 包 |
public/ | 由 nginx 提供的静态文件 | 可通过 /assets/app_name/ 访问 |
www/ | 门户页面 | 文件名 = URL 路径 |
2. 开发周期
Code → Migrate → Build → Test → Commit
分步说明
# 1. Make code changes (DocTypes, reports, APIs, etc.)
# 2. Migrate — sync DocType schema + run patches
bench --site mysite migrate
# 3. Build — compile JS/CSS assets
bench build --app my_custom_app
# 4. Test — run Python tests
bench --site mysite run-tests --app my_custom_app
# 5. Commit
git -C apps/my_custom_app add -A && git -C apps/my_custom_app commit -m "feat: add feature"
修改 DocType JSON 文件后,务必运行 bench migrate。
修改 JS/CSS 文件后,务必运行 bench build。
3. 从 Git 获取应用
# Public repo
bench get-app https://github.com/org/my_app
# Specific branch
bench get-app https://github.com/org/my_app --branch develop
# Private repo via SSH
bench get-app [email protected]:org/private_app.git
# Private repo via token (v15+)
bench get-app https://[email protected]/org/private_app.git
执行 get-app 后,务必在目标站点上安装:
bench --site mysite install-app my_app
get-app 会将应用克隆到 apps/,并添加到 apps.txt。
install-app 会创建数据库表并运行 after_install 钩子。
4. 安装和移除应用
安装顺序很重要
应用会按照 apps.txt 中列出的顺序安装。如果应用 B 依赖应用 A,应用 A 必须列在前面。
# Install
bench --site mysite install-app my_app
# Verify
bench --site mysite list-apps
# Output: frappe, erpnext, my_app
# Remove from site (keeps code in apps/)
bench --site mysite remove-app my_app
# Remove from bench entirely (deletes code)
bench remove-app my_app
应用依赖(v14+)
在 hooks.py 中声明:
required_apps = ["frappe", "erpnext"]
安装期间,Frappe 务必检查 required_apps,并在缺少依赖项时阻止安装。
5. 使用 bench console 调试
bench --site mysite console
打开带有 Frappe 上下文的 IPython REPL:
# Query data
frappe.db.sql("SELECT name, status FROM `tabSales Invoice` LIMIT 5", as_dict=True)
# Get a document
doc = frappe.get_doc("Sales Invoice", "SINV-00001")
print(doc.grand_total)
# Test a whitelisted method
from my_app.api import my_function
result = my_function(param="value")
# Check configuration
frappe.get_site_config()
# Auto-reload on code changes (v15+)
# Start with: bench --site mysite console --autoreload
调试时务必使用 bench console——切勿使用原始 SQL 修改生产数据。
6. 开发模式与生产模式
开发模式
# Enable
bench set-config -g developer_mode 1
# Start dev server (Procfile: web + worker + redis + socketio)
bench start
开发模式支持:
- 在 Desk 中编辑 DocType
- 报表/脚本的“Is Standard”选项
- Python 文件变更时自动重新加载
- 在浏览器中显示详细错误回溯
- 安装
dev-requirements.txt中的依赖项
生产模式
# Disable developer mode
bench set-config -g developer_mode 0
# Setup production (nginx + supervisor)
sudo bench setup production USERNAME
# Restart
sudo supervisorctl restart all
# or
sudo systemctl restart supervisor
生产模式:
- 通过 nginx 提供服务(端口 80/443)
- 通过 supervisor 运行后台工作进程
- 由 nginx 直接提供静态文件
- 错误记录到文件中,而不是浏览器中
- 生产站点上切勿启用
developer_mode
7. 构建资源
v15+(esbuild)
# Build all apps
bench build
# Build specific app
bench build --app my_custom_app
# Watch mode (auto-rebuild on changes)
bench watch
v14(build.json)
v14 使用应用根目录中的 build.json 将源文件映射到打包文件:
{
"css/my_app.css": [
"public/css/style.css"
],
"js/my_app.js": [
"public/js/main.js"
]
}
在 hooks.py 中引入资源
# Desk (backend UI)
app_include_js = "my_app.bundle.js" # v15+ bundle syntax
app_include_css = "my_app.bundle.css"
# Portal (website)
web_include_js = "my_app_web.bundle.js"
web_include_css = "my_app_web.bundle.css"
# v14 legacy syntax
app_include_js = "/assets/my_app/js/my_app.js"
app_include_css = "/assets/my_app/css/my_app.css"
更改 JS/CSS 文件后,务必运行 bench build。
如果资源没有更新,务必运行 bench clear-cache。
8. 应用版本控制
init.py 中的版本字符串
# my_custom_app/__init__.py
__version__ = "1.2.0"
务必使用语义化版本号:MAJOR.MINOR.PATCH
- MAJOR:不兼容的变更
- MINOR:新功能(向后兼容)
- PATCH:错误修复
bench version 会读取该版本号,它也会显示在 Desk 中并用于 Marketplace。
检查版本
bench version
# frappe 15.23.0
# erpnext 15.18.0
# my_custom_app 1.2.0
9. 补丁:数据迁移
编写补丁
# my_app/patches/v1_2/update_customer_status.py
import frappe
def execute():
frappe.reload_doc("module_name", "doctype", "customer_extension")
frappe.db.sql("""
UPDATE `tabCustomer Extension`
SET status = 'Active'
WHERE status IS NULL
""")
frappe.db.commit()
在 patches.txt 中注册
# patches.txt — v14+ supports sections
[pre_model_sync]
my_app.patches.v1_1.fix_old_data
my_app.patches.v1_2.rename_field_before_schema
[post_model_sync]
my_app.patches.v1_2.update_customer_status
my_app.patches.v1_2.migrate_settings
执行时机(v14+):
[pre_model_sync]— 在应用 DocType 架构更改之前运行[post_model_sync]— 在应用架构更改之后运行(新字段已可用)- 无分区标题 — 默认在
[pre_model_sync]中运行
补丁规则
- 始终将新补丁添加到所属分区的末尾
- 补丁只运行一次 — 记录在
tabPatch Log中 - 如需重新运行补丁,追加注释:
my_app.patches.v1_2.fix #2025-03-20 - 访问新增或修改的 DocType 前,始终调用
frappe.reload_doc() - 需要使用新字段的补丁,始终放在
[post_model_sync]中 - 单行补丁:
execute:frappe.delete_doc("Page", "old-page", ignore_missing=True)
测试补丁
# Run all pending patches
bench --site mysite migrate
# Run a specific patch manually in console
bench --site mysite console
>>> from my_app.patches.v1_2.update_customer_status import execute
>>> execute()
>>> frappe.db.commit()
10. 发布到 Frappe Marketplace
前置条件清单
- 应用托管在公开的 GitHub 仓库中
setup.py或pyproject.toml中包含正确的元数据__init__.py中包含有效的__version__- README.md 中包含安装说明
- 所有测试均通过
setup.py(v14)
from setuptools import setup, find_packages
setup(
name="my_custom_app",
version="1.0.0",
description="My Custom App for ERPNext",
author="Your Name",
author_email="[email protected]",
packages=find_packages(),
zip_safe=False,
include_package_data=True,
install_requires=["frappe"],
)
pyproject.toml(v15+)
[project]
name = "my_custom_app"
dynamic = ["version"]
requires-python = ">=3.10,<3.13"
dependencies = ["frappe"]
[build-system]
requires = ["flit_core >=3.4,<4"]
build-backend = "flit_core:buildapi"
发布步骤
- 在 https://frappecloud.com/marketplace 创建账户
- 添加你的 GitHub 仓库
- 配置支持的版本(v14、v15)
- 提交审核
- 审核通过后,应用会显示在 Marketplace 中
11. 客户站点上的应用更新生命周期
# Pull latest code
bench update --pull
# Or update specific app
cd apps/my_custom_app && git pull origin main && cd ../..
# Then migrate (runs patches + syncs schema)
bench --site mysite migrate
# Rebuild assets
bench build --app my_custom_app
# Restart workers
bench restart
bench update 命令依次执行:备份 → 拉取 → 安装依赖 → 迁移 → 构建 → 重启。
在生产环境运行 bench update 前,务必进行备份。
将更新应用到生产环境前,务必先在预发布环境中测试。
另请参阅
- references/examples.md — 完整的应用脚手架示例
- references/anti-patterns.md — 常见错误
- references/workflows.md — 分步工作流
- references/module-workspace-shipping.md — Module Def、modules.txt 和工作区交付
frappe-syntax-hooks— 完整的 hooks.py 参考frappe-core-database— 数据库和迁移模式frappe-impl-workspace— 工作区构建器、组件和自定义