
使用 Storybook 进行国际化
如何使用 Storybook 进行组件国际化

支持应用中的多种语言是一项棘手的任务。有些语言的词语较长,会导致意外的文本溢出。有些语言在不同地区之间有不同的区域设置——例如英国英语 vs 美国英语。还有一些语言是从右到左阅读的,这会改变整个页面的布局。
面向全球受众的应用需要国际化(i18n),即“本地化”应用以适应不同地区。但国际化 UI 非常繁琐。您必须在每种支持的区域设置中验证应用的每个状态,开发过程中需要手动切换语言偏好设置。
有了 Storybook,您可以将任意区域设置传递给组件,而无需更改浏览器偏好设置,只需单击即可切换区域设置。本教程将向您展示如何操作。
➕ 在 Storybook 中公开 i18next 翻译
🎁 使用 i18next provider 包裹 stories
🔘 在工具栏中添加区域设置切换器
👈 添加从右到左的语言支持
我们将构建什么
大多数开发者都使用 i18next,这是一个流行的 JavaScript 库,允许应用为每种支持的区域设置定义单独的文件。它会检测用户的语言偏好和区域设置,并且只加载检测到的区域设置。
区域设置不是作为输入传递给组件,而是通过上下文全局共享。让我们使用 i18next 来扩展 Storybook,在工具栏中添加一个区域设置切换器,以便选择与您的组件共享的区域设置。
请参考 i18next-react GitHub 仓库中的 代码示例 进行学习。

先决条件
在开始之前,请确保您有一个使用 i18next-react 的可运行 React 应用,并且已设置了 Storybook 6.0 或更高版本。如果您需要设置这些的资源,我在下面提供了一些建议:
或者,如果您更喜欢视频,可以观看 Chantastic 关于为您的 React 应用添加 i18next 的精彩视频。
1. 将 i18next 公开到 Storybook
为了使您的翻译在 stories 中可用,您需要首先将您的 i18next 实例公开到 Storybook。以下是我 React 应用中使用的 ./src/i18n.js 文件中的 i18next 实例示例。
// src/i18n.js
import i18n from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
i18n
.use(Backend) // lazy loads translations from /public/locales
.use(LanguageDetector) // detect user language
.init({
fallbackLng: 'en',
debug: true,
interpolation: {
escapeValue: false,
},
});
export default i18n;为了将此实例公开到 Storybook,我们可以将其导入到 ./.storybook/preview.js 文件中,Storybook 在此文件中保存其共享的 story 配置。
// .storybook/preview.js
import i18n from '../src/i18n';2. 使用 i18next provider 包裹您的 stories
既然 Storybook 已经可以访问 i18next,我们需要将其与我们的 stories 共享。为此,我们将创建一个 decorator 来包裹我们的 stories。
// .storybook/preview.js
import React, { Suspense } from "react";
import { I18nextProvider } from "react-i18next";
import i18n from '../src/i18n';
// Wrap your stories in the I18nextProvider component
const withI18next = (Story) => {
return (
// This catches the suspense from components not yet ready (still loading translations)
// Alternative: set useSuspense to false on i18next.options.react when initializing i18next
<Suspense fallback={<div>loading translations...</div>}>
<I18nextProvider i18n={i18n}>
<Story />
</I18nextProvider>
</Suspense>
);
};
// export decorators for storybook to wrap your stories in
export const decorators = [withI18next];太棒了!我们的 stories 现在正式拥有了翻译的访问权限。如果我们更改 ./src/i18n.js 中定义的 lng,您会看到 stories 以新的语言重新加载。

3. 添加区域设置切换器
硬编码您的区域设置很麻烦,并且对查看已部署 Storybook 的任何人都没有帮助,因此让我们为 Storybook 工具栏添加一个区域设置切换器。如果您想了解更多关于切换器的信息,请查看 Yann Braga 的关于添加主题切换器到 Storybook 的文章。
为此,我们可以在 .storybook/preview.js 中声明一个名为 locale 的全局变量,并为其分配一个支持的语言列表供选择。
// .storybook/preview.js
/* Snipped for brevity */
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
locale: {
name: 'Locale',
description: 'Internationalization locale',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', title: 'English' },
{ value: 'de', title: 'Deutsch' },
],
showName: true,
},
},
};
回顾 Storybook,我们现在可以看到工具栏中添加了一个“Locale”(区域设置)切换器,其中包含我们刚刚设置的选项。

现在让我们更新 decorator 以便在我们选择新语言时更改区域设置。
// .storybook/preview.js
/* Snipped for brevity */
const withI18next = (Story, context) => {
const { locale } = context.globals;
// When the locale global changes
// Set the new locale in i18n
useEffect(() => {
i18n.changeLanguage(locale);
}, [locale]);
return (
<Suspense fallback={<div>loading translations...</div>}>
<I18nextProvider i18n={i18n}>
<Story />
</I18nextProvider>
</Suspense>
);
};
瞧——一个由 i18next-react 驱动的、功能齐全的区域设置切换器,适用于您的 stories!

4. 设置文档方向
有些语言不像英语那样是从左到右阅读的。例如,阿拉伯语是从右到左阅读的。HTML 通过 dir 属性内置了对这一点的支持。
首先,让我们将阿拉伯语作为选项添加到区域设置切换器中,方法是将一个对象添加到我们的 globalTypes 的 items 数组中。
// .storybook/preview.js
/* Snipped for brevity */
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
locale: {
name: 'Locale',
description: 'Internationalization locale',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', title: 'English' },
{ value: 'de', title: 'Deutsch' },
{ value: 'ar', title: 'عربي' },
],
showName: true,
},
},
};通过使用 i18next 的 dir(lng) 函数和 languageChanged 事件,我们可以为选定的区域设置设置文档方向。
// .storybook/preview.js
/* Snipped for brevity */
// When The language changes, set the document direction
i18n.on('languageChanged', (locale) => {
const direction = i18n.dir(locale);
document.dir = direction;
});
现在,当我们将其设置为阿拉伯语时,Storybook 的文档方向将设置为 ”rtl” 🎉

总结
在 Storybook 中添加区域设置切换器,可以让我们使用更长的字符串甚至像阿拉伯语这样的从右到左的语言来检查组件。
如果您想参考我的 DIY 实现,请查看 i18next-react 的 Storybook 示例。但是,如果您希望有人为您处理这些,请查看 Stevensack 出色的 storybook-react-i18next 插件。
想要更多教程?
我们希望听到您的声音!
您喜欢这个教程吗?您还想看到哪些其他的 Storybook 集成教程?
请在 @storybookjs 上发推,或在 Storybook Discord 服务器上联系我们!我们迫不及待想见到您 🤩
支持 i18n 任务艰巨!为什么呢?
— Storybook (@storybookjs) 2022年9月21日
📏 冗长的翻译会导致意外的文本溢出
👯 不同地区存在多种区域设置——例如英国 vs 美国英语
👈 从右到左会改变整个布局
在我们的新教程中了解如何使用 Storybook 测试您的 i18n UI https://#/3X20kUguWN pic.twitter.com/SMBiinTiYu