Discord Bot开发中两种module.exports函数导出方式的差异及TypeError问题解析
这是个很典型的CommonJS模块导出结构不匹配问题,咱们一步步拆解差异的根源:
第一种可正常运行的写法
你直接把commandMessage函数挂载到了module.exports的同名属性上:
module.exports.commandMessage = async(message, commandArgs) => { message.reply(`This is a test, it should work, maybe. Who knows? I hope.\n ${commandArgs._}`) .then(msg => { msg.delete({ timeout: 3000 }) }) .catch(console.error) }
此时module.exports的最终结构是:
{ commandMessage: [AsyncFunction] }
当你用const global = require('../global.js')引入后,global就是上面这个对象,所以global.commandMessage直接指向目标函数,调用自然没问题。
第二种无法运行的写法
你先定义了commandMessage函数,然后把它赋值给了module.exports.functions:
const commandMessage = async(message, commandArgs) => { message.reply(`This is a test, it should work, maybe. Who knows? I hope.\n ${commandArgs._}`) .then(msg => { msg.delete({ timeout: 3000 }) }) .catch(console.error) } module.exports.functions = commandMessage
这时候module.exports的结构变成了:
{ functions: [AsyncFunction] // 这里的functions就是commandMessage函数本身 }
而你调用的时候还是用global.commandMessage,但这个属性在导出的对象里根本不存在——global里只有functions属性,所以会抛出TypeError: global.commandMessage is not a function。
你后来尝试的global.functions.commandMessage也不对,因为functions本身就是那个异步函数,不是一个包含commandMessage属性的对象,所以这个子属性同样不存在。
如果想导出多个函数(你的原本需求)
如果你希望把通用函数都放在functions这个对象下导出,应该这样调整:
const commandMessage = async(message, commandArgs) => { message.reply(`This is a test, it should work, maybe. Who knows? I hope.\n ${commandArgs._}`) .then(msg => { msg.delete({ timeout: 3000 }) }) .catch(console.error) } // 可以添加更多通用函数 const anotherCommonFunc = () => { /* 逻辑 */ } module.exports.functions = { commandMessage, anotherCommonFunc }
此时module.exports的结构是:
{ functions: { commandMessage: [AsyncFunction], anotherCommonFunc: [Function] } }
调用的时候就可以用global.functions.commandMessage(message, commandArgs),完美匹配你原本想导出函数集合的需求。
内容的提问来源于stack exchange,提问作者Georgescu Rares Daniel

