es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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

Tags:  , , ,

Answer

  1. Avatar for 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 archivo package.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 el package.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 mediante import { Clase } from '../node_modules/mi-librería-asombrosa/dist/cjs/index.js'.

    Además, agregar { "type": "module" } al package.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.

Comments are closed.