Skip to content

Windows + Node.js v24 启动/编译时报 ERR_UNSUPPORTED_ESM_URL_SCHEME,疑似 UTS/uni_modules 解析链将绝对路径传给 ESM import #5991

@6iedog

Description

@6iedog

问题描述

在 Windows 环境下,使用 uni 启动项目(npm run dev)或通过 HBuilderX 编译时,Node.js v24 会抛出:

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 'd:'

从现象看,构建链中的某一处把 Windows 绝对路径(如 D:...)直接传给了 ESM import(),而不是先转换成 file:// URL。

复现环境

OS: Windows
Node.js: v24.10.0
包管理器: npm / pnpm

uni-app 相关版本(示例):
@dcloudio/uni-app: 3.0.0-5000620260331001
@dcloudio/vite-plugin-uni: 3.0.0-5000620260331001
@dcloudio/uni-cli-shared: 3.0.0-5000620260331001
vite: 5.2.8

复现步骤

在 Windows 上安装 Node.js v24
安装项目依赖
执行:
npm run dev
或在 HBuilderX 中运行/编译

编译开始后报错

实际结果

node:internal/modules/esm/load:183
    throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed, schemes);
          ^

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 'd:'
    at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:183:11)
    at defaultLoad (node:internal/modules/esm/load:78:3)
    at ModuleLoader.load (node:internal/modules/esm/loader:841:12)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:612:31)
    at #createModuleJob (node:internal/modules/esm/loader:643:36)
    at #getJobFromResolveResult (node:internal/modules/esm/loader:353:34)
    at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:318:41)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:685:25) {
  code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}

预期结果

在 Windows + Node.js v24 环境下,uni 启动和编译流程可以正常执行,不应因为 Windows 绝对路径被直接当作 ESM specifier 而失败。

初步定位

当前怀疑问题出在 @dcloudio/uni-cli-shared 的 UTS / uni_modules 解析链,与 Vite runtime 的 external import 组合触发。

  1. Vite runtime 中存在直接 external import
    node_modules/vite/dist/node/runtime.js
runExternalModule(filepath) {
  return import(filepath);
}

如果 filepath 是 D:... 这样的 Windows 绝对路径,Node.js v24 会直接抛出 ERR_UNSUPPORTED_ESM_URL_SCHEME。

  1. uni-cli-shared 中存在大量绝对路径解析与传播
    疑似相关文件:

@dcloudio/uni-cli-shared/dist/uts.js
@dcloudio/uni-cli-shared/dist/vite/plugins/uts/uni_modules.js
@dcloudio/uni-cli-shared/dist/easycom.js
例如:

@dcloudio/uni-cli-shared/dist/vite/plugins/uts/uni_modules.js

const module = resolveUTSAppModule(...);
if (module) {
  if (module.endsWith('.uts')) {
    return module;
  }
  return module + '?uts-proxy';
}

@dcloudio/uni-cli-shared/dist/easycom.js

if (path.isAbsolute(source) && source.startsWith(rootDir)) {
  source = '@/' + normalizePath(path.relative(rootDir, source));
}

从这些代码看,构建链里本身就存在 Windows 绝对路径进入模块解析流程的情况,但似乎不是所有分支都统一做了 @/ 或 file:// 转换。

临时绕过方式
目前可以通过 Node preload hook 在 ESM loader 层拦截并修复:

import { pathToFileURL } from 'node:url'

export function resolve(specifier, context, nextResolve) {
  if (/^[a-z]:[\\/]/i.test(specifier)) {
    return nextResolve(pathToFileURL(specifier).href, context)
  }
  return nextResolve(specifier, context)
}

但这只是绕过,不是根修,且在 HBuilderX 中不一定方便注入。

建议修复方向

建议在以下任一层统一处理 Windows 绝对路径:

在 @dcloudio/uni-cli-shared 中,避免将 D:... 直接作为 ESM import source 传递
在进入 external module import 前,对 Windows 绝对路径执行:
pathToFileURL(filepath).href
以兼容 Node.js v24 的 ESM loader 行为

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions