跳转至

前端-模块解析-js文件覆盖ts导致导出缺失

问题现象

web/src/api/recommendation.ts 中新增 applyInitialization() 方法后,浏览器点击按钮报:

recommendationApi.applyInitialization is not a function
vue-tsc --noEmit 类型检查通过,文件内容正确,但运行时方法不存在。

核心问题

  • Vite 优先加载同名 .js 文件web/src/api/recommendation.tsweb/src/api/recommendation.js 同时存在。Vite 在模块解析时优先匹配 .js 扩展名(.js > .ts),导致运行时加载的是旧 .js 文件,新方法未包含其中。
  • .js 文件为未跟踪的遗留产物git ls-files web/src/api/*.js 返回空,说明这些 .js 文件是历史遗留的手写或工具生成的副本,不在版本控制中。
  • Vite HMR 不会使新导出生效:即使修改 .ts 文件触发 HMR,如果 .js 文件同时存在,Vite 仍从错误入口加载模块。

解决方法

  1. 扫描所有 ts/js 重复文件
cd web/src
find . -name "*.js" | while read js; do
  ts="${js%.js}.ts"
  if [ -f "$ts" ]; then echo "DUPLICATE: $js"; fi
done
  1. 删除不重复的 .js 文件(仅删未跟踪的):
# web/src/api/ (7 个)
rm web/src/api/cards.js web/src/api/favorites.js \
   web/src/api/fetch-records.js web/src/api/home.js \
   web/src/api/news.js web/src/api/recommendation.js \
   web/src/api/request.js

# web/src/composables/
rm web/src/composables/useKeyboardPagination.js

# web/src/
rm web/src/main.js

# web/src/router/
rm web/src/router/index.js

# web/src/utils/
rm web/src/utils/logger.js
  1. 清除 Vite 缓存并重启
rm -rf web/node_modules/.vite
cd web && pnpm dev
  1. 验证构建
cd web && pnpm build

下次防错措施

  1. 提交前检查重复文件:在 start.bat 或 CI 中加检查脚本:

    cd web/src
    find . -name "*.js" | while read js; do
      ts="${js%.js}.ts"
      if [ -f "$ts" ]; then
        echo "ERROR: 重复文件 -> $js 应删除"
        exit 1
      fi
    done
    

  2. 快速定位手段:遇到 "xxx is not a function" 但类型检查通过时,首先检查是否存在同名 .js/.ts 文件冲突。

  3. .gitignore 防御:在 web/.gitignore 中加 *.js,或在 web/src/.gitignore 中排除与 .ts 同目录的 .js,防止再次出现重复文件。