Búsqueda de sitios web

node.js - Importando un módulo CommonJS en un proyecto de Typescript que exporta ESModules


Estoy creando una biblioteca de NodeJs en Typescript y planeo hacer que sea compatible con Node@14+. Por lo tanto, decidí basar este proyecto como un ESModule en lugar de CommonJs. Ahora hay algunas bibliotecas requeridas que son CommonJs y estoy instalando sus @types. Las importaciones de mi archivo Typescript se ven así:

import { Command } from 'commander';
import inquirer from 'inquirer';
import { resolve } from 'path';
import { render } from 'mustache';

import { copySync, readdirSync, readFile, readFileSync, writeFile } from 'fs-extra';

y el tsconfig.json se ve así:

{
  "include": ["src/**/*"],
  "compilerOptions": {
    // type checking
    "exactOptionalPropertyTypes": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitOverride": true,
    "noImplicitReturns": true,
    "noPropertyAccessFromIndexSignature": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "strict": true,
    // module
    "module": "ES2020",
    "moduleResolution": "node",
    "rootDir": "src",
    "resolveJsonModule": true,
    // emit
    "outDir": "dist",
    //    "importHelpers": true,
    // imterop constraints
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    // language and environment
    "lib": ["ES2020"],
    "target": "ES2020",
    // completeness
    "skipLibCheck": true
  }
}

Como puedes ver, estoy apuntando a ES2020 ya que es totalmente compatible con Node@14+ y basé mi configuración en la increíble respuesta aquí https://stackoverflow.com/a/61305579/5863472. Además, estoy configurando "type": "module" en mi package.json.

Esto se compila sin problema pero no se ejecuta. El error que lanza Node es

import { copySync, readdirSync, readFile, readFileSync, writeFile } from 'fs-extra';

^^^^^^^^

SyntaxError: Exportación nombrada 'readFile' no encontrada. El módulo solicitado 'fs-extra' es un módulo CommonJS, el cual puede no soportar todas las exportaciones de module.exports como exportaciones nombradas.

Los módulos CommonJS siempre se pueden importar mediante la exportación por defecto, por ejemplo usando:

importar pkg desde 'fs-extra';

const { copySync, readdirSync, readFile, readFileSync, writeFile }=pkg;

La misma base de código se compila bien usando "module": "ES2020" en mi tsconfig.json y eliminando la clave type en mi package.json.

La forma que he encontrado para solucionar esto es siguiendo el mensaje de error. Esto funciona bien:

import { Command } from 'commander';
import inquirer from 'inquirer';
import { resolve } from 'path';
import mustache from 'mustache';
import fs from 'fs-extra';

const { copySync, readdirSync, readFile, readFileSync, writeFile } = fs;
const { render } = mustache;

Pero esto se siente como un gran problema y parece algo que podría ser automatizado. ¿Me estoy perdiendo de alguna opción de compilación o algo que pueda convertir automáticamente import { foo } from 'bar' a import bar from 'bar'; const { foo }=bar?

P.D. Realmente no quiero usar Babel...