node.js - การนำเข้าโมดูล CommonJS ในโปรเจกต์ Typescript ที่ส่งออกเป็น ESModules
ฉันกำลังสร้างไลบรารี 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 } จาก 'fs-extra';
^^^^^^^^
SyntaxError: ไม่พบการส่งออกแบบตั้งชื่อ '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 อัตโนมัติ
ป.ล. ฉันจริงๆ ไม่อยากใช้ Babel เลย...