如何在运行时捆绑并加载i18n模块?

时间:2016-04-11 18:00:17

标签: webpack

我尝试从RequireJS迁移到Webpack,而且我不确定处理我们的语言环境文件的最佳方法。

目前,我们为每个语言环境生成一个单独的JS文件。这些文件包含7个以上的i18n消息模块定义以及库配置(例如时刻)。例如,我们的da_DK文件类似于:



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




在运行时,我们确定要与我们的应用程序的其余部分一起加载的相应语言文件。我们的应用代码不知道加载了哪个区域设置;任何依赖于语言环境的模块都会require('moment-locale')require('messages')

我想和Webpack做类似的事情,但我还没有找到一个很好的方法来实现这个目标。

我已经看到了require.context的动态需求,但听起来最终会将所有可能的区域设置与我的应用捆绑在一起,我不喜欢这样做。

我也查看了DllPlugin,认为每个语言环境文件都可能是" dll",但我注意到dll清单包含特定的模块名称(例如:node_modules / moment / locale / de-at.js )我认为我需要更通用,所以webpack知道我require('moment-locale')时,它需要查看该dll。

我能够让它工作的一种方法是更新我的语言环境包生成代码,以便为每个语言环境创建一个类似于以下内容的条目:



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




然后在webpack配置中,我将library字段设置为我的应用程序的命名空间。然后在我的应用程序的webpack配置中,我在externals中引用了这些模块。换句话说,当加载da_DK.js时,它会将window下的所有模块放在命名空间下,供应用程序在加载时引用。我宁愿不使用这种方法,但这是我迄今为止能够实现这一目标的唯一方式。

还有其他/更好的方法来实现这个目标吗?

2 个答案:

答案 0 :(得分:10)

有多种方法可以解决这个问题。 3种可行的方法是:

  1. 打包捆绑包中的所有区域设置。
  2. 让你的软件包延迟加载 locale
  3. 为每个区域设置制作单独的分发包
  4. 打包捆绑包中的所有区域设置

    通过这种方式,您可以为较少的http请求交换较高的捆绑包大小。如果区域设置很小,这可能是要采取的路线。在所有其他情况下,我会建议反对它,因为它会使捆绑尺寸更大并且会增加负载。

    让您的软件包延迟加载语言环境

    为此,请利用Webpacks code splitting functionality。这样您就可以创建bundle.jsda_DK.jssv_SE.js等等,并使用require() / require.ensure加载其中一个区域设置文件,具体取决于bundle.js中的逻辑。

    为每个区域设置制作单独的分发包

    根据您进行区域设置协商的方式,最佳方法可能是在构建时上创建单个捆绑包。换句话说,创建bundle.da_DK.js一个bundle.sv_SE.js等等。如果您在加载包之前根据可用的内容进行语言环境协商(例如,网址中的/da/ slug,会话设置等等),这可能是最佳选择。

    这样做你将a)创建尽可能小的包和b)将获得性能提升(尽管很小)因为不需要在运行时完成转换。 i18n plugin for Webpack将帮助您创建单独的捆绑包。

    旁注

    Moment.js,虽然它是一个非常好的库,但它并不是真正的Webpack友好。它将加载所有区域设置。看一下这个线程来改变这种行为:https://stackoverflow.com/a/25426019/2533681

答案 1 :(得分:0)

对于那些对动态打包(按需)加载与webpack捆绑在一起的(语言)词典感兴趣的人,有一个新的软件包https://github.com/whitecolor/lp-loader