在基于模块的JavaScript体系结构中将语言翻译定义放在何处?

时间:2016-12-11 10:10:01

标签: javascript ecmascript-6 translation

目前我有这样的结构。

id: data[i].id,
headers: ["Även åsnor", "försöker på engelska"],
columns: {
  userName: data[i].firstName + " " + data[i].lastName,
  finishOn: data[i].finishOn !== null 
    ? data[i].finishOn 
    : "pågår..."
  }

我希望上面的构造与此类似地进行重构。

id: data[i].id,
headers: [Lang.userName, Lang.completedOn],
columns: {
  userName: data[i].firstName + " " + data[i].lastName,
  finishOn: data[i].finishOn !== null 
    ? data[i].finishOn 
    : Lang.holdYourPonnies
  }

然后,我可以将所有语言字段放在一个单独的模块中并保存在那里。我在JavaScript中从未这样做过,我在这方面也有顾虑。

  • 我是否需要为每个导入它的模块使用单独的语言模块?
  • 或者我应该有一个语言模块并多次导入,每个需要语言的模块一次?
  • 或者有没有办法在根模块中导入它并将其提供给树中的每个人?

1 个答案:

答案 0 :(得分:1)

您可以将语言定义作为对象从JS模块导出,也可以将它们保存在JSON文件中。语法基本相同:

{
  "FOO": "foo"
}

export default {
  "FOO": "foo"
}

但是模板文字可以用于JS文件中的多行字符串,这显着提高了可读性。

大多数情况下,在某些时候对变量的支持是必要的。通常需要一个简单的模板引擎。为简单起见,性能模板文字也可以在这里使用:

export default {
  FOO: "foo",
  BAR: `multiline
        bar`,
  BAZ: (val) => `template baz: ${val}`
}

这可以通过简化的本地化API有效地处理:

import en from './en';
import se from './se';

export class L10n {
  constructor() {
    this.lang = 'en';
    this.definitions = { en, se };
  }

  switch(lang) {
    this.lang = lang;
  }

  get(token, ...templateVars) {
    const val = this.definitions[this.lang][token];

    if (typeof val === 'function')
      return val(...templateVars);
    else
      return val;
  }
}

export default new L10n;

可以像:

一样使用
l10n.get('FOO');
l10n.get('BAZ', 'baz value');