useModel 无法加载自定义 model(@fesjs/utils 中 @babel/traverse CJS/ESM 互操作问题)
问题描述
自定义 model 无法通过 useModel 加载。项目 src/models/ 下已有模型文件(如 districtTreeModel.js),但运行时调用
useModel('districtTreeModel')
抛出异常:
模型 "districtTreeModel" 不存在。
可用的模型有: @@initialState
请检查模型名称是否正确,或确认模型文件是否已正确导出。
即 fes-plugin-model 在 onGenerateFiles 阶段扫描 src/models 时未能将自定义模型注册进生成的 core.js(注册表中只有 @@initialState),导致所有自定义 model 不可用。
排查后定位根因在 @fesjs/utils@4.0.1 的产物 dist/index.mjs:
import traverse from "@babel/traverse";
@babel/traverse 是 CJS 模块,在 Node 原生 ESM 中 default 导入拿到的是 module.exports 对象(真实函数在其 .default 属性上)而非函数本身,导致 model 扫描解析所依赖的 traverse 不可用,自定义模型注册失败。
目前通过 pnpm patch 临时修复(patches/@fesjs__utils@4.0.1.patch):
-import traverse from "@babel/traverse";
+import traverse_import from "@babel/traverse";
+var traverse = Object.assign(traverse_import.default || traverse_import, traverse_import);
打完补丁后重启 fes dev,core.js 正常生成自定义模型,useModel('districtTreeModel') 恢复正常。
建议在 @fesjs/utils 源码(packages/utils)中对 @babel/traverse 的导入做 CJS/ESM 互操作兼容(traverse.default || traverse),避免使用方各自打补丁。
环境描述/版本信息
- OS: Windows 11 22H2
- Browser: 不涉及(根因在 Node 侧 model 扫描,与浏览器无关)
- Node: v22.17.0
- fes: @fesjs/fes@4.0.1(@fesjs/utils@4.0.1、@fesjs/plugin-model@4.0.x)
- 包管理器: pnpm 10.20.0
- 项目 package.json:
{
"name": "@fesjs/template",
"version": "0.0.1",
"private": true,
"type": "module",
"scripts": {
"build": "fes build",
"dev": "fes dev"
},
"dependencies": {
"@fesjs/builder-vite": "^5.0.0",
"@fesjs/fes": "^4.0.0",
"@fesjs/plugin-access": "^4.0.0",
"@fesjs/plugin-enums": "^4.0.0",
"@fesjs/plugin-login": "^4.0.1",
"@fesjs/plugin-model": "^4.0.0",
"@fesjs/plugin-request": "^4.0.0",
"vue": "^3.5.17"
},
"pnpm": {
"patchedDependencies": {
"@fesjs/utils@4.0.1": "patches/@fesjs__utils@4.0.1.patch"
}
}
}
如何复现
- 使用 pnpm 创建 fes 4.x 项目,
package.json 设置 "type": "module",安装 @fesjs/fes、@fesjs/plugin-model(此时 @fesjs/utils 解析到 4.0.1)
- 在
src/models/ 下新增自定义模型文件,如 districtTreeModel.js(默认导出一个组合式函数)
- 执行
pnpm dev(即 fes dev),启动时 plugin-model 扫描 src/models 生成 core.js
- 页面中调用
useModel('districtTreeModel'),抛出"模型不存在,可用的模型有: @@initialstate",自定义 model 加载失败
预期结果
无需打补丁,fes dev 启动后 src/models 下的自定义模型能正常注册进 core.js,useModel('districtTreeModel') 可以正常加载并返回模型实例。即 @fesjs/utils 内部对 @babel/traverse(CJS 模块)的导入应正确处理 Node ESM 的 default 导出互操作(traverse.default || traverse)。
useModel 无法加载自定义 model(@fesjs/utils 中 @babel/traverse CJS/ESM 互操作问题)
问题描述
自定义 model 无法通过
useModel加载。项目src/models/下已有模型文件(如districtTreeModel.js),但运行时调用抛出异常:
即
fes-plugin-model在onGenerateFiles阶段扫描src/models时未能将自定义模型注册进生成的core.js(注册表中只有@@initialState),导致所有自定义 model 不可用。排查后定位根因在
@fesjs/utils@4.0.1的产物dist/index.mjs:@babel/traverse是 CJS 模块,在 Node 原生 ESM 中 default 导入拿到的是module.exports对象(真实函数在其.default属性上)而非函数本身,导致 model 扫描解析所依赖的traverse不可用,自定义模型注册失败。目前通过 pnpm patch 临时修复(
patches/@fesjs__utils@4.0.1.patch):打完补丁后重启
fes dev,core.js正常生成自定义模型,useModel('districtTreeModel')恢复正常。建议在
@fesjs/utils源码(packages/utils)中对@babel/traverse的导入做 CJS/ESM 互操作兼容(traverse.default || traverse),避免使用方各自打补丁。环境描述/版本信息
{ "name": "@fesjs/template", "version": "0.0.1", "private": true, "type": "module", "scripts": { "build": "fes build", "dev": "fes dev" }, "dependencies": { "@fesjs/builder-vite": "^5.0.0", "@fesjs/fes": "^4.0.0", "@fesjs/plugin-access": "^4.0.0", "@fesjs/plugin-enums": "^4.0.0", "@fesjs/plugin-login": "^4.0.1", "@fesjs/plugin-model": "^4.0.0", "@fesjs/plugin-request": "^4.0.0", "vue": "^3.5.17" }, "pnpm": { "patchedDependencies": { "@fesjs/utils@4.0.1": "patches/@fesjs__utils@4.0.1.patch" } } }如何复现
package.json设置"type": "module",安装@fesjs/fes、@fesjs/plugin-model(此时@fesjs/utils解析到 4.0.1)src/models/下新增自定义模型文件,如districtTreeModel.js(默认导出一个组合式函数)pnpm dev(即fes dev),启动时 plugin-model 扫描src/models生成core.jsuseModel('districtTreeModel'),抛出"模型不存在,可用的模型有: @@initialstate",自定义 model 加载失败预期结果
无需打补丁,
fes dev启动后src/models下的自定义模型能正常注册进core.js,useModel('districtTreeModel')可以正常加载并返回模型实例。即@fesjs/utils内部对@babel/traverse(CJS 模块)的导入应正确处理 Node ESM 的 default 导出互操作(traverse.default || traverse)。