node.js - Importere en CommonJS-modul i et Typescript-prosjekt som eksporterer ESModuler


Jeg lager et NodeJs-bibliotek i Typescript, og jeg planlegger å gjøre det kompatibelt med Node@14+. Så jeg har bestemt meg for å basere dette prosjektet som en ESModule i stedet for CommonJs. Nå er det noen biblioteker som kreves som er CommonJs, og jeg installerer deres @types. Importene i Typescript-filen min ser slik ut:

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';

og tsconfig.json ser slik ut:

{
  "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
  }
}

Som du kan se, sikter jeg mot ES2020 siden det er fullt støttet av Node@14+ og jeg baserte konfigurasjonen min på det utrolige svaret her https://stackoverflow.com/a/61305579/5863472. I tillegg setter jeg "type": "module" i min package.json.

Dette bygges uten problemer, men kjører ikke. Feilen som kastes av Node er

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

^^^^^^^^

SyntaxError: Navngitt eksport 'readFile' ble ikke funnet. Den forespurte modulen 'fs-extra' er en CommonJS-modul, som kanskje ikke støtter alle module.exports som navngitte eksporter.

CommonJS-moduler kan alltid importeres via standardeksporten, for eksempel ved å bruke:

import pkg fra 'fs-extra';

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

Den samme kodebasen kompilerer bra ved å bruke "module": "ES2020" i min tsconfig.json og fjerne type-nøkkelen i min package.json.

Måten jeg har funnet for å omgå dette på er ved å følge feilmeldingen. Dette fungerer fint:

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;

Men dette føles som en slik byrde og virker som noe som kunne vært automatisert. Går jeg glipp av et kompilasjonsalternativ eller noe som automatisk kan konvertere import { foo } from 'bar' til import bar from 'bar'; const { foo }=bar.

P.S. Jeg vil virkelig ikke bruke Babel...