Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

added `devEngines` support breaks updating dependencies

Đang mở
#729 14 bình luận 6 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
52/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
nodejs, typescript
Lĩnh vực
tooling

Hướng nghiên cứu

Bắt đầu trong sources/specUtils.ts, đặc biệt là parsePackageJSON và lệnh gọi loadSpec đến parseSpec. Tái hiện lệnh corepack npm install đã được báo cáo với một package.json sử dụng devEngines.packageManager.version "^10", sau đó xác định cách xử lý nào trong các cách được đề xuất là cách intended. Hoàn tất khi các bản cập nhật dependency không còn từ chối các dải semver hợp lệ, trong khi các kiểm tra nghiêm ngặt đối với phiên bản đầy đủ vẫn hoạt động như được ghi rõ trong tài liệu.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

The recent devEngines support seems to cause errors with dependabot (all updates broken), this is an example but there are more packages like this:

Error running package manager command: corepack npm install vite@7.0.5 --force --dry-run false --ignore-scripts --package-lock-only
Error: Invalid package manager specification in package.json (npm@^10); expected a semver version
NPM : Invalid package manager specification in package.json (npm@^10); expected a semver version

Context:
Within our project we have this in the package.json:

"engines": {
    "node": "^20.11.0 || ^22 || ^24"
  },
  "devEngines": {
    "packageManager": {
      "name": "npm",
      "version": "^10",
      "onFail": "error"
    },
    "runtime": {
      "name": "node",
      "version": "^22",
      "onFail": "error"
    }
  }

(We support a wide range of engines - but for development devs should only use Node 22 and NPM 10 to have consistent compiled assets (and test results)).

I guess this is caused here: https://github.com/nodejs/corepack/pull/643/files#r2234021913


I see two ways to fix corepack:

  1. Only enforce strict version if a full version was passed, see patch:
diff --git a/sources/specUtils.ts b/sources/specUtils.ts
index edd5c7e..82c1435 100644
--- a/sources/specUtils.ts
+++ b/sources/specUtils.ts
@@ -77,47 +77,51 @@ function warnOrThrow(errorMessage: string, onFail?: DevEngineDependency[`onFail`
       console.warn(`! Corepack validation warning: ${errorMessage}`);
   }
 }
-function parsePackageJSON(packageJSONContent: CorepackPackageJSON) {
-  const {packageManager: pm} = packageJSONContent;
-  if (packageJSONContent.devEngines?.packageManager != null) {
-    const {packageManager} = packageJSONContent.devEngines;
-
-    if (typeof packageManager !== `object`) {
-      console.warn(`! Corepack only supports objects as valid value for devEngines.packageManager. The current value (${JSON.stringify(packageManager)}) will be ignored.`);
-      return pm;
+function parsePackageJSON({devEngines, packageManager}: CorepackPackageJSON) {
+  const spec = {
+    packageManager,
+    enforceExactVersion: true,
+  };
+
+  if (devEngines?.packageManager != null) {
+    const {packageManager: pm} = devEngines;
+
+    if (typeof pm !== `object`) {
+      console.warn(`! Corepack only supports objects as valid value for devEngines.packageManager. The current value (${JSON.stringify(pm)}) will be ignored.`);
+      return spec;
     }
-    if (Array.isArray(packageManager)) {
+    if (Array.isArray(pm)) {
       console.warn(`! Corepack does not currently support array values for devEngines.packageManager`);
-      return pm;
+      return spec;
     }
 
-    const {name, version, onFail} = packageManager;
+    const {name, version, onFail} = pm;
     if (typeof name !== `string` || name.includes(`@`)) {
       warnOrThrow(`The value of devEngines.packageManager.name ${JSON.stringify(name)} is not a supported string value`, onFail);
-      return pm;
+      return spec;
     }
     if (version != null && (typeof version !== `string` || !semverValidRange(version))) {
       warnOrThrow(`The value of devEngines.packageManager.version ${JSON.stringify(version)} is not a valid semver range`, onFail);
-      return pm;
+      return spec;
     }
 
     debugUtils.log(`devEngines.packageManager defines that ${name}@${version} is the local package manager`);
 
-    if (pm) {
-      if (!pm.startsWith?.(`${name}@`))
-        warnOrThrow(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the "devEngines.packageManager" field set to ${JSON.stringify(name)}`, onFail);
-
-      else if (version != null && !semverSatisfies(pm.slice(packageManager.name.length + 1), version))
-        warnOrThrow(`"packageManager" field is set to ${JSON.stringify(pm)} which does not match the value defined in "devEngines.packageManager" for ${JSON.stringify(name)} of ${JSON.stringify(version)}`, onFail);
-
-      return pm;
+    if (packageManager) {
+      if (!packageManager.startsWith?.(`${name}@`))
+        warnOrThrow(`"packageManager" field is set to ${JSON.stringify(packageManager)} which does not match the "devEngines.packageManager" field set to ${JSON.stringify(name)}`, onFail);
+      else if (version != null && !semverSatisfies(packageManager.slice(pm.name.length + 1), version))
+        warnOrThrow(`"packageManager" field is set to ${JSON.stringify(packageManager)} which does not match the value defined in "devEngines.packageManager" for ${JSON.stringify(name)} of ${JSON.stringify(version)}`, onFail);
+      return spec;
     }
 
-
-    return `${name}@${version ?? `*`}`;
+    return {
+      enforceExactVersion: semverValid(version),
+      packageManager: `${name}@${version ?? `*`}`,
+    };
   }
 
-  return pm;
+  return spec;
 }
 
 export async function setLocalPackageManager(cwd: string, info: PreparedPackageManagerInfo) {
@@ -233,11 +237,11 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
     process.env = selection.localEnv;
   }
 
-  const rawPmSpec = parsePackageJSON(selection.data);
-  if (typeof rawPmSpec === `undefined`)
+  const {enforceExactVersion, packageManager} = parsePackageJSON(selection.data);
+  if (typeof packageManager === `undefined`)
     return {type: `NoSpec`, target: selection.manifestPath};
 
-  debugUtils.log(`${selection.manifestPath} defines ${rawPmSpec} as local package manager`);
+  debugUtils.log(`${selection.manifestPath} defines ${packageManager} as local package manager`);
 
   return {
     type: `Found`,
@@ -249,6 +253,6 @@ export async function loadSpec(initialCwd: string): Promise<LoadSpecResult> {
       onFail: selection.data.devEngines.packageManager.onFail,
     },
     // Lazy-loading it so we do not throw errors on commands that do not need valid spec.
-    getSpec: () => parseSpec(rawPmSpec, path.relative(initialCwd, selection.manifestPath)),
+    getSpec: () => parseSpec(packageManager, path.relative(initialCwd, selection.manifestPath), {enforceExactVersion}),
   };
 }
  1. Ignore devEngines if it is a version range, see patch:
diff --git a/sources/specUtils.ts b/sources/specUtils.ts
index edd5c7e..183a62e 100644
--- a/sources/specUtils.ts
+++ b/sources/specUtils.ts
@@ -113,8 +113,9 @@ function parsePackageJSON(packageJSONContent: CorepackPackageJSON) {
       return pm;
     }
 
-
-    return `${name}@${version ?? `*`}`;
+    if (semverValid(version)) {
+      return `${name}@${version ?? `*`}`;
+    }
   }
 
   return pm;
Ngôn ngữ chính
TypeScript
Star
3.8k
Fork
279
Merge trung bình
1 giờ 47 phút
Pull request đã merge (30 ngày)
2

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nodejs/corepack

Tất cả issue của nodejs/corepack

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.