重构代码遇错:如何实现单输入函数返回三参数供md.use()调用?
解决markdown-it容器插件的函数封装问题
我懂你想精简代码的需求!把重复的配置逻辑抽成单输入函数确实能让代码更整洁,而且刚好md.use()支持展开数组参数,完美适配你的需求。
先看一下你原本能正常运行的代码(方便对照):
md.use(require('markdown-it-container'), 'warning', { render: function (tokens, idx) { var m = tokens[idx].info.trim().match(/^warning\s+(.*)$/); if (tokens[idx].nesting === 1) { return '<div class="warning-block"><p class="warning-title">' + md.utils.escapeHtml(m[1]) + '</p>\n'; } else { return '</div>\n'; } } });
核心思路
md.use()的调用格式是md.use(插件模块, 容器名称, 配置对象),我们可以写一个只接受单个输入参数的工厂函数,让它返回包含这三个元素的数组,然后用ES6的扩展运算符...把数组展开传入md.use(),就能实现你的需求。
实现方案
比如你想让函数接收容器名称作为唯一输入(这样可以快速创建不同名称的容器插件),代码可以这么写:
// 单输入的容器插件工厂函数 function createContainer(containerName) { // 返回md.use需要的三个参数组成的数组 return [ require('markdown-it-container'), containerName, { render: function (tokens, idx) { // 动态匹配容器名称,避免硬编码 var m = tokens[idx].info.trim().match(new RegExp(`^${containerName}\\s+(.*)$`)); if (tokens[idx].nesting === 1) { // 动态生成类名,保持样式和容器名称一致 return `<div class="${containerName}-block"><p class="${containerName}-title">${md.utils.escapeHtml(m[1])}</p>\n`; } else { return '</div>\n'; } } } ]; } // 调用方式:展开数组传入md.use md.use(...createContainer('warning'));
自定义扩展
如果你的单输入不是容器名称,而是其他配置项(比如自定义标题前缀、样式类名),也可以灵活调整函数:
// 比如输入是标题前缀 function createWarningContainer(titlePrefix) { const containerName = 'warning'; return [ require('markdown-it-container'), containerName, { render: function (tokens, idx) { var m = tokens[idx].info.trim().match(/^warning\s+(.*)$/); if (tokens[idx].nesting === 1) { return `<div class="warning-block"><p class="warning-title">${titlePrefix}${md.utils.escapeHtml(m[1])}</p>\n`; } else { return '</div>\n'; } } } ]; } // 使用时传入前缀 md.use(...createWarningContainer('⚠️ '));
可能踩的坑
- 一定要用扩展运算符
...展开数组,不然md.use()会把整个数组当成第一个参数,直接报错。 - 确保
md变量在工厂函数内部是可访问的(比如把函数定义在md初始化之后,或者如果不需要md.utils.escapeHtml,可以换成原生的转义逻辑)。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

