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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions