moment.jsがWebpackでロケールをロードしないようにするにはどうすればよいですか?


199

moment.jsWebpackを使用しているときに、すべてのロケール(英語のみが必要です)のロードを停止できる方法はありますか?私はソースを探していますが、それhasModuleが定義されている場合、それはwebpackの場合、常にrequire()すべてのロケールを試行します。私はこれを修正するためにプルリクエストが必要だと確信しています。しかし、webpack設定でこれを修正できる方法はありますか?

以下は、momentjsをロードするための私のwebpack設定です。

resolve: {
            alias: {
                moment: path.join(__dirname, "src/lib/bower/moment/moment.js")
            },
        },

それなら、どこでも必要なときに、ただやるだけですrequire('moment')。これは機能しますが、バンドルに約250 kBの不要な言語ファイルが追加されます。また、私はmomentjsとgulpのバウアーバージョンを使用しています。

また、これがwebpack設定で修正できない場合は、ロケールをロードする関数へのリンクがあります。ステートメントに追加&& module.exports.loadLocalesしてみましたが、ifwebpackは実際には機能しません。それはrequire何があっても問題ありません。今は正規表現を使用していると思いますので、どうすれば修正できるかわかりません。


nmp代わりに経由でモーメントを使用しようとしましたbowerか?
AndreasKöberle2014

私はすべてのクライアントライブラリにbowerを、すべてのビルドツールにnpmを使用しています。私のプロジェクトがどのようにレイアウトされているかを考えると、この方法を維持したいと思います。また、github.com / moment / moment / issues / 1866の最後の返信を見ると、自分の問題は解決しましたが、ソースを少し編集する必要があります。nodeとwebpackをどのように区別するかわからないので、これを正しい方法で修正する方法はまだわかりません。
epelc 2014

回答:


305

コードrequire('./locale/' + name)localeディレクトリ内のすべてのファイルを使用できます。したがって、webpackはバンドル内のモジュールとしてすべてのファイルを含みます。どの言語を使用しているかはわかりません。

ある2つのプラグインモジュールは、あなたのバンドルに含まれるべきかについての詳細な情報を与えるWebPACKのために有用である:ContextReplacementPluginIgnorePlugin

require('./locale/' + name)コンテキストと呼ばれます(式を含むrequire)。webpackは、このコードフラグメントからいくつかの情報を推測します:ディレクトリと正規表現。ここに:directory = ".../moment/locale" regular expression = /^.*$/。したがって、デフォルトでは、localeディレクトリ内のすべてのファイルが含まれます。

ContextReplacementPluginすなわち(含めたい言語を選択して)新しい正規表現を提供推論された情報を上書きすることができます。

別のアプローチは、でのrequireを無視することですIgnorePlugin

次に例を示します。

var webpack = require("webpack");
module.exports = {
  // ...
  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /de|fr|hu/)
    // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
  ]
};

3
無視ローダーを使用する方法を説明できますか?`new webpackreg.IgnorePlugin(/\.\/ locale \ /.+。js $ /、[])`を試しましたが、うまくいきませんでした。また、contextReplacementPluginにはまだバンドルにファイルが含まれており、それらを使用していないと思います。
epelc 2014

9
この問題(github.com/webpack/webpack/issues/198)には、moment + webpackに関する詳細な説明が含まれています。
Tobias K.

2
new webpack.IgnorePlugin(/^\.\/lang$/, /moment$/)githubに関するコメントから動作すると思いますありがとうございます。
epelc 14

16
Webpackドキュメントでは、2番目の引数は正規表現の配列です。私はplugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]) ],どれがうまくいくかを試しまし た。
Alex K

6
@AlexKinnee ドキュメント内のブラケット表記は、配列ではなくオプションの引数であることを意味します。
yangmillstheory

8

私たちのプロジェクトには、次のような瞬間が含まimport moment from 'moment/src/moment';れています。これでうまくいくようです。ただし、モーメントの使用法は非常に単純なので、SDKとの不整合があるかどうかはわかりません。WebPackがロケールファイルを静的に見つける方法を認識していないため、これは機能すると思います。警告が表示されます(空のフォルダーをに追加することで簡単に非表示にできますmoment/src/lib/locale/locale)が、ロケールは含まれていません。


1
これがあなたのためにどのように機能しているのか分かりません...私はそのgithub.com/angular/angular-cli/issues/6137と戦うために試されただけで、github.com / ksloan/moment-miniを使用することで終わりました。適切なモジュール式momentライブラリが、いつかバージョン3 github.com/moment/moment/milestone/15登場します。
kuncevic.dev


2

Adam McCrmickの回答に基づいて、あなたは近くにいたので、エイリアスを次のように変更します。

resolve: {
    alias: {
        moment: 'moment/src/moment'
    },
},

1
これは、含めるすべてのモジュールの動作を変更し、サードパーティのライブラリに興味深い問題を引き起こす可能性があるという警告です。ただし、一般的には機能するはずです
Adam McCormick

1
詳しく説明できますか?すべてのエイリアスの使用例を経験したわけではありません。私の理解では、そのモジュールに触れた場合にのみ問題になります。この場合は「瞬間」
bigopon

3
解決エイリアスを設定すると、それらはシステム(依存するライブラリを含む)でのインポートまたは要求の使用に適用されます。したがって、必要な瞬間に依存するモジュールの場合、そのモジュールの結果も変更することになります。これは、依存関係ツリーのノードモジュールと競合するエイリアスを設定した場合に発生します(たとえば、依存関係がそのライブラリを使用している場合の「イベント」など)。実際には、名前の競合に関する問題だけがあり、このような動作の改善はありませんでしたが、これは1つのインポート文を変更するよりも危険なアプローチです。
Adam McCormick

2

webpack2あなたが行うことができた瞬間の最近のバージョン:

import {fn as moment} from 'moment'

そしてwebpack.config.jsあなたの中で:

resolve: {
    packageMains: ['jsnext:main', 'main']
}

1
私はあなたが意味していると思いますmainFields: ...
ギジェルモ・グラウ

webpack2を見て、フィールド名が変更されたことを確認してください。
ケビン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.