dcloudio / dcloudio/uni-app

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

Open
#5,991 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
41.6k
Forks
3.7k
Avg merge
7h 6m
Merged PRs (30d)
6

Description

## 问题描述

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

```txt
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 中运行/编译

编译开始后报错

## 实际结果

```txt
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。

2. 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 行为

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.