node.js - SWCs bundler kompilerer til ES6 import i stedet for require


Er det mulig å la SWC pakke TypeScript-filer samtidig som man transformerer ES6-importer til commonjs require()? Ikke sikker på om jeg ikke får det til å fungere på grunn av min begrensede forståelse, eller om jeg mangler et bestemt valg.

I utgangspunktet har jeg en inngangs-TS-fil som importerer et eksternt bibliotek via en enkel import convert from 'xml-js';. Deretter, med følgende spack.config.js:

module.exports = {
  module: {
    type: 'commonjs',
  },
  options: {
    jsc: {
      target: 'es2018',
      parser: {
        syntax: 'typescript',
        // isModule: true,
        // dynamicImport: true,
    },
  },
  externalModules: ['xml-js'],
  entry: {
    'loader': __dirname + '/src/loader.ts',
  },
  output: {
    path: __dirname + '/dist',
  },
}

Jeg ville forvente at pakken skulle inneholde et commonjs require() (på grunn av type: 'commonjs'), men i stedet resulterer det i import convert from "xml-js"; Jeg har prøvd en hel del forskjellige konfigurasjonsalternativer, men resultatet har vært det samme hver gang.

Når jeg bruker Rollup med rollup-plugin-typescript2, resulterer det i en require(): var convert=require('xml-js'); Dette er slik jeg forventer at SWC's bundler også skal fungere.

Min følelse sier at SWC også bør være i stand til å gjøre dette, men jeg er ikke sikker på hvordan. Enhver antydning i riktig retning blir svært verdsatt.

Takk!

Svar #1

Selvfølgelig kan du det. Her er dokumentasjonen fra SWC-nettstedet.

Du har inkludert den nødvendige type: "commonjs", men på feil sted. Jeg har ikke brukt Spack eller hva enn denne konfigurasjonsfilen er, men det ser ut til at filen din bør si dette:

module.exports = {
  options: {
    module: {
      type: 'commonjs',
    },
    jsc: {
      target: 'es2018',
      parser: {
        syntax: 'typescript',
        // isModule: true,
        // dynamicImport: true,
      }
    },
  },
  // ...
}

For de som bruker en .swcrc-konfigurasjonsfil (husk å fjerne kommentarer):

{
  "$schema": "https://json.schemastore.org/swcrc",
  "module": {
    "type": "commonjs" // can be "es6", "umd", or "amd"
  },
  // any other options
}

Svar #2

Jeg støtte også på dette problemet: den nåværende SWC kan ikke transpile require() fra commonjs til import fra esm. Den kan bare konvertere esm til commonjs.

{
   "jsc": {
     "target": "esnext",
   }
   "module": {
     "type": "es6"
   },
}

Forresten: SWC-bundleren er et annet relatert prosjekt (for øyeblikket fortsatt i tidlig fase). SWC er kode-transpileren.

Jeg har prøvd esbuild, men det støtter fortsatt ikke å transpile require:

npx esbuild src/custom.cjs --format=esm --outfile=custom.mjs
▲ [WARNING] Converting "require" to "esm" is currently not supported [unsupported-require-call]

Kanskje bare babel kan for øyeblikket støtte: https://babeljs.io/docs/babel-plugin-transform-modules-commonjs

Endelig er min nåværende konklusjon at hvis du vil bruke nyere kode-transpilere som SWC/esbuild, er det best å skrive i ESM og oversette dem til commonjs. Ellers bruk babel i stedet.