TypeScriptからmomentJsを使用しようとしています。TypeScriptのコンパイルに使用しているモジュールシステムに応じて、momentJsの使用方法に異なる動作が見られます。 TypeScriptをcommonJsでコンパイルすると、すべてが期待どおりに機能し、momentJsのドキュメントに従うことができます。
import moment = require("moment");
moment(new Date()); //this works
"moment"をインポートするときにTypeScriptモジュールシステムとして"system"を使用すると、強制的に実行されます
import moment = require("moment");
moment.default(new Date()); //this works
moment(new Date()); //this doesn't work
使用するTypeScriptモジュールシステムに関係なく、両方を機能させるための回避策を見つけました
import m = require("moment")
var moment : moment.MomentStatic;
moment = (m as any).default || m;
私はこれが好きではありません、そしてなぜそれがこのように振る舞うのか理解したいと思います。私は何か間違ったことをしていますか?誰かが私に何が起こっているのか説明できますか?
これは、SystemJSがmoment
をモジュールオブジェクトでラップすることによってES6スタイルのモジュールに自動的に変換しているのに対し、CommonJSはそうではないために発生しています。
CommonJSがmoment
をプルすると、実際のmoment
関数が得られます。これは私たちがJavaScriptでしばらく行ってきたことであり、非常に見覚えがあるはずです。それはあなたが書いたかのようです:
var moment = function moment() {/*implementation*/}
SystemJSがmoment
をプルする場合、モーメント関数は提供されません。 default
という名前のプロパティに割り当てられたモーメント関数を使用してオブジェクトを作成します。それはあなたが書いたかのようです:
var moment = {
default: function moment() {/*implementation*/}
}
なぜそれをするのですか? ES6/TSによると、モジュールは関数ではなく1つ以上のプロパティのマップである必要があるためです。 ES6では、以前は自分自身をエクスポートしていた大規模な外部ライブラリの規則は、export default
を使用してモジュールオブジェクトのdefault
プロパティの下で自分自身をエクスポートすることです(ES6では続きを読む ここ ;/TypeScriptでは、コンパクトなimport moment from "moment"
構文を使用してこのような関数をインポートできます。
何も悪いことはしていません。インポートしたモジュールの形式を選択し、選択に固執する必要があります。 CommonJSとSystemJSの両方を使用する場合は、同じインポートスタイルを使用するように構成することを検討してください。 'systemjs default import'を検索すると、問題の このディスカッション になり、--allowSyntheticDefaultImports
設定が実装されます。
これが私がSystem.jsとTypeScript1.7.5で行った方法です
_import * as moment from "moment";
...
moment.utc(); // outputs 2015 (for now).
_
ただし、utc()
メソッドを使用していることに注意してください。 mkとしてmoment()
を使用できません。説明しましたが、これはSystem.jsによってmoment.default()
に変換されます。原因として、DefinitelyTyped型にはdefault
メソッドが含まれていないため、コンパイルエラーを回避するには、moment["default"]()
のようなものを使用する必要があります(私は知っています、醜いです)。
次のステップでは、System.js構成に以下を追加する必要がありました。
_System.config({
paths: {
'moment': 'node_modules/moment/moment.js'
}
});
_
この後、すべてが魅力として機能しました。
私が取り組んでいるプロジェクトに引き込む瞬間は苦痛でしたが、私たちはこれを使用してそれを解決することになりました:
import momentRef = require('moment');
var moment: moment.MomentStatic = momentRef;
私のsystem.configの場合:
paths: {
'moment': 'node_modules/moment/moment.js'
},
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
コンポーネントにmomentjsをインポートする*を削除しました。これは、moment.jsファイルのコードを複数のオブジェクトとして扱うと思います。
変化する:
import * as moment from 'moment';
に:
import moment from 'moment';