TypeScript-modulsystemer på momentJS oppfører seg merkelig
Jeg prøver å bruke momentJs fra TypeScript: avhengig av hvilket modul-system jeg bruker for å kompilere TypeScript, finner jeg forskjellig oppførsel på hvordan jeg kan bruke momentJs. Når jeg kompilerer TypeScript med commonJs fungerer alt som forventet, og jeg kan bare følge momentJs-dokumentasjonen:
import moment = require("moment");
moment(new Date()); //this works
Hvis jeg bruker "system" som TypeScript-modulsystem når jeg importerer "moment", blir jeg tvunget til å gjøre
import moment = require("moment");
moment.default(new Date()); //this works
moment(new Date()); //this doesn't work
Jeg fant en løsning for å få dem begge til å fungere uavhengig av hvilket TypeScript-modulsystem som brukes
import m = require("moment")
var moment : moment.MomentStatic;
moment = (m as any).default || m;
Jeg liker ikke dette, og jeg vil gjerne forstå hvorfor det oppfører seg slik. Gjør jeg noe feil? Kan noen forklare meg hva som skjer?
Svar #1
Jeg løste problemet ved å erstatte
import moment from "moment";
import-erklæring med
import * as moment from "moment";
dette.
Svar #2
Dette skjer fordi SystemJS automatisk konverterer moment til et ES6-stil modul ved å pakke det inn i et modulobjekt, mens CommonJS ikke gjør det.
Når CommonJS henter inn moment, får vi den faktiske moment-funksjonen. Dette er det vi har gjort i JavaScript en stund nå, og det bør se veldig kjent ut. Det er som om du skrev:
var moment = function moment() {/*implementation*/}
Når SystemJS henter inn moment, gir det deg ikke moment-funksjonen. Det oppretter et objekt med moment-funksjonen tildelt en egenskap som heter default. Det er som om du skrev:
var moment = {
default: function moment() {/*implementation*/}
}
Hvorfor gjør det det? Fordi en modul bør være et kart over en eller flere egenskaper, ikke en funksjon, ifølge ES6/TS. I ES6 er konvensjonen for massive eksterne biblioteker som tidligere eksporterte seg selv å eksportere seg selv under default-egenskapen til et modulobjekt ved å bruke export default (les mer her; i ES6/TypeScript kan du importere funksjoner på denne måten ved å bruke den kompakte import moment from "moment"-syntaksen).
Du gjør ikke noe galt, du trenger bare å velge formatet på modulene du importerer, og holde deg til valget ditt. Hvis du vil bruke både CommonJS og SystemJS, kan det være lurt å se på hvordan du konfigurerer dem til å bruke samme importstil. Et søk etter 'systemjs default import' ledet meg til denne diskusjonen om problemet ditt, hvor de implementerer --allowSyntheticDefaultImports-innstillingen.
