Hvordan bruke momentjs i TypeScript med SystemJS?


Oppsettet til prosjektet mitt inkluderer verktøyet 'jspm' for biblioteker og verktøyet 'tsd' for typinger.

Etter å ha installert Moments TypeScript d.ts-fil (disse), kan jeg ikke finne en måte å laste og faktisk bruke en moment-instans på.

I filen min (som bruker SystemJS modulinnlasting)

/// <reference path="../../../typings/tsd.d.ts" />
import * as moment from "moment";
import * as _ from "lodash";
...
...
const now = (this.timestamp === 0) ? moment() : moment(this.timestamp);

Jeg får en «TypeError: moment er ikke en funksjon»

Definisjonene er strukturert på samme måte som lodash, som fungerer bra, så jeg vet ikke hva som kan være årsaken.

Kan noen hjelpe?

Svar #1

Jeg gjorde følgende:

Jeg installerte moment-definisjonsfilen som følger:

tsd install moment --save

Deretter laget jeg main.ts:

///<reference path="typings/moment/moment.d.ts" />

import moment = require("moment");
moment(new Date());

Og jeg løp:

tsc --module system --target es5 main.ts # no error 
tsc --module commonjs --target es5 main.ts # no error 

main.js ser slik ut:

// https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/system-register.md - this is the corresponding doc
///<reference path="typings/moment/moment.d.ts" />
System.register(["moment"], function(exports_1) {
    var moment;
    return {
        setters:[
            function (moment_1) {
                // You can place `debugger;` command to debug the issue
                // "PLACE XY"
                moment = moment_1;
            }],
        execute: function() {
            moment(new Date());
        }
    }
});

Min TypeScript-versjon er 1.6.2.

Dette er det jeg fant ut:

Momentjs eksporterer en funksjon (dvs. _moment=utils_hooks__hooks og utils_hooks__hooks er en funksjon, det er ganske klart.

Hvis du setter et stoppunkt på stedet jeg betegnet som PLACE XY ovenfor, kan du se at moment_1 er et objekt (!) og ikke en funksjon. Relevante linjer: 1, 2

For å konkludere, problemet har ingenting med TypeScript å gjøre. Problemet er at systemjs ikke bevarer informasjonen om at momentjs eksporterer en funksjon. Systemjs kopierer rett og slett egenskaper fra det eksporterte objektet fra en modul (en funksjon er også et objekt i JavaScript). Jeg antar du bør opprette en sak i systemjs-repositoriet for å finne ut om de anser det som en feil (eller en funksjon :)).

Svar #2

Siden versjon 2.13 inkluderer moment TypeScript-typinger. Det er ikke nødvendig å bruke tsd (eller typings) lenger.

I systemjs.config.js-filen, legg bare til følgende:

  var map = {
    // (...)
    moment: 'node_modules/moment',      
  };

  var packages = {
    // (...)
    moment: { main: 'moment.js', defaultExtension: 'js' },
  };

Og i modulen:

import moment = require('moment')

Relaterte artikler