DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

uuid/v1 报 ERR_PACKAGE_PATH_NOT_EXPORTED:改用包入口的命名导出

uuid 8 移除旧深层入口后,应从 uuid 包入口导入对应函数;核对真正的调用方和依赖版本,保留算法,并区分 uuid 12 起的 ESM 范围。

代码执行 require('uuid/v1') 后报 ERR_PACKAGE_PATH_NOT_EXPORTED,并指出 Package subpath './v1' is not defined by "exports",应先检查 uuid 的版本与旧导入写法。uuid 7 已弃用这种深层入口,uuid 8 移除了它;包里有对应实现文件,不代表调用方仍可通过 uuid/v1 访问。

这项限制来自包的公开入口契约。清空缓存或重新下载同一版本,不会让未导出的子路径变成合法入口;直接修改 node_modules 中的 exports 也容易在下次安装时丢失。

先找出哪段代码导入了旧子路径

查看报错栈中的调用文件,区分自己的代码与依赖内部代码。错误路径中的 node_modules/uuid/package.json 能帮助确定实际加载的是哪份 uuid;一个依赖树可能安装多份不同版本,不应只看项目根目录声明的版本。

如果自己的源码使用 uuid/v1 或 uuid/v4,修改调用方。若旧写法来自第三方包,应核对该包的维护版本和兼容依赖范围,升级或替换对应调用方;只在根目录再安装一份 uuid,未必会改变嵌套依赖实际加载的那份。

不要凭包名猜测一定是哪一个上游库造成。相同 ERR_PACKAGE_PATH_NOT_EXPORTED 也可能来自其他未导出的子路径,需要按完整路径及调用栈分别定位。

从包入口取得同一种 UUID 函数

以下是 ESM 项目中使用 v1 的局部示例,假定已安装与项目 Node 环境兼容的 uuid:

import { v1 as uuidv1 } from 'uuid';

const id = uuidv1();

这里保留了原来的 v1 算法。原代码使用 v4 时,才对应使用 v4 命名导出;不要只因常见示例是 v4 就顺手改变业务 ID 的生成方式。

对于仍使用支持 CommonJS 的 uuid 版本,例如既有 uuid 8 项目,可采用包入口的解构写法:

const { v1: uuidv1 } = require('uuid');

const id = uuidv1();

这只是已有兼容版本的迁移示例,不是在推荐新项目固定旧版。uuid 12 起不再支持 CommonJS,因此不能把这段 require 写法连同“升级到最新版”作为一条通用方案。需要升级到该范围时,应先安排 ESM 兼容与运行环境调整,再采用对应版本的公开 API。

命名导出和默认导出也应区分。把深层路径改成 import uuid from 'uuid',再调用 uuid.v1,并不符合 uuid 8 原生 ESM 的命名导出契约。应直接导入需要的函数,并核对原来传入的 options、buffer 等参数在目标版本中的含义。

不通过公开内部目录来绕过限制

Node 支持的 exports 会优先于 main 限定可访问入口,require 与 import 都受相应契约约束。给安装包随手添加 "./": "./dist/" 或删除 exports,会暴露包未承诺的内部布局,并不能修正依赖仍使用旧 API 的事实。

应用代码也不应改为绝对路径直读某台机器的 dist 文件。那会依赖安装目录、内部文件结构与打包结果,难以在 CI 或下一次升级中保持一致。

需要临时维护上游补丁时,应使用项目明确管理、可审查和可回退的补丁流程,修正实际导入方并验证其依赖范围。不要手工改 node_modules 后就把本机启动成功当作可重现的发布方案。

用干净安装验证修改,而不是只检查一台机器

调整前保存代码、包清单与锁文件,明确改动的是哪个调用方。依赖升级会改变解析结果,按项目正常流程审查锁文件与版本兼容性,不用无范围的批量升级掩盖这一个错误。

在隔离的开发或 CI 环境按锁文件完成安装,再执行原来失败的入口,确认栈中不再访问 uuid/v1 等移除路径。随后核对 ID 的版本、格式以及实际业务调用;加载成功不代表可以接受生成算法或参数语义的变化。

需要回退时恢复代码、依赖清单与锁文件,并重新安装一致的依赖。回退无法自动更改已经写入数据库或发给外部系统的 ID;若升级同时改变过生成规则,应单独核对这些已产生的数据。