javascript - Vad är motsvarigheten till module.exports för ES6-moduler?


Jag har ett befintligt paket skrivet i JavaScript som jag försöker konvertera till TypeScript. Min fråga är, vad är motsvarigheten till module.exports för ES6-moduler?

Till exempel om jag har följande kod:

module.exports = function () {
    console.log("Hello World");
};

Det enda sättet jag har hittat att göra detta i ES-moduler är genom att göra något liknande följande.

const myFunc = function () {
    console.log("Hello World");
};
export default myFunc;
// OR
export { myFunc };

Självklart är detta inte samma sak som module.exports=//....

Vilket leder till detta problem. När jag kör detta genom TypeScript och får den genererade koden, kommer användare av paketet antingen behöva använda ett import defaultExport from "module-name"; uttalande (vilket inte är dåligt), eller istället för att kunna komma åt det med require("module-name") måste de använda require("module-name").default (om de använder standard JS, inte TypeScript). Vilket uppenbarligen är en brytande API-ändring för standard JavaScript-användare.

Uppenbarligen är målet här att inte ha några brytande API-ändringar (och att inte kräva några ändringar i kundernas kod).

En ytterligare krav för någon lösning. På andra ställen i paketet behöver jag kunna exportera många olika filer som ett objekt. Så tidigare har jag gjort:

module.exports = {
    "thing1": require("./a.js"),
    "thing2": require("./b.js")
};

Så jag behöver kunna exportera detta som vanligt utan att kräva att användaren gör thing1.default. Den här verkar hittills vara det enklare kravet eftersom jag exporterar ett objekt vilket ES-moduler verkar hantera riktigt bra. Det är när man exporterar ett enskilt (icke-namngivet) uttryck som det blir riktigt knepigt.

Finns det ett sätt att göra detta utan att behöva göra detta till en brytande förändring av API:et?

Svar #1

Lösningen här är att använda TypeScript-kommandot export =. Detta gör att du kan använda antingen require eller import med modulen.

export = function () {
    console.log("Hello World");
};
import myModule from "./lib/myModule";

// OR

const myModule = require("./lib/myModule");

För mer information har TypeScript-dokumentationen en guide om att migrera från JavaScript, och specifikt ett avsnitt som kallas Exportera från moduler.

Svar #2

Typescript rekommenderar att du inte skriver om din kod, utan istället konfigurerar den för att tillåta js-moduler.

När vi arbetade med att konvertera en mycket stor app från js till TS tog vi ställningen att skriva ny kod i TS och sakta konvertera js till ts (men inte spendera en massa tid enbart på konvertering).

Vi behövde aktivera några alternativ i tsconfig.json, såsom:

{
  ...,
  "compilerOptions" : {
    ... 
    "moduleResolution": "node",
    "allowJs": true,
    ...
  },
  "include" [
    "path/to/my/js",
  ]
}

du behöver också uppdatera din webpack.config.js:

module.exports = {
   // ... my settings


   resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
    },
}

Du kan också behöva deklarera require som en funktion (om du får fel som require är odefinierad):

declare function require(path: string): any;

mer information finns här: https://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html