web-dev-qa-db-ja.com

SystemScriptでTypeScriptでモーメントjsを使用する方法は?

私のプロジェクトのセットアップには、ライブラリ用の「jspm」ツールとタイピング用の「tsd」ツールが含まれています。

MomentのTypeScript d.tsファイル( これら )をインストールした後、momentインスタンスをロードして実際に使用する方法が見つかりません。

ファイル内(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);

TypeError:momentis a function」ではない

定義は lodash と同じように構造化されており、正常に機能するため、原因がわからない。

誰でも助けることができますか?

25
droritos

私は次のことをしました:

moment定義ファイル を次のようにインストールしました。

tsd install moment --save

次に、main.tsを作成しました:

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

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

そして、私は走った:

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

main.jsは次のようになります。

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

TypeScriptバージョンは1.6.2です。

これは私が見つけたものです:

Momentjsは 関数 をエクスポートします(つまり、_moment = utils_hooks__hooksおよびutils_hooks__hooksは関数です。これは非常に明確です。

上記のPLACE XYとして示した場所にブレークポイントを配置すると、moment_1が関数ではなくオブジェクト(!)であることがわかります。関連する行: 12

結論として、問題はTypeScriptとは関係ありません。問題は、systemjsがmomentjsが関数をエクスポートする情報を保持しないことです。 Systemjsは、エクスポートされたオブジェクトのプロパティをモジュールから単純にコピーします(関数はJavaScriptのオブジェクトでもあります)。 systemjsリポジトリに問題を報告して、彼らがそれをバグ(または機能:)と見なしているかどうかを確認する必要があると思います。

29
Martin Vseticka

バージョン2.13以降、モーメントにはTypeScriptのタイピングが含まれています。 tsd(またはtypings)を使用する必要はもうありません。

の中に systemjs.config.jsファイル、次を追加するだけです:

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

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

そして、モジュール内:

import moment = require('moment')
14

プロキシの制限のためにnpmを使用できなかったため、これを機能させるのに非常に苦労しました(したがって、ライブラリを手動でインストールする必要がありました)。瞬間のバージョンと間違いなくタイプされたファイルがプロジェクトの適切な場所にインストールされている場合、これを少しいじって動作させることができます。

便利なメモがあります moment.jsのWebサイト TypeScriptの瞬間の設定について。私の場合に役立った重要な側面は、tsconfig.jsonファイルのcompilerOptionsセクションに次を追加することでした。

"allowSyntheticDefaultImports": true
4
RichL

これはAngular 2で動作しますが、これに固有のものであってはなりません。基本的には、システムローダーにmoment.min.js

In system.config.js

// map tells the System loader where to look for things
var map = {
  'app':                        'app', // 'dist',

  '@angular':                   'node_modules/@angular',
  'rxjs':                       'node_modules/rxjs',

  // tell system where to look for moment
  'moment':                     'node_modules/moment/min'
};

// packages tells the System loader how to load when no filename and/or no extension
var packages = {
  'app':                        { main: 'main.js',  defaultExtension: 'js' },
  'rxjs':                       { defaultExtension: 'js' },

  // tell system which file represents the script when you import
  'moment':                     { main: 'moment.min.js', defaultExtension: 'js'}
};

モジュール内:

import moment from 'moment';

または(2016年10月13日編集):

import * as moment from 'moment';

一部のコメント者はimport *上記の構文を使用し、いくつかのアップグレード後にも同様に切り替える必要がありました(理由はわかりません)。

3
Josh Werts

TypeScriptファイルで、使用するとき

import moment from 'moment';

モジュール「モーメント」が見つからないという。私はモーメントをnpmパッケージとしてインストールし、適切に参照しましたが、その理由で、そのmoment.d.tsは以下のようにモジュールではなく名前空間として瞬間をエクスポートします。参照できません。

export = moment; 

だから私はそれを変更した場合

declare module 'moment' {
    export default moment;
}

インポートは完全に機能します。ここで私が間違っているのは何ですか?

1
Jojo

私のスタッフには、VS 2015(Update 3)でWebpackを使用しています。したがって、package.jsonおよびwebpack.config.vendor.jsファイルのコードを追加した後、コンポーネントの最上部でimport moment = require( 'moment')を呼び出すだけです(TypeScript、Angular 2)。

0
Thomas.Benz

私は瞬間を使用してインストールされたと仮定します

jspm install moment

これにより、config.jsのマップセクションにエントリが追加されます。

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

これにより、jsファイルの瞬間にアクセスできます

import moment from 'moment';

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

インポートすると* as momentモジュール名前空間をインポートします。したがって、瞬間は、プロパティがモジュールエクスポートであるオブジェクトになります。これにより、デフォルトのエクスポートはmomentとしてではなく、moment.defaultとしてインポートされます。のようなもの

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

あなたのコードで実際に動作するかもしれませんが、それが使用されるように意図された方法ではありません。

0
LazerBass

クライアント側の開発またはサーバー側(たとえば、node.js)にモーメントを使用しようとしているかどうかは少し明確ではありません。しかし、あなたのケースがフロントエンドの場合、私は瞬間をかなり簡単に使うことができました:

1)プロジェクトにファイルを追加しました:

enter image description here

2)簡単なテストコードを書きました。

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

そして、私のプロジェクトは正常にビルドされ、ブラウザにテストアラートが表示されました。

0
Mark Dolbyrev

ちょうど私のプロジェクトでそれをやった。それは角張っていますが、私はそれが重要ではないと思い、正しい道にあなたを置くかもしれません。次のように簡単です:

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