在一个应用程序中支持多种语言是很棘手的。有些语言有冗长的单词,会导致意外的文本溢出。有些语言在不同地区有不同的定位--想想英国英语和美国英语。还有一些语言是从右到左阅读的,这会改变整个页面的流程。
面向全球受众的应用程序需要国际化(i18n),即为不同地区 "本地化 "应用程序的做法。但用户界面的国际化是很繁琐的。你必须在开发过程中通过手动切换语言偏好来验证你的应用程序在每个支持的地区的每个状态。
有了Storybook,你可以在不改变浏览器偏好的情况下向你的组件传递任意的语言,并且只需一次点击就可以交换语言。这个配方告诉你如何。
在Storybook中公开i18next翻译🎁
用i18next提供者包裹故事🔘
在工具栏中添加一个地区切换器
ὑ
添加从右到左的语言支持
我们正在建造的东西
大多数开发者使用 i18next,这是一个流行的JavaScript库,让应用程序为每个支持的地区定义单独的文件。它可以检测用户的语言偏好和地区,并且只加载检测到的地区性语言。
地区设置不是作为输入传递给组件,而是通过上下文全局共享。让我们使用i18next来扩展Storybook,在工具栏上添加一个地区切换器,以选择与你的组件共享哪种地区。
请使用i18next-react GitHub仓库中的代码示例进行学习。

先决条件
在我们开始之前,请确保你有一个工作的React应用程序,使用 [i18next-react](https://github.com/i18next/react-i18next)的React应用,该应用已设置为Storybook 6.0或更新版本。如果你需要资源来设置这些,我在下面附上一些建议。
如果你喜欢视频,可以看看Chantastic关于在React应用中添加i18next的精彩视频。
1.将i18next暴露给Storybook
为了使你的翻译在你的故事中可用,你首先需要将你的i18next实例暴露给Storybook。下面是一个来自./src/i18n.js 文件的i18next实例在我的React应用程序中使用的例子。
// 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保存其共享故事配置的./.storybook/preview.js 文件中。
// .storybook/preview.js
import i18n from '../src/i18n';
2.2.用i18next提供者包装你的故事
现在Storybook可以访问i18next,我们需要在我们的故事中分享它。要做到这一点,我们要做一个装饰器来包装我们的故事。
// .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];
很好!我们的故事可以正式访问我们的翻译。如果我们改变./src/i18n.js 中定义的lng ,你会看到你的故事以新的语言重新加载。

3.添加一个地区切换器
硬编码你的语言是很烦人的,而且对查看你部署的故事书的人也没有帮助,所以让我们在故事书的工具栏上添加一个语言切换器。如果你想了解更多关于切换器的信息,请查看Yann Braga的关于添加主题切换器的文章。
要做到这一点,我们可以在.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,我们现在可以看到,我们已经在工具栏上添加了一个 "地域 "切换器,上面有我们刚刚设置的选项。

现在,让我们更新我们的装饰器,当我们选择一种新的语言时,改变我们的语言环境。
// .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驱动的、功能齐全的语言切换器就出现在你的故事中了。

4.设置文档方向
有些语言不像英语那样从左到右阅读。例如,阿拉伯语是从右到左阅读的。HTML有内置的支持,即dir 属性。
首先,让我们在globalTypes的items数组中添加一个对象,把阿拉伯语作为我们的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' },
{ 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;
});
现在,当我们把故事书设置为阿拉伯语时,文档方向被设置为”rtl” 🎉。

总结
在Storybook中添加一个地区切换器,可以让你用较长的字符串,甚至是从右到左的语言(如阿拉伯语)来检查你的组件。
如果你想参考我的DIY实现,请查看i18next-react的Storybook例子。然而,如果你想让人帮你处理这个问题,可以看看Stevensack的很棒的 storybook-react-i18nextaddon。