node.js - ייבוא מודול CommonJS בפרויקט TypeScript שמייצא מודולי ES


אני יוצר ספריית NodeJs ב-Typescript ואני מתכנן שהיא תתמוך ב-Node@14+. לכן, החלטתי לבסס את הפרויקט הזה כ-ESModule במקום CommonJs. עכשיו יש כמה ספריות נדרשות שהן CommonJs ואני מתקין את @types שלהן. האימפורטים של קובץ ה-typescript שלי נראים כך:

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

ו-tsconfig.json נראה כך:

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

כפי שאתם יכולים לראות, אני מתמקד ב-ES2020 מכיוון שזה נתמך באופן מלא על ידי Node@14+ ואני מבסס את הקונפיגורציה שלי על התשובה המדהימה כאן https://stackoverflow.com/a/61305579/5863472. בנוסף, אני מגדיר "type": "module" בקובץ package.json שלי.

זה נבנה ללא בעיה אבל לא רץ. השגיאה שמוציאה Node היא

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

^^^^^^^^

שגיאת תחביר: ייצוא בשם 'readFile' לא נמצא. המודול המבוקש 'fs-extra' הוא מודול CommonJS, ועשוי שלא לתמוך בכל module.exports כייצוא בשם.

מודולי CommonJS תמיד ניתנים לייבוא דרך הייצוא הדיפולטי, לדוגמה באמצעות:

import pkg מ־'fs-extra';

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

אותו בסיס קוד מתרגם היטב כאשר משתמשים ב-"module": "ES2020" ב-tsconfig.json שלי ומסירים את המפתח type ב-package.json שלי.

הדרך שמצאתי לעקוף את זה היא על ידי עקיבה אחרי הודעת השגיאה. זה עובד טוב:

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;

אבל זה מרגיש כל כך מעצבן ונראה כמו משהו שניתן להיעזר בכלי עבורו. האם אני מפספס אפשרות קומפילציה או משהו שיכול להמיר אוטומטית import { foo } from 'bar' ל- import bar from 'bar'; const { foo }=bar.

נ.ב. אני באמת לא רוצה להשתמש בבאבל...