web-dev-qa-db-ja.com

Angular 2のAoTコンパイラにロールアップを使用し、Moment.jsをインポートする

公式AoTガイド for Angular 2を追いかけようとしています。Moment.jsをアプリケーションで使用しています。Moment.jsは私のpackages.jsonファイルで、バージョン2.15.0を使用していますが、これまでこのようにインポートしてきました。

import * as moment from 'moment';

しかし、ロールアップを実行する必要がある部分に到達すると、次のエラーが発生します。

名前空間を呼び出すことはできません(「モーメント」)

this に従って瞬間をインポートする方法に関連しているように見えます。だから、私はこれをどのように行うべきですか?他の方法で瞬間をインポートすることはできません。私が使用する場合

import moment from 'moment'

コンパイルエラーが表示されます

外部モジュール「モーメント」にはデフォルトのエクスポートがありません

29
Vitor Machado

私は最終的に両方のエラーを取り除くことに成功しました。避けるべきこと:

名前空間を呼び出すことはできません(「モーメント」)

以下を使用する必要があります。

import moment from 'moment'

それから避けるために

「モーメント」にはデフォルトのエクスポートはありません

Tsconfig.json(compilerOptions)に追加する必要があります。

"allowSyntheticDefaultImports": true

EDIT 17/11/2016

また、rollup-config.jsファイルに次を追加する必要がありました。

plugins: [
  nodeResolve({jsnext: true, module: true}),
  commonjs({
    include: [
        'node_modules/rxjs/**',
        'node_modules/moment/**'
      ]
    }
  }),
  uglify()
]
22
j3r6me

私は目前の問題の素晴らしい解決策を見つけました:

Npm-install追加パッケージ moment-es6 はデフォルトのエクスポートを提供します。次に、「moment」ではなく「moment-es6」からインポートします。

import moment from 'moment-es6';

  • Systemjsで使用するには、systemjs.config.jsマップセクションに次を追加します。
    'moment-es6': 'npm:moment-es6/index.js'

  • 追加 'node_modules/moment-es6/**'をロールアップ構成のcommonjsセクションのincludeに追加します(rollup-plugin-commonjs)

13
akaegi

ここでは、TypeScript(2.1.6)とロールアップ(0.41.4)を使用して作業を行いました。

  1. 瞬間をインポートするには、標準的な方法を維持します。

    _import * as moment from 'moment';_

_import moment from 'moment';_は、デフォルトのエクスポートのないパッケージでは非標準です。実行時にエラーが発生します:_moment_1.default is not a function_

  1. TypeScriptでは、モーメントをanyとしてキャストしてモーメントwithを使用し、default関数を呼び出します。

    _var momentFunc = (moment as any).default ? (moment as any).default : moment;
    var newFormat = momentFunc(value).format( format );
    _

moment(value).format(format)は、ロールアップツリーの揺れでエラーになります:Cannot call a namespace ('moment')

7

Ng-packagrでも同様の問題があり、npmリポジトリで公開できるモジュールを生成するためにロールアップを使用します。プロジェクトは、@ angular-cli(webpackを使用)を使用して構築されました。

アスタリスクメソッドを使用してインポートされる2つの依存関係があります。

 import * as dataUrl from 'dataurl';

うまく機能し、次のように使用されます:

 dataUrl.parse(url)

エクスポートされたオブジェクトは関数として使用されるため、別のインポートでエラーが発生しました(名前空間を呼び出せません)。

 import * as svgPanZoom from 'svg-pan-zoom';
 svgPanZoom(element); <== error: Cannot call a namespace

これを回避するには、エクスポートされた初期化関数を別のconstに割り当て、それをコードで使用します。

 import * as svgPanZoomImport from 'svg-pan-zoom';
 const svgPanZoom = svgPanZoomImport;

 svgPanZoom(element);

また、上記のようにtsconfig.json構成を変更しました。

バージョン:ng-packagr:1.4.1ロールアップ:0.50.0 TypeScript:2.3.5 @ angular/cli:1.4.8 webpack:3.7.1

この助けを願って、

ロブ

4
Rob Gansevles

上記と同じ問題を抱えていました。

_import * as moment from 'moment';_-systemjsを介して開発およびロードする場合は機能しましたが、ロールアップ中は機能しませんでした。

_import moment from 'moment';_-ロールアップビルドで機能しましたが、開発中は機能しませんでした。

ビルドの種類に応じてコードを変更する必要を回避するために、瞬間をグローバルとして追加し、瞬間をインポートする代わりに使用する必要があるすべての場所にインポートするヘルパー関数を作成しました。

つまり、両方のタイプのシナリオで同じコードが機能します。それは特にきれいではありませんが、より良い方法があれば私に知らせてください!

ヘルパー関数は、独自のファイル_momentLoader.ts_に追加されています

_import { default as mom } from 'moment';
export default function moment(args?: any): mom.Moment {
    let m = window["moment"];
    if (!m) { 
        console.error("moment does not exist globally.");
        return undefined;
    }
    return m(args);
}
_

他のクラスでモーメントを使用するには、関数をインポートし、モーメントを直接インポートしたかのように呼び出します。

_import moment from '../../momentLoader';_

let d = moment().utc("1995-12-25");

let m = moment("1995-12-25");

Systemjsにグローバルとしてロードさせるには、次の手順に従いました。 http://momentjs.com/docs/#/use-it/system-js/

私の場合、systemjsの現在の設定は次のようになります。

_let meta = {
    'lib:moment/moment.js': { format: 'global' }
};

System.config({
    paths: paths,
    map: map,
    packages: packages,
    meta: meta
});

System.import('lib:moment/moment.js');
_

ロールアップビルドでは、moment.jsがスクリプトタグを介してページに追加されていることを確認する必要があります。残念ながら、ロールアップビルドファイルには含まれません。

3
Nick Cameron

このスレッドimport moment from 'moment';動作するはずです。

0
Tycho

上記のすべてのソリューションを試しましたが、うまくいきませんでした。働いたのは

import moment from 'moment-with-locales-es6';
0
Adrian Ber

My Angular 5(5.2.9)プロジェクト(Ng2からアップグレード))で、prodビルドのGulpおよびRollup(0.58.0)でmomentJs(2.24)の使用に同じ問題がありました。

ここで先ほど述べたように、import * as moment from 'moment';は、パッケージリスト内のmomentJsを参照する(SystemJSを介した)開発でのみ機能します。

{
  name: 'moment',
  path: 'node_modules/moment/min/moment.min.js'
}

その他のケースは、ロールアップの使用(プロダクションビルド)です。momentJsのコードはES6モジュール(moment/src内)ですが、異なる方法でエクスポートされます(通常のエクスポート)。 import moment from 'moment';がロールアップの

include: [
  'node_modules/rxjs/**',
]

およびES6モジュールのインポート。

はい、ES6ラッパー(moment-es6など)を使用するのは簡単なソリューションです。ただし、常にmomentJsが必要です。同時に、この問題に対するもう1つの簡単な解決策があります。インポート行をDevからProdに置き換えます。たとえば、Gulpはいくつかのステップでgulp-replaceを使用できます。

return gulp.src([
     ...
    ])
    .pipe(replace('import * as moment from \'moment\';', 'import moment from \'moment\';'))
     ...;
0
PIoneer_2

バージョン2.13.0以降、

import * as moment from 'moment';

0
Zubair Lawrence