如何在SvelteKit中使用discord.js?解决require未定义错误
在SvelteKit中正确使用discord.js的解决方案
discord.js是Node.js专属库,依赖Node.js核心模块(如net、fs),无法在浏览器环境运行。SvelteKit默认将代码分为客户端/服务端执行逻辑,你必须把机器人的核心逻辑放到服务端专属代码文件中,才能避免之前的报错。
步骤1:正确安装依赖
确保将discord.js安装到生产依赖(而非开发依赖),因为服务端运行时需要它:
npm install discord.js
步骤2:将机器人逻辑放到服务端代码中
方式1:通过API路由初始化机器人
在src/routes/api/discord-bot/+server.js(TypeScript则用+server.ts)中编写代码,这是SvelteKit的服务端专用API路由:
// src/routes/api/discord-bot/+server.js import { Client, GatewayIntentBits } from 'discord.js'; import { DISCORD_TOKEN } from '$env/static/private'; // 全局实例化,避免每次请求重复创建Client let discordClient; export async function GET() { if (!discordClient) { discordClient = new Client({ intents: [GatewayIntentBits.Guilds] }); discordClient.on('ready', () => { console.log(`Discord机器人已登录:${discordClient.user.tag}`); }); // 用环境变量存令牌,不要硬编码 await discordClient.login(DISCORD_TOKEN); } return new Response(JSON.stringify({ status: '机器人运行中' }), { status: 200 }); }
启动SvelteKit后,访问/api/discord-bot即可触发机器人初始化。
方式2:启动SvelteKit时自动初始化机器人
如果希望启动项目时就运行机器人,可在服务端钩子文件src/hooks.server.js中编写:
// src/hooks.server.js import { Client, GatewayIntentBits } from 'discord.js'; import { DISCORD_TOKEN } from '$env/static/private'; let discordClient; export async function handle({ event, resolve }) { // 仅初始化一次机器人 if (!discordClient) { discordClient = new Client({ intents: [GatewayIntentBits.Guilds] }); discordClient.on('ready', () => console.log(`机器人已登录:${discordClient.user.tag}`)); await discordClient.login(DISCORD_TOKEN); } // 将机器人实例挂载到event.locals,方便其他服务端代码调用 event.locals.discordClient = discordClient; const response = await resolve(event); return response; }
为什么之前的方法失败?
- 直接在客户端组件(
.svelte文件)中使用import/require:discord.js依赖浏览器不存在的Node.js核心模块,Vite会因兼容性问题报错。 - 使用
createRequire:该方法依赖Node.js的module模块,而Vite为了浏览器兼容性,已将module模块外部化,客户端代码无法访问。
注意事项
- 所有discord.js相关逻辑必须放在服务端执行的文件中:API路由(
+server.js/ts)、服务端钩子(hooks.server.js/ts)、或标记为server-only的库文件。 - 务必用SvelteKit的环境变量管理Discord令牌,不要硬编码到代码中,避免泄露敏感信息。
内容的提问来源于stack exchange,提问作者Hyunduk Shin
相关产品推荐
相关产品推荐

