同Node.js版本的CentOS服务器中cheerio报'is not a function'错误排查求助
根据你描述的本地正常、同Node版本、重装依赖仍无效的情况,以下是几个值得深入排查的方向:
Cheerio版本不一致
虽然执行了npm install,但本地和服务器可能安装了不同版本的Cheerio。比如Cheerio v1.x之后的版本导出方式有明显变化:旧版本里cheerio本身是可直接调用的函数,但新版本默认导出的是包含load方法的对象,直接调用cheerio(sel)就会触发"not a function"错误。
排查方法:分别在本地和服务器执行npm list cheerio查看版本,若版本不同,在package.json中锁定Cheerio的具体版本(比如"cheerio": "^0.22.0"),再重新在服务器执行安装。全局变量污染
你的代码中$ = cheerio.load(s, { decodeEntities: true });没有用var/let/const声明,会把$挂载到全局对象上。CentOS的Node环境中,如果有其他模块或脚本修改了全局的$,或者Cheerio加载过程中出现异常,可能导致后续cheerio变量被意外覆盖。
解决办法:给$加上声明(比如const $ = cheerio.load(...)),同时检查代码中是否有其他可能修改cheerio变量的逻辑。npm安装完整性或缓存问题
即便删除了node_modules,服务器的npm缓存可能残留损坏的Cheerio包。另外,如果服务器安装依赖时权限不足(比如用非root用户安装导致部分目录无法写入),会造成Cheerio模块安装不完整,require时加载的模块导出不符合预期。
排查方法:在服务器执行npm cache clean --force清理缓存,再重新执行npm install;同时确保安装时使用的用户有足够权限,必要时可添加--unsafe-perm参数(谨慎使用)。Node.js环境的细微差异
虽然Node版本都是12.18.3,但本地和服务器的系统依赖(比如libuv版本、系统库)可能存在差异,导致Cheerio加载逻辑异常。另外,检查服务器是否启用了特殊Node启动参数(比如--experimental-modules),这会影响CommonJS模块的加载方式。
排查方法:在服务器运行一个简单的测试脚本对比本地输出:const cheerio = require('cheerio'); console.log(typeof cheerio); // 正常应为'function'或'object',取决于版本 console.log(cheerio); // 打印Cheerio的导出内容,和本地结果对比代码写法的版本兼容性问题
你的代码里用了cheerio(sel).find(selector),但sel已经是通过$('.text')获取的Cheerio对象。在新版本Cheerio中,直接用sel.find(selector)即可,不需要再用cheerio()包裹——这种写法在旧版本兼容,但新版本会因为cheerio不再是可调用函数而报错。尝试修改代码写法,看是否解决问题。
内容的提问来源于stack exchange,提问作者Martin Cup

