当我在 Linux 上运行我的代码时,它工作正常。但在具有相同 Node js 版本(18.18.0)的 Windows 上,我收到错误。
我使用现代 ES 导入,我的 package.json 有字符串
"type": "module"
。
我写了不和谐的机器人,这就是我所做的:
const rootDir = dirname(fileURLToPath(import.meta.url));
const commandsPath = join(rootDir, 'src', 'commands');
console.log('BEFORE FILTER');
const commandFiles = readdirSync(commandsPath).filter(file => file.endsWith('.js'));
console.log('BEFORE LOOP');
for (const file of commandFiles) {
console.log('BEFORE JOIN');
const filePath = join(commandsPath, file);
console.log('BEFORE AWAIT');
const command = await import(filePath);
console.log('SUCCESS');
// etc...
因此,如果我运行此代码,我会收到日志
BEFORE FILTER
、BEFORE LOOP
、BEFORE JOIN
、BEFORE AWAIT
和错误
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
我尝试更改
commandsPath
初始化:
const commandsPath = join('file:', rootDir, 'src', 'commands');
运行时会出现日志
BEFORE FILTER
和 ENOENT 错误,命令目录的路径正确
Error: ENOENT: no such file or directory, scandir 'file:\C:\Users\Correct\Path\To\src\commands'
如果我尝试
const commandsPath = fileURLToPath(join('file:', rootDir, 'src', 'commands'));
BEFORE FILTER
、BEFORE LOOP
、BEFORE JOIN
、BEFORE AWAIT
和第一个示例ERR_UNSUPPORTED_ESM_URL_SCHEME
错误
最后,如果我尝试
const commandsPath = fileURLToPath(join('file:', rootDir, 'src', 'commands'));
和
const command = await import(fileURLToPath(filePath));
BEFORE FILTER
、BEFORE LOOP
、BEFORE JOIN
、BEFORE AWAIT
和 TypeError [ERR_INVALID_URL_SCHEME]: The URL must be of scheme file
我该怎么办?
提前道歉,我无法测试它,因为我不在Windows上运行,我根据知识给出答案,希望我是对的。
要解决此问题,您需要修复
'file:\C:\Users\Correct\Path\To\src\commands'
中的 URL。file:///C:/Users/Correct/Path/To/src/commands
.
有两个区别,一是 3
/
而不是 1,二是 ''
。'
,虽然不那么愚蠢,但仍然是解决路径类型,但它就是这样。
要解决此问题,请使用
.href
并添加 \\
。在你最初的尝试中:
const rootDir = dirname(fileURLToPath(import.meta.url));
const commandsPath = join(rootDir, 'src', 'commands');
console.log('BEFORE FILTER');
const commandFiles = readdirSync(commandsPath).filter(file => file.endsWith('.js'));
console.log('BEFORE LOOP');
for (const file of commandFiles) {
console.log('BEFORE JOIN');
const filePath = join(commandsPath, file);
console.log('BEFORE URL CONVERSION');
const fileURL = new URL(`file://${filePath}`).href; // <- ** here **
console.log('BEFORE AWAIT');
const command = await import(fileURL);
console.log('SUCCESS');
// ... rest of your code
}
这次尝试
const commandsPath = join('file:', rootDir, 'src', 'commands');
应该是const commandsPath = join('file:\\', rootDir, 'src', 'commands').href;
。href
:const command = await import(filePath.href);