web-dev-qa-db-fra.com

Comment utiliser moment js dans TypeScript avec SystemJS?

La configuration de mon projet comprend l'outil 'jspm' pour les bibliothèques et l'outil 'tsd' pour les typages.

Après avoir installé le fichier TypeScript d.ts de moment ( this ), je ne trouve pas le moyen de charger et d’utiliser une instance de moment.

Dans mon dossier (en utilisant le chargement du module SystemJS)

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

Je reçois un "TypeError: moment n'est pas une fonction"

Les définitions sont structurées de la même façon que lodash , ce qui fonctionne bien, donc je ne sais pas quelle peut en être la cause.

Quelqu'un peut-il aider?

25
Dror Weiss

J'ai fait ce qui suit:

J'ai installé momentfichier de définition comme suit:

tsd install moment --save

Puis j'ai créé main.ts:

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

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

Et j'ai couru:

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

main.js ressemble à ceci:

// 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());
        }
    }
});

Ma version de TypeScript est 1.6.2. 

C'est ce que j'ai découvert:

Momentjs exporte une fonction _ (c'est-à-dire _moment = utils_hooks__hooks et utils_hooks__hooks est une fonction, c'est assez clair.

Si vous placez un point d'arrêt à l'endroit indiqué par PLACE XY ci-dessus, vous constaterez que moment_1 est un objet (!) Et non une fonction. Lignes pertinentes: 1 , 2

Pour conclure, le problème n'a rien à voir avec TypeScript. Le problème est que systemjs ne conserve pas les informations qui momentjs exporte une fonction. Systemjs copie simplement les propriétés de l'objet exporté à partir d'un module (une fonction est aussi un objet en JavaScript). Je suppose que vous devriez signaler un problème dans le référentiel de systemjs pour savoir s’ils le considèrent comme un bogue (ou une fonctionnalité :)).

29
Martin Vseticka

Depuis la version 2.13, moment inclut les typages TypeScript. Plus besoin d'utiliser tsd (ou typings).

Dans le fichier systemjs.config.js, ajoutez simplement ce qui suit:

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

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

Et dans le module:

import moment = require('moment')
14
Philippe Plantier

J'ai eu énormément de difficulté à faire en sorte que cela fonctionne, car je ne pouvais pas utiliser npm en raison de restrictions de proxy (j'ai donc dû installer manuellement les bibliothèques). À condition que les versions de moment et de fichiers bien typés soient installées aux emplacements appropriés dans votre projet, vous pouvez faire en sorte que cela fonctionne avec un peu de bidouillage.

Il y a une note utile ici sur le site internet moment.js sur la configuration de TypeScript avec moment. L'aspect clé qui m'a aidé dans mon cas a été d'ajouter ce qui suit dans la section compilerOptions de mon fichier tsconfig.json:

"allowSyntheticDefaultImports": true
4
RichL

Dans mon fichier TypeScript, lorsque j'utilise 

import moment from 'moment';

il dit ne peut pas trouver le «moment» du module. J'ai installé moment en tant que paquet npm et il a correctement référencé, mais pour la raison, moment.d.ts exporte le moment sous forme d'espace de nom, pas de module comme ci-dessous, je ne peux pas le référencer.

export = moment; 

Donc si je le change en 

declare module 'moment' {
    export default moment;
}

l'importation fonctionne parfaitement. Qu'est-ce que je fais mal ici?

1
Ali Raza

Pour mes affaires, j'utilise Webpack avec VS 2015 (mise à jour 3). Ainsi, après avoir ajouté les codes des fichiers package.json et webpack.config.vendor.js, il suffit d'appeler import moment = require ("moment") tout en haut de mon composant (TypeScript, Angular 2).

0
Thomas.Benz

Je suppose que moment a été installé en utilisant

jspm install moment

Cela devrait ajouter une entrée dans la section map de votre config.js.

...
"moment": "npm:[email protected]",
...

De cette façon, vous pouvez accéder à moment dans vos fichiers js via

import moment from 'moment';

console.log(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));

Lorsque vous importez * as moment, vous importez l'espace de noms du module. Donc, moment sera un objet dont les propriétés sont des exportations de module. De cette façon, l’export par défaut ne sera pas importé en tant que moment, mais en tant que moment.default .

moment.default().format('dddd, MMMM Do YYYY, h:mm:ss a')

pourrait effectivement fonctionner dans votre code mais ce n’est pas la façon dont il est destiné à être utilisé.

0
LazerBass

Ce n'est pas clair si vous essayez d'utiliser moment pour le développement côté client ou pour le côté serveur (par exemple, node.js). Mais, si votre cas est front-end, alors j'ai pu utiliser moment assez facile:

1) Je viens d'ajouter des fichiers à mon projet:

 enter image description here

2) Écrit un code de test simple:

window.onload = () =>
{
    var timestamp: number = 111111111111111;
    var momentResult: moment.Moment = moment(timestamp);
    alert(momentResult.toISOString());
};

Et mon projet a été construit correctement et j'ai vu un test d'alerte dans le navigateur.

0
Mark Dolbyrev

Je viens de le faire dans mon projet. C'est anguleux, mais je ne pense pas que cela compte et qu'il puisse vous mettre sur la bonne voie. C'est simple comme:

import MomentStatic = moment.MomentStatic;

class HelpdeskTicketController {
  constructor(private moment: MomentStatic) { // angulars dependency injection, you will have some global probably
    let d = this.moment(new Date()); // works
    console.log(d.add(2, 'hours').format()); // works
  }

  ...
0
smajl