¿Por qué TypeScript importa CommonJS en lugar de ESM?
Seguí este tutorial para crear un paquete dual. Así es como se ve la estructura de archivos del paquete:
my-awesome-lib
package.json
dist
|-- mjs
|-- package.json
|-- index.js
|-- cjs
|-- package.json
|-- index.js
En package.json
:
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
"exports": {
".": {
"require": "./dist/cjs/index.js",
"import": "./dist/mjs/index.js"
}
},
El package.json
en la carpeta mjs
:
{
"type": "module"
}
El package.json
en la carpeta cjs
:
{
"type": "commonjs"
}
En mi aplicación de TypeScript, instalé mi propio paquete e intenté importarlo. Sin embargo, observé algo extraño:
// src/index.ts
import { Class } from 'my-awesome-lib'
import { Class } from '../node_modules/my-awesome-lib/dist/mjs/index.js';
La primera declaración de importación apunta a ../node_modules/my-awesome-lib/dist/cjs/index.js
en lugar de la carpeta mjs
. La segunda declaración de importación es la que realmente quiero.
¿Alguien puede decirme qué salió mal? ¿Es porque publiqué mi biblioteca de manera incorrecta?
P.D.
Este es mi tsconfig.json
:
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"moduleResolution": "node",
"outDir": "dist"
},
"include": ["src"]
}
P.D. Agregar "type": "module"
al package.json
de la aplicación tampoco hace que este error desaparezca.
davy.ai
El problema que estás enfrentando se debe al hecho de que tu archivo
tsconfig.json
tiene definido"module": "es2020"
, lo cual significa que tu compilador de TypeScript generará módulos ECMAScript (ES modules) en lugar de módulos CommonJS. Sin embargo, el archivopackage.json
de tu librería está configurado para utilizar CommonJS en el directorio"cjs"
y ES modules en el directorio"mjs"
.Cuando importas tu librería usando
import { Clase } from 'mi-librería-asombrosa'
, Node.js busca un módulo CommonJS (debido a su comportamiento por defecto) y encuentra../node_modules/mi-librería-asombrosa/dist/cjs/index.js
en lugar de../node_modules/mi-librería-asombrosa/dist/mjs/index.js
. Esto ocurre porque la propiedad"main"
en elpackage.json
de la librería está definida como"dist/cjs/index.js"
.Para solucionar este problema, debes cambiar la propiedad
"main"
de tu librería a"dist/mjs/index.js"
. Esto hará que Node.js busque por defecto la versión de tu librería en formato ES module. Sin embargo, ten en cuenta que este cambio solo afectará el comportamiento de importación por defecto. Si deseas importar explícitamente la versión CommonJS, aún podrás hacerlo medianteimport { Clase } from '../node_modules/mi-librería-asombrosa/dist/cjs/index.js'
.Además, agregar
{ "type": "module" }
alpackage.json
de tu aplicación no ayudará a resolver este problema, ya que esta configuración solo afecta la forma en que Node.js carga y analiza los archivos de módulos, no cómo tu compilador de TypeScript compila tu código.