聊聊前端國際化文案該如何處理

NO IMAGE

背景

最近接到一個海外項目業務需求,項目最終會被來自不同國家的客戶所使用,期望能讓客戶有一個良好的用戶體驗,因此前端需要適配國際化。

面臨的挑戰

乍一聽,這個海外項目需求並沒有什麼特別的地方,似乎就多了一個國際化適配。但細細一想,事情可沒這麼簡單,前端開發面臨了很多新的問題。下面梳理一下國際化開發中通常會面臨的挑戰:

  • 頁面文案全部可配置
    需要配置的文案大致有四種: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. 項目需求較固定,後期只做簡單維護,不會新增大的需求
  • 分析
    這是國際化開發的基本流程,“前端開發”和“翻譯團隊”是必不可少的兩個節點,但它們相互之間依賴的太重。“提取文案”的過程本質上是在重複勞動,因此可以考慮由程序來完成。

  • 代碼示例

    • 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!"
    }
    

青銅時期

前面分析了“提取文案”的過程本質上是在重複勞動,那我們看看有沒有辦法進行改進。我們可以先對比一下“無國際化需求”和“有國際化需求”時的前端開發流程。如圖所示:

聊聊前端國際化文案該如何處理

可以看出右邊多了三個過程:

  1. 將文案提取為變量
  2. 為變量命名,要合乎其場景
  3. 將變量和文案信息存到資源文件

這裡我們提出一個期望或願景:希望能像開發普通業務一樣去開發有國際化需求的業務!

為了達成這一願景,我們需要有一個工具:它能夠掃描指定的文件,並能識別出文件中的字符串,然後能根據字符串的含義生成變量名,並用變量表達式替換掉原來的字符串,最後能夠將提取出來的變量自動追加到資源文件中。

如何實現這樣的工具?我們可以用 Babel 將js文件解析為一顆語法樹,然後遍歷並找出字符串節點,接下來調用 Google Cloud Translation API 將字符串翻譯為英文,並以此作為變量名得到變量表達式,最後用變量表達式替換掉原來的文本即可。如下圖所示:

聊聊前端國際化文案該如何處理

幸運的是,i18n-pick 已經有那麼點味道了~

聊聊前端國際化文案該如何處理

  • 分析
    這是站在開發層面,對前端開發體驗和開發效率提出的改進辦法,將重複的事情交給程序去完成

黃金時期

有了石器時期的生產方式作為鋪墊,我們可以在此基礎上繼續做改進。既然“前端開發”和“翻譯團隊”之間依賴的太重,那我們可以在中間加一個節點“文案配置平臺”。前端將提取的文案直接上傳到“文案配置平臺”,翻譯團隊直接在“文案配置平臺”上進行文案翻譯,前端直接從“文案配置平臺”獲取翻譯後的最新文案。

聊聊前端國際化文案該如何處理

  • 文案配置平臺應當具備的基本能力
    1. 面向前端開發人員:文案錄入、輸出
    2. 面向翻譯團隊:文案翻譯、發佈
    3. 其他:文案版本控制
  • 適用場景
    1. 有大量的國際化業務需求
    2. 希望將其沉澱為通用能力平臺,提升業務開發效率
  • 分析
    這是從架構層面對國際化開發方式進行優化和提效,一般大的互聯網公司因為其自身業務的複雜度,都早已沉澱出很多的通用能力平臺。

總結

以上每種思路都有各自適用的場景,實際生產中需要從開發成本、開發體驗、後期維護、能力沉澱等多維度進行考慮。這篇文章旨在拋磚引玉打開思路,各位看官可以將自己的思路拋出來一起討論。

參考

文章可隨意轉載,但請保留此 原文鏈接

非常歡迎有激情的你加入 ES2049 Studio,簡歷請發送至 caijun.hcj(at)alibaba-inc.com

相關文章

簡單,真誠「阿里新零售CRO技術部大前端團隊」春招實習!

「每日一瞥📰」0218~0308

從手機端H5製作來看WEB動畫的術與道

「譯」使用WebAssembly替換應用程序中的HotPath