nodejs / nodejs/node

Recommend `node`/`default` conditions instead of `require`/`import` as a solution to the dual package hazard

Đang mở
#52,174 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.

doc
Ngôn ngữ chính
JavaScript
Star
122k
Fork
37.3k
Merge trung bình
4 ngày 2 giờ
Pull request đã merge (30 ngày)
283

Mô tả

Affected URL(s)

https://nodejs.org/api/packages.html#dual-package-hazard

Description of the problem

Publishing packages with dual CommonJS and ESM sources, while has the benefits of supporting both CJS consumers and ESM-only platforms, is known to cause problems because Node.js might load both versions. Example:

package.json foo.cjs foo.mjs
{
  "name": "foo",
  "exports": {
    "require": "./foo.cjs",
    "import": "./foo.mjs"
  }
}
exports.object = {};     
export const object = {};     
package.json bar.js
{
  "name": "bar",
  "main": "./bar.js"
}
const foo = require("foo");
exports.object = foo.object;     
// my app

import { object as fooObj } from "foo";
import { object as barObj } from "bar";

console.log(fooObj === barObj); // false?????

The two suggested solutions boil down to "even when you have an ESM entrypoint, still use only CJS internallly". This solves the dual package hazard, but completely defeats the cross-platform benefits of dual modules.

If foo instead used these export conditions:

{
  "name": "foo",
  "exports": {
    "node": "./foo.cjs",
    "default": "./foo.mjs"
  }
}

Then:

  • there would be no dual-package hazard in Node.js, because it only ever loads the CommonJS version
  • there would be no dual-package hazard in bundlers, because they would only ever load either the node version (if they are configured to target Node.js) or the default version (if they are configured to target other platforms).
  • the package solves the dual-package hazard while still providing an ESM-only version

We have been using this node/default pattern in @babel/runtime for a couple years, because we wanted to provide an ESM-only version for browsers while still avoiding the dual-package hazard (@babel/runtime is mostly stateless, but @babel/runtime/helpers/temporalUndefined relies on object identity of an object defined in a separate file).

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.

Hướng nghiên cứu

Bắt đầu với phần “Dual package hazard” bị ảnh hưởng tại nodejs.org/api/packages.html#dual-package-hazard và xem xét các giải pháp được đề xuất hiện có cùng với đề xuất node/default trong issue này. Công việc được coi là hoàn tất khi đạt được sự thống nhất về khuyến nghị và cập nhật chính xác phần tài liệu đó, bao gồm cả hành vi của CommonJS và ESM được mô tả ở đây.

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

Đánh giá

Công nghệ
javascript, node.js
Lĩnh vực
documentation
Loại issue
Tài liệu
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
52/100

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.