ค้นหาเว็บไซต์

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 เลย...