背景
最近接到一个海外项目业务需求,项目最终会被来自不同国家的客户所使用,期望能让客户有一个良好的用户体验,因此前端需要适配国际化。
面临的挑战
乍一听,这个海外项目需求并没有什么特别的地方,似乎就多了一个国际化适配。但细细一想,事情可没这么简单,前端开发面临了很多新的问题。下面梳理一下国际化开发中通常会面临的挑战: 页面文案全部可配置
- 需要配置的文案大致有四种:label、placeholder、字段校验提示信息、超链接。
- 页面文案样式处理 文案样式需要特别注意,不同语言的文字,可能会有不同的表现。例如下面两张图所示:
英语(页面样式正常)
- 日期、数字格式处理 页面上展示日期或数量的地方,也是需要做国际化适配。
- LTR/RTL 很多中东国家的语言习惯都是 RTL,可以尝试使用 direction 和 transform 来解决。
- 图片(banner)国际化 如果你想把国际化做的足够精细,那么图片国际化也是需要考虑的。
- 第三方 UI 组件 如果使用了第三方 UI 组件,如:elementUI、ant design UI 等,这些 UI 框架通常都宣称支持国际化,但支持的国际化语言数量有限,并不一定能满足业务需求。
- 前端开发工作量和后期维护成本激增 大量的文案需要被提取出来,被提取出来的文案最终会被合并到一个文件中去,如:en-US.json。这些工作如果通过手工完成,那么工作量会是非常巨大的。
国际化文案的处理思路
以上列举出了很多挑战,但实际上“页面文案处理”才是最主要的矛盾,因为它直接导致前端开发工作量和维护成本的激增。下面我们重点来讨论文案处理思路,其实从实现国际化的角度来看,jQuery、Vue、React 等都只是载体而已,实现思路都是相通的,因此国际化文案处理与具体的技术框架并不耦合。接下来将会抛出几种国际化文案处理思路,每种思路对生产力和生产关系的要求有高有低,姑且将其分别对应为石器时期、青铜时期、黄金时期。
石器时期
传统的国际化开发流程:前端开发到一定阶段,将文案提取到资源文件(通常为 en-US.json),然后将资源文件发送给翻译团队,翻译团队翻译出各国语言版本的文案,每种语言对应一个资源文件,最后将这些资源文件发回给前端开发人员,前端开发人员更新到自己本地。如下图所示:
- 适用场景
1.页面上要提取的文案不多
2.支持的国际化语言较少,比如:只需要支持中文和英文
3.项目需求较固定,后期只做简单维护,不会新增大的需求
4.分析 这是国际化开发的基本流程,“前端开发”和“翻译团队”是必不可少的两个节点,但它们相互之间依赖的太重。“提取文案”的过程本质上是在重复劳动,因此可以考虑由程序来完成。
5.代码示例
6.App.js
import React, { Component } from 'react';
import { IntlProvider, FormattedMessage } from 'react-intl';
import qs from 'querystring';
import logo from './logo.svg';
import './App.css';
import DEFAULT_MESSAGES from './i18n/en-US.json';
const DEFAULT_LOCALE = 'en-US';
class App extends Component {
state = {
messages: DEFAULT_MESSAGES,
};
componentWillMount() {
const search = window.location.search.slice(1);
const params = qs.parse(search);
const locale = params.locale || DEFAULT_LOCALE;
const messages = require(`./i18n/${locale}.json`);
debugger;
this.setState({
messages,
});
}
render() {
const { messages } = this.state;
return (
<IntlProvider locale="en" messages={messages}>
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<FormattedMessage
id="welcome"
defaultMessage={`Hello world!`}
/>
</p>
<a
className="App-link"
href="/?locale=zh-CN"
rel="noopener noreferrer"
>
zh-CN
</a>
<a
className="App-link"
href="/?locale=en-US"
rel="noopener noreferrer"
>
en-US
</a>
</header>
</div>
</IntlProvider>
);
}
}
export default App;
复制代码
en-US.json
{
"welcome": "Hello world!"
}
复制代码
青铜时期
前面分析了“提取文案”的过程本质上是在重复劳动,那我们看看有没有办法进行改进。我们可以先对比一下“无国际化需求”和“有国际化需求”时的前端开发流程。如图所示:
- 将文案提取为变量
- 为变量命名,要合乎其场景
- 将变量和文案信息存到资源文件
这里我们提出一个期望或愿景:希望能像开发普通业务一样去开发有国际化需求的业务!