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

ES2049發表於2019-02-18

背景

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

面臨的挑戰

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

  • 頁面文案全部可配置 需要配置的文案大致有四種: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

相關文章