2016-04-11 7 views
8

私はRequireJSからWebpackに移行しようとしており、私たちのロケールファイルを処理する最良の方法は不明です。実行時にi18nモジュールをバンドルしてロードするには?

現在、各ロケールごとに別々のJSファイルを生成しています。これらのファイルには、i18nメッセージ用の7つ以上のモジュール定義とライブラリ構成(モーメントなど)が含まれています。実行時に

(function (global, factory) { 
 
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) : 
 
    typeof define === 'function' && define.amd ? define('moment-locale',['moment'], factory) : 
 
    factory(global.moment) 
 
}(this, function (moment) { 'use strict'; 
 

 

 
    var da = moment.defineLocale('da', { 
 
     ... 
 
    }); 
 

 
    return da; 
 

 
})); 
 

 
define('messages',[],function(){ 
 
    var da_messages = { 
 
    ... 
 
    }; 
 
    
 
    return da_messages; 
 
});

は、我々は我々のアプリの残りの部分とロードする適切な言語ファイルを決定します。たとえば、私たちのda_DKファイルは次のように見えます。私たちのアプリケーションコードは、どのロケールが読み込まれているか分かりません。ロケールに依存するモジュールはすべてrequire('moment-locale')require('messages')となります。

私はWebpackと同様のことをしたいと思っていますが、まだこれを達成する良い方法が見つかりませんでした。

私は動的要求のためにrequire.contextを見ましたが、そうしないと、すべての可能なロケールが自分のアプリにバンドルされてしまいます。

また、各ロケールファイルが "dll"である可能性があると思ってDllPluginを調べましたが、dllマニフェストに特定のモジュール名(例:node_modules/moment/locale/de-at.js)私はrequire('moment-locale')、それはそのDLLを見てする必要がありますので、Webpackは知っているので、より一般的にする必要があります。

module.exports = { 
 
    'messages': require('messages'), 
 
    'moment-locale': require('moment-locale'), 
 
    ... 
 
};

、その後:それはのように見える各ロケールのエントリを作成するように、私は仕事にこれを取得することができた

一つの方法は、私のロケールのバンドルの生成コードを更新しましたwebpackの設定では、libraryフィールドを私のアプリケーション用の名前空間に設定しました。そして、私のアプリのウェブパック設定では、externalsでこれらのモジュールを参照しました。つまり、da_DK.jsが読み込まれると、ロード時に参照するための名前空間の下のwindowのすべてのモジュールが参照されます。私はむしろこのアプローチを使用したくないですが、それがこれまでのところこれを実現するための唯一の方法です。

これを達成する別の方法がありますか?

答えて

7

これについては、複数の方法があります。実行可能な方法は3つあります。

  1. バンドル内のすべてのロケールをパッケージ化します。
  2. ロケール
  3. は、ロケールごとに個別のバンドル

パッケージあなたのバンドル内のすべてのロケール

あなたがいずれかの高いバンドルサイズをトレードます。この方法をお使いのバンドル遅延ロードを作りますより少ないhttp要求。ロケールが小さい場合は、これがルートとなる可能性があります。それ以外の場合は、バンドルサイズを大きくして負荷を増加させるので、私はそれに対して助言をします。

バンドルにロケールを読み込みます。

これを行うには、Webpacks code splitting functionalityを利用してください。このようにしてbundle.jsda_DK.jssv_SE.jsなどを作成し、require()/require.ensureを使用して、bundle.jsのロジックに応じてロケールファイルのいずれかを読み込むことができます。

あなたが最良のアプローチはビルド時上の個々のバンドルを作成することであるかもしれないロケールネゴシエーションを行う方法に応じて各ロケール

のための個々のバンドルを作成します。つまり、bundle.da_DK.jsbundle.sv_SE.jsというように作成します。バンドルがロードされる前に利用可能なものに基づいてロケールネゴシエーションを行う場合(URLに/da/スラッグ、セッション設定など)これが進む方法かもしれません。

このようにすると、可能な限り小さなバンドルを作成します。b)ランタイムを実行する必要がないため、パフォーマンスは向上します(ただし、小さくなります)。 i18n plugin for Webpackは個々のバンドルの作成に役立ちます。

サイドノート

Moment.js、それは本当に良いライブラリですが、それは本当にWebPACKの友好的ではありません。それはすべてロケールをロードします。このスレッドを見て、その動作を変更してください:https://stackoverflow.com/a/25426019/2533681

+1

ありがとうございました! 1.私は、数多くのロケールをサポートしており、各ロケールバンドルが約600KBのところに座っているので、このアプローチを避けたいと思います。 2.私はこのアプローチを試みましたが、実行時までロケールを知らないので、可能なすべてのロケールをバンドルするための動的require/require.contextを使用しなければならないと思います。 3.現在、ロケールごとにバンドルを生成していますが、実行時に負荷がかかり、残りのアプリケーションとやりとりするという課題がありました。 –

+0

約2.ロケールを別のファイルに分割する場合は、ロケールを別々に要求することができます。 3.私は、各ロケールごとに個別のバンドルを作成することを話していました。 _both_ "app code"とロケールを含むバンドル。 –

関連する問題