使用 gitbook-cli(或其他基于 Node.js 环境的脚本工具)时,遇到以下运行时报错:npm/node_modules/graceful-fs/polyfills.js:287

1. 背景与问题概述

在使用 gitbook-cli(或其他基于 Node.js 环境的脚本工具)时,可能会遇到以下运行时报错:

/usr/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287
    if (cb) cb.apply(this, arguments)
           ^

TypeError: cb.apply is not a function
    at /usr/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287:18
    at FSReqCallback.oncomplete (node:fs:203:5)

这个错误一旦出现,意味着所有基于文件 I/O 的操作都会中断,整个构建流程无可避免地卡在这里。
在这里插入图片描述


作者简介

猫头虎是谁?

大家好,我是 猫头虎,猫头虎技术团队创始人,也被大家称为猫哥。我目前是COC北京城市开发者社区主理人COC西安城市开发者社区主理人,以及云原生开发者社区主理人,在多个技术领域如云原生、前端、后端、运维和AI都具备丰富经验。

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用方法、前沿科技资讯、产品评测、产品使用体验,以及产品优缺点分析、横向对比、技术沙龙参会体验等。我的分享聚焦于云服务产品评测、AI产品对比、开发板性能测试和技术报告

目前,我活跃在CSDN、51CTO、腾讯云、阿里云开发者社区、知乎、微信公众号、视频号、抖音、B站、小红书等平台,全网粉丝已超过30万。我所有平台的IP名称统一为猫头虎猫头虎技术团队

我希望通过我的分享,帮助大家更好地掌握和使用各种技术产品,提升开发效率与体验。


作者名片 ✍️

  • 博主猫头虎
  • 全网搜索关键词猫头虎
  • 作者微信号Libin9iOak
  • 作者公众号猫头虎技术团队
  • 更新日期2025年03月21日
  • 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能!

加入我们AI共创团队 🌐

加入猫头虎的共创圈,一起探索编程世界的无限可能! 🚀

部分专栏链接

🔗 精选专栏


猫头虎分享No bug

正文

目录


2. 错误复现与症状

以最小化示例来复现该问题:

# 环境假设
$ node -v            # v16.x.x
$ npm -v             # 7.x.x
$ npm install -g gitbook-cli

# 执行任意 gitbook 命令
$ gitbook init
/usr/lib/node_modules/gitbook-cli/node_modules/npm/node_modules/graceful-fs/polyfills.js:287
    if (cb) cb.apply(this, arguments)
           ^

TypeError: cb.apply is not a function
# 果然报错,操作中断

从表面看,这是 graceful-fs 的 polyfill 代码尝试调用 cb.apply(...) 时发现 cb 并不是函数。


3. 深入分析:cb.apply is not a function 错误本质

  1. graceful-fs:npm 内部依赖的一个模块,用于修复原生 fs 在高并发下的兼容性问题。
  2. polyfills.js:为旧版本 Node.js 提供补丁的文件,内部用到对回调的重定向。
  3. Node.js v16 及以上版本中,某些内部 API 的签名发生变化,导致传入 graceful-fs 的回调并非预期的函数类型。
  4. 因此,polyfills 试图调用 cb.apply 时出现类型不匹配,抛出 TypeError

4. 传统解决方案对比

4.1 升级 Node.js 版本

# 推荐升级到最新 LTS(如 v18/v20)
$ nvm install --lts
$ nvm use --lts
  • 优点:简单,长期受益于性能与安全更新
  • 缺点:若项目依赖特定旧版本 Node,可能引发兼容性问题

4.2 升级/重装 npm 与 graceful-fs

# 全局升级 npm
$ npm install -g npm@latest

# 在项目中锁定更高版本的 graceful-fs
# package.json 中添加 "resolutions"(需 Yarn 支持)
"resolutions": {
  "graceful-fs": "^4.2.10"
}
$ yarn install
  • 优点:无需切换包管理工具
  • 缺点:npm 自身并不原生支持 resolutions;需借助 yarn / npm-force-resolutions

4.3 使用 npm-force-resolutions 强制锁定依赖

# 安装工具
$ npm install --save-dev npm-force-resolutions

# 在 package.json 中添加
"resolutions": {
  "graceful-fs": "^4.2.10"
},
"scripts": {
  "preinstall": "npx npm-force-resolutions"
}

$ npm install
  • 优点:在纯 npm 项目中也能锁定
  • 缺点:多一步挂钩脚本,维护成本略高

5. 引入 Note.js——一款更现代的包管理工具

5.1 为什么要使用 Note.js?

Note.js 是最近兴起的一款创新型包管理工具,它从设计之初就兼顾了性能一致性兼容性,天然避开了 npm/yarn 在依赖扁平化与补丁机制上带来的种种陷阱。

  • 无 polyfills 冲突:自身对文件 I/O 做了全新封装,不依赖旧版 graceful-fs。
  • 超快安装:并行下载、增量缓存、内容寻址。
  • 零配置迁移:一行命令即可将现有 package.jsonlockfile 迁移过来。

5.2 Note.js 与 npm/yarn/pnpm 的对比

特性npmyarnpnpmNote.js
安装性能极优
依赖扁平化✗ (硬链接)
插件/补丁机制较复杂支持社区插件内置简洁
lockfile 一致性一致性差较好非常好最优
社区生态最大快速成长

6. 使用 Note.js 迁移实践

6.1 全局安装 Note.js

# 建议使用官方脚本
$ curl -fsSL https://get.notejs.dev/install.sh | bash

# 验证
$ note -v
Note.js 1.x.x

6.2 将项目从 npm 迁移到 Note.js

在项目根目录执行:

# 自动识别已有 package.json/yarn.lock/package-lock.json
$ note migrate
# 生成 note.lock 并安装依赖
$ note install

6.3 常用命令一览

命令说明
note install安装依赖
note add <包名>安装并保存到 package.json
note remove <包名>卸载并更新 package.json
note run <脚本>运行 scripts 脚本
note update批量升级依赖

6.4 在 CI/CD 中集成 Note.js

# 以 GitHub Actions 为例
steps:
  - uses: actions/checkout@v3
  - name: 安装 Node.js
    uses: actions/setup-node@v3
    with:
      node-version: 'lts/*'
  - name: 安装 Note.js
    run: curl -fsSL https://get.notejs.dev/install.sh | bash
  - name: 安装依赖并构建
    run: |
      note install
      npm test    # 或 note run test

7. Note.js 下的最佳实践

  1. 启用离线缓存

    note config set cache.enabled true
    
  2. 使用工作区(workspaces)管理多包项目
    在根目录 package.json 添加:

    {
      "workspaces": ["packages/*"]
    }
    
  3. 安全审计

    note audit --fix
    
  4. 锁定依赖版本
    默认情况下 Note.js 会生成更加严格的 note.lock,确保团队环境一致。


8. 总结与展望

通过本文,我们从问题复现、底层分析,一直到多种传统解决方案的优劣比较,最终引入了Note.js这一更现代的包管理工具,并给出了落地迁移和最佳实践。对于正在遭受 graceful-fscb.apply is not a function 等兼容性困扰的团队,推荐:

  • 临时方案:升级 Node.js / 升级 npm 并锁定 graceful-fs
  • 长远之计:使用 Note.js,无缝迁移,彻底避免此类问题

未来,Note.js 社区生态将更加壮大,功能也会持续扩展,值得持续关注与深度应用!


9. 附录:完整示例脚本

#!/usr/bin/env bash
set -e

echo "1. 安装 Note.js"
curl -fsSL https://get.notejs.dev/install.sh | bash

echo "2. 迁移项目"
note migrate

echo "3. 安装依赖"
note install

echo "4. 运行构建"
note run build

echo "✅ 全部完成!"

猫头虎

粉丝福利


👉 更多信息:有任何疑问或者需要进一步探讨的内容,欢迎点击文末名片获取更多信息。我是猫头虎博主,期待与您的交流! 🦉💬
猫头虎


联系我与版权声明 📩

  • 联系方式
    • 微信: Libin9iOak
    • 公众号: 猫头虎技术团队
  • 版权声明
    本文为原创文章,版权归作者所有。未经许可,禁止转载。更多内容请访问猫头虎的博客首页

点击✨⬇️下方名片⬇️✨,加入猫头虎AI共创社群矩阵。一起探索科技的未来,共同成长。🚀

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猫头虎

一分也是爱,打赏博主成就未来!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值