旧版Revel(v0.1x)迁移核心是脱离GOPATH、启用Go Modules并适配v1.x运行机制:剪切项目至非GOPATH路径,删src/pkg/bin,go mod init设正确模块名,删app.conf中app.path,升级revel CLI至v1.1.0+,重写资源与数据库路径逻辑,更新拦截器注册为InterceptMethod,启用revel.watch=true。

旧版 Revel 项目(v0.1x)迁移到现代实践,核心不是“升级框架版本”,而是放弃 GOPATH 强依赖、启用 Go Modules,并替换掉已被废弃的路径约定和运行机制。直接运行 revel upgrade 或沿用 revel run 在 GOPATH 外会失败,这不是配置问题,是底层模型已淘汰。
确认你用的是真·旧版 Revel(v0.1x)
检查项目根目录是否存在 GOPATH/src/github.com/yourname/myapp/ 这类嵌套结构;运行 revel version 输出含 v0.1(如 v0.18.0);app.conf 里有 app.path= 且指向绝对路径——这些是典型旧版痕迹。新版 Revel(v1.x+)已原生支持 Modules,不再解析 app.path,也不再要求项目在 GOPATH 内。
停用 GOPATH,初始化 Go Modules
旧版项目几乎必然卡在 GOPATH 工作区里,迁移第一步是“物理脱离”:
- 把整个项目剪切到任意非 GOPATH 路径,例如
~/code/my-revel-app/ - 删除项目内所有
src/、pkg/、bin/目录(它们属于 GOPATH 时代产物) - 在项目根目录执行:
go mod init github.com/yourname/my-revel-app(模块名需与 import 路径一致) - 删掉
app.conf中的app.path行——它已被忽略,留着反而误导
此时 revel run 若报 module not found,说明 Revel CLI 版本太老;必须升级 CLI:go install github.com/revel/cmd/revel@latest。v1.1.0+ 的 CLI 才能识别 go.mod 并自动加载模块。
重写资源路径与数据库定位逻辑
旧版常靠 runtime.Caller(1) 获取 model.go 路径来拼 SQLite 文件名,这在 Modules + revel run 下必崩——调用栈指向 Revel 内部代码,不是你的文件。必须改用可执行体定位:
- 替换所有类似
filepath.Dir(runtime.Caller(1).File)的代码 - 改用:
execPath, _ := os.Executable(); rootDir := filepath.Dir(filepath.Dir(execPath))(假设二进制在rootDir/app,数据库放rootDir/data/foo.db) - 静态资源 URL(如
/public/js/app.js)若曾硬编码路径,需统一走 Revel 的Static路由或通过拦截器注入版本参数,避免缓存失效问题
Revel v1.x 不再自动挂载 public/ 到 /,要确认 routes 文件中仍有 GET /public/ static 类似路由,否则 404。
拦截器注册方式变更
旧版 app/init.go 里常见 revel.Intercept(..., revel.BEFORE) 直接传函数指针,v1.x 要求显式指定拦截时机和作用域:
- 把
revel.Intercept(controllers.SetVersion, revel.BEFORE)改为revel.InterceptMethod(controllers.SetVersion, revel.BEFORE) - 确保该行位于
revel.Harness.Init()之前,否则拦截器不生效 - 若用了自定义
Filter(非 Method 拦截器),需重写为revel.BuiltinFilter兼容格式,否则生命周期错乱
最易被忽略的是:v1.x 默认禁用 dev mode 的模板热重载,需在 conf/app.conf 显式设 revel.watch = true,否则改了 .html 模板要手动重启。


















