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?
J'ai fait ce qui suit:
J'ai installé moment
fichier 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é :)).
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')
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
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?
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).
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é.
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:
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.
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
}
...