You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS机器人开发:加载命令目录子目录时ESM错误修复

问题:Node.js ESM 导入本地文件触发 ERR_UNSUPPORTED_ESM_URL_SCHEME 错误

我正在用Node.js开发机器人,想做一个帮助命令,命令文件按分类放在commands/slash目录的子文件夹(比如Moderation)里。当前代码如下:

import Command from "../../../structures/Command.js"
import { Embed } from "eris-addons"
import fs from "fs"
import { readdirSync } from "fs"
import path from "path"
import { join } from "path"

import { fileURLToPath } from "url"

const __dirname = path.dirname(fileURLToPath(import.meta.url));

// Map of category names to command objects
const categories = new Map();

// Load commands from the "commands/slash" folder and its subdirectories
const commandFolders = readdirSync(path.join(__dirname, '../'));
for (const folder of commandFolders) {
    const fullPath = path.join(__dirname, '../', folder);
    if (fs.lstatSync(fullPath).isDirectory()) {
        const commandFiles = fs.readdirSync(fullPath).filter((file) => file.endsWith('.js'));
        for (const file of commandFiles) {
            const filePath = path.join(fullPath, file);
            const { default: CommandClass } = await import(filePath);
            const command = new CommandClass();
            if (!categories.has(folder)) {
                categories.set(folder, []);
            }
            categories.get(folder).push(command);
        }
    }
}

运行时出现以下错误:

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'

错误来自const { default: CommandClass } = await import(filePath);这一行,请问如何修复?


解决方案

错误原因

ESM模块规范中,import()函数仅支持file:// 协议的URL或data URL。在Windows系统中,直接传入的本地绝对路径(如C:\xxx\command.js)会被Node.js误判为c:协议,不符合ESM导入要求,因此触发错误。

修复步骤

  1. 从url模块导入pathToFileURL方法,它可以将本地文件路径转换为合法的file:// URL。
  2. 修改导入语句,用pathToFileURL处理本地路径后再传入import()。

修改后的关键代码:

首先更新顶部的导入:

import { fileURLToPath, pathToFileURL } from "url"

然后替换原导入语句:

// 替换原有的 import(filePath) 行
const { default: CommandClass } = await import(pathToFileURL(filePath));

说明

pathToFileURL会自动适配系统路径格式:

  • 在Windows下,将C:\project\commands\slash\Moderation\kick.js转换为file:///C:/project/commands/slash/Moderation/kick.js
  • 在类Unix系统下,将/home/user/project/commands/slash/Moderation/kick.js转换为file:///home/user/project/commands/slash/Moderation/kick.js
    完全符合ESM导入的URL要求。

内容的提问来源于stack exchange,提问作者ETLegacy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 03:55:15