Zoeken op website

node.js - Een CommonJS-module importeren in een Typescript-project dat ESModules exporteert


Ik maak een NodeJs-bibliotheek in Typescript en ik ben van plan om deze Node@14+ te laten ondersteunen. Dus ik heb besloten om dit project te baseren als een ESModule in plaats van CommonJs. Er zijn nu enkele bibliotheken nodig die CommonJs zijn en ik installeer hun @types. De imports van mijn Typescript-bestand zien er als volgt uit:

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

en het tsconfig.json ziet er zo uit:

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

Zoals je kunt zien, richt ik me op ES2020 omdat dit volledig wordt ondersteund door Node@14+ en ik heb mijn configuratie gebaseerd op het geweldige antwoord hier https://stackoverflow.com/a/61305579/5863472. Ook stel ik "type": "module" in mijn package.json in.

Dit bouwt zonder probleem maar draait niet. De fout die door Node wordt opgegooid is

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

^^^^^^^^

SyntaxError: Gennemde export 'readFile' niet gevonden. De opgevraagde module 'fs-extra' is een CommonJS-module, die mogelijk niet alle module.exports als genaamde exports ondersteunt.

CommonJS-modules kunnen altijd worden geïmporteerd via de standaardexport, bijvoorbeeld met:

import pkg van 'fs-extra';

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

Dezelfde codebase compileert goed met "module": "ES2020" in mijn tsconfig.json en het verwijderen van de type-sleutel in mijn package.json.

De manier die ik heb gevonden om dit te omzeilen is door het foutbericht te volgen. Dit werkt prima:

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;

Maar dit voelt als zo'n gedoe en lijkt iets dat geautomatiseerd zou kunnen worden. Mis ik een compilatie-optie of iets dat automatisch import { foo } from 'bar' kan omzetten naar import bar from 'bar'; const { foo }=bar.

P.S. Ik wil echt geen Babel gebruiken...