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.
נ.ב. אני באמת לא רוצה להשתמש בבאבל...