如何开发 Cheerio 插件?有哪些实用插件模式?
Cheerio 插件的核心模式是扩展 cheerio.prototype(即 $.fn),给选择器结果集添加自定义方法。基本写法:module.exports = function(cheerio) { cheerio.prototype.myMethod = function() { return this; } },然后 cheerio.use(pluginFn) 加载。插件方法内部通过 this 访问当前选中的元素集合,用 cheerio(el) 包装后即可调用所有原生方法。返回 this 支持链式调用,返回 .get() 则输出普通数组。
追问
插件方法怎么访问当前选中的元素?
方法内 this 就是 cheerio 对象,this.each((i, el) => ...) 遍历,cheerio(el) 包装单个元素。this.length 获取匹配数量,this[i] 直接取原生节点。
怎么让插件支持配置参数?
导出一个工厂函数而非直接函数:module.exports = (options) => (cheerio) => { ... },调用时 cheerio.use(myPlugin({ trim: true }))。内部用默认参数合并:const opts = { trim: true, ...options }。
有哪些实用的插件场景? 最常见三类:①文本清洗——批量 removeTags/cleanText,去掉 script/style/注释;②结构化提取——tableToArray 把表格转二维数组,tableToObjects 按表头生成对象数组;③URL 标准化——resolveUrls 把相对路径转绝对路径,处理懒加载 data-src。
插件方法和独立工具函数怎么选? 需要操作 DOM 节点、支持链式调用、依赖当前选择器上下文时用插件;纯数据转换、不涉及 DOM 操作时用普通函数。插件的优势是和 cheerio API 风格统一,缺点是污染原型。
开发插件要注意什么?
方法名加业务前缀避免冲突(如 seo_extractLinks 而非 extractLinks);返回 this 保持链式;用 try-catch 包裹核心逻辑防止异常中断;在 peerDependencies 声明 cheerio 版本。
写段代码
javascript// 表格转对象数组插件 module.exports = function(cheerio) { cheerio.prototype.tableToObjects = function() { const headers = this.find('th').map((i, el) => cheerio(el).text().trim()).get(); return this.find('tbody tr').map((i, tr) => { const obj = {}; cheerio(tr).find('td').each((j, td) => { obj[headers[j]] = cheerio(td).text().trim(); }); return obj; }).get(); }; };