nodejs / nodejs/node

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

Abierto
#52,174 14 comentarios 6 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

doc
Lenguaje dominante
JavaScript
Estrellas
122k
Forks
37.3k
Merge medio
4 d 2 h
PR fusionados (30 d)
283

Descripción

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).

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la sección afectada «Dual package hazard» en nodejs.org/api/packages.html#dual-package-hazard y revisa las soluciones sugeridas existentes junto con la propuesta node/default de este issue. Se considera terminado cuando se haya llegado a un acuerdo sobre la recomendación y se haya actualizado correctamente esa sección de la documentación, incluido el comportamiento de CommonJS y ESM descrito aquí.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
javascript, node.js
Área
documentation
Tipo de issue
Documentación
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
52/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.