Faker 本地化完整指南:切换 70+ 语言、构建自定义回退链与处理缺失数据
【免费下载链接】fakerGenerate massive amounts of fake data in the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/faker/faker
本指南以 docs/guide/localization.md 为核心,系统讲解 Faker 的多语言机制:如何切换到德语、中文等 70 余种预构建语言实例,如何通过new Faker({ locale: [...] })构建自定义 locale 与回退链,以及如何解读并解决 "Missing Data" 与 "Not-Applicable Data" 两类典型错误。读完本文,你将掌握从"默认英文数据"到"任意语言定制实例"的完整实战方案,并能结合 locale 代理源码 理解其底层查找原理。
一、快速切换语言:预构建 locale 实例
默认情况下,从@faker-js/faker导入的faker实例生成的是英文数据。Faker 内置了超过 70 个预构建的语言实例,每个实例都是一个独立的Faker对象,可直接导入使用。
例如,切换到德语:
import { fakerDE as faker } from '@faker-js/faker'; faker.person.fullName(); // 生成德语风格的全名这种按需导入的实例在 src/locale/index.ts 中集中导出,每个 locale 文件(如 src/locale/de.ts)内部都会构建一个带合理回退链的实例:
// src/locale/de.ts(自动生成) export const faker = new Faker({ locale: [de, en, base], });可以看到,即使是最普通的fakerDE实例,内部也按de → en → base的优先级组织数据:先取德语定义,缺失时回退到最完整的英文,再回退到跨语言通用的base定义。
::: tip 提示 你也可以用new Faker(...)自行构建自定义实例,实现 locale 覆盖与自定义回退,详见下文。 :::
二、构建自定义 locale 与回退链
当内置实例无法满足需求时,可以自己组装 locale。核心思路是:给Faker构造函数传入一个 locale 数组,按优先级从高到低排列,运行时取第一个包含所需数据的定义。
2.1 完整示例:自定义 locale + 多级回退
import type { LocaleDefinition } from '@faker-js/faker'; import { base, de, de_CH, en, Faker } from '@faker-js/faker'; const customLocale: LocaleDefinition = { title: 'My custom locale', internet: { domainSuffix: ['test'], }, }; export const customFaker = new Faker({ locale: [customLocale, de_CH, de, en, base], });上述例子包含 5 个 locale,按顺序逐一检查,第一个包含请求数据的定义胜出:
| 顺序 | locale | 作用 |
|---|---|---|
| 1 | customLocale | 自定义定义,覆盖其下所有回退定义(如domainSuffix使用['test']) |
| 2 | de_CH | 瑞士德语,用瑞士(CH)数据覆盖部分德语定义 |
| 3 | de | 通用德语定义 |
| 4 | en | 通用英文定义。Faker 最完整的 locale,用于填补缺口;是否作为回退视需求而定 |
| 5 | base | 基础定义,包含所有语言通用的数据(如 emoji、ISO 代码、时区等) |
关于base,src/locales/base/index.ts 的注释明确说明:"The base locale contains data that is shared across all locales such as ISO codes, time zones, and more",即它承载跨语言共享的数据,应始终作为回退链的兜底。
2.2 底层合并逻辑
从源码看,locale 数组并不是简单的"运行时逐层查找",而是在创建实例时先合并成一个扁平对象。核心逻辑位于 src/utils/merge-locales.ts:
export function mergeLocales(locales: LocaleDefinition[]): LocaleDefinition { const merged: LocaleDefinition = {}; for (const locale of locales) { for (const key in locale) { const value = locale[key]; if (merged[key] === undefined) { merged[key] = { ...value }; } else { merged[key] = { ...value, ...merged[key] }; } } } return merged; }合并时后面的 locale 会覆盖前面的同名条目({ ...value, ...merged[key] }中后者优先)。这与createFakerCore的调用方式相互印证——src/core.ts 在创建核心时执行:
locale: createLocaleProxy( Array.isArray(locale) ? mergeLocales(locale) : locale ),因此数组中的第一个 locale 拥有最高优先级,这也解释了 2.1 示例中的查找顺序。合并后的对象再被包装成只读的 LocaleProxy,任何对实例上 locale 数据的赋值都会被拒绝(抛出You cannot edit the locale data on the faker instance)。
三、可用 locale 全览
以下为当前仓库内置的全部 locale(Locale列与Faker列分别对应数据定义与实例的导入名,例如import { de, fakerDE } from '@faker-js/faker'):
| Locale | Name | Faker |
|---|---|---|
af_ZA | Afrikaans (South Africa) | fakerAF_ZA |
ar | Arabic | fakerAR |
az | Azerbaijani | fakerAZ |
base | Base | fakerBASE |
bn_BD | Bengali (Bangladesh) | fakerBN_BD |
cs_CZ | Czech (Czechia) | fakerCS_CZ |
cy | Welsh | fakerCY |
da | Danish | fakerDA |
de | German | fakerDE |
de_AT | German (Austria) | fakerDE_AT |
de_CH | German (Switzerland) | fakerDE_CH |
dv | Maldivian | fakerDV |
el | Greek | fakerEL |
en | English | fakerEN |
en_AU | English (Australia) | fakerEN_AU |
en_AU_ocker | English (Australia Ocker) | fakerEN_AU_ocker |
en_BORK | English (Bork) | fakerEN_BORK |
en_CA | English (Canada) | fakerEN_CA |
en_GB | English (Great Britain) | fakerEN_GB |
en_GH | English (Ghana) | fakerEN_GH |
en_HK | English (Hong Kong) | fakerEN_HK |
en_IE | English (Ireland) | fakerEN_IE |
en_IN | English (India) | fakerEN_IN |
en_NG | English (Nigeria) | fakerEN_NG |
en_NP | English (Nepal) | fakerEN_NP |
en_US | English (United States) | fakerEN_US |
en_ZA | English (South Africa) | fakerEN_ZA |
eo | Esperanto | fakerEO |
es | Spanish | fakerES |
es_MX | Spanish (Mexico) | fakerES_MX |
fa | Farsi/Persian | fakerFA |
fi | Finnish | fakerFI |
fr | French | fakerFR |
fr_BE | French (Belgium) | fakerFR_BE |
fr_CA | French (Canada) | fakerFR_CA |
fr_CH | French (Switzerland) | fakerFR_CH |
fr_LU | French (Luxembourg) | fakerFR_LU |
fr_SN | French (Senegal) | fakerFR_SN |
he | Hebrew | fakerHE |
hr | Croatian | fakerHR |
hu | Hungarian | fakerHU |
hy | Armenian | fakerHY |
id_ID | Indonesian (Indonesia) | fakerID_ID |
it | Italian | fakerIT |
ja | Japanese | fakerJA |
ka_GE | Georgian (Georgia) | fakerKA_GE |
ko | Korean | fakerKO |
ku_ckb | Kurdish (Sorani) | fakerKU_ckb |
ku_kmr_latin | Kurdish (Kurmanji, Latin) | fakerKU_kmr_latin |
lv | Latvian | fakerLV |
mk | Macedonian | fakerMK |
mn_MN_cyrl | Mongolian (Mongolia, Cyrillic) | fakerMN_MN_cyrl |
nb_NO | Norwegian (Norway) | fakerNB_NO |
ne | Nepali | fakerNE |
nl | Dutch | fakerNL |
nl_BE | Dutch (Belgium) | fakerNL_BE |
pl | Polish | fakerPL |
pt_BR | Portuguese (Brazil) | fakerPT_BR |
pt_PT | Portuguese (Portugal) | fakerPT_PT |
ro | Romanian | fakerRO |
ro_MD | Romanian (Moldova) | fakerRO_MD |
ru | Russian | fakerRU |
sk | Slovak | fakerSK |
sl_SI | Slovenian (Slovenia) | fakerSL_SI |
sr_RS_latin | Serbian (Serbia, Latin) | fakerSR_RS_latin |
sv | Swedish | fakerSV |
ta_IN | Tamil (India) | fakerTA_IN |
th | Thai | fakerTH |
tr | Turkish | fakerTR |
uk | Ukrainian | fakerUK |
ur | Urdu | fakerUR |
uz_UZ_latin | Uzbek (Uzbekistan, Latin) | fakerUZ_UZ_latin |
vi | Vietnamese | fakerVI |
yo_NG | Yoruba (Nigeria) | fakerYO_NG |
zh_CN | Chinese (China) | fakerZH_CN |
zh_TW | Chinese (Taiwan) | fakerZH_TW |
zu_ZA | Zulu (South Africa) | fakerZU_ZA |
::: tip 关于覆盖度与启动性能 部分 locale 覆盖度有限,会更依赖英文 locale 作为缺失功能的来源。但长期来看,显式指定具体 locale 通常更有利:指定 locale 能减少实例启动所需的时间,而启动时间在每次执行都会重新加载导入的测试框架中具有累积效应(compounding effect)。 :::
四、Locale 命名规范与批量访问
4.1 命名规则
Faker 的 locale 命名高度系统化:
- 前两个字符为小写语言代码,遵循 ISO 639-1 标准,例如
ar(阿拉伯语)、en(英语); - 同一语言在不同国家有不同的地址、电话模式,可用下划线追加两位大写国家代码(遵循 ISO 3166-1 alpha-2),例如
en_US表示美式英语、en_AU表示澳大利亚英语; - 极少数情况下还需追加变体段(同样以下划线分隔),用于表示带口音的变体或不同书写系统,例如
en_AU_ocker(澳大利亚 "Ocker" 方言)、sr_RS_latin(塞尔维亚拉丁字母拼写)。
4.2 通过 allFakers / allLocales 批量访问
推荐做法是逐个具名导入。如果需要遍历所有 locale,可以访问两个聚合对象(其键为 locale 代码,定义于 src/locale/index.ts 的allFakers中):
import { allFakers, allLocales } from '@faker-js/faker'; console.dir(allFakers['de_AT']); // de_AT 的预构建 Faker 实例 console.dir(allLocales['de_AT']); // de_AT 的原始 locale 数据定义典型场景是枚举全部 locale 做抽样验证:
import { allFakers } from '@faker-js/faker'; for (let key of Object.keys(allFakers)) { try { console.log( `In locale ${key}, a sample name is ${allFakers[key].person.fullName()}` ); } catch (e) { console.log(`In locale ${key}, an error occurred: ${e}`); } }五、错误处理(一):Missing Data(数据缺失)
5.1 错误特征
当你使用的 locale 实例还不具备某个方法所需的数据时,会得到如下错误:
[Error]: The locale data for 'category.entry' are missing in this locale. Please contribute the missing data to the project or use a locale/Faker instance that has these data. For more information see https://fakerjs.dev/guide/localization.html该错误由 src/internal/locale-proxy.ts 的assertLocaleData在访问到undefined条目时抛出。从源码可以确认,这一错误的信息文本本身也是项目的一部分(... are missing in this locale)。
5.2 解决方案:补充回退
为实例追加 fallback locale 即可:
import { Faker, base, el, en } from '@faker-js/faker'; const faker = new Faker({ locale: [el, en, base], }); console.log(faker.location.country()); // 'Belgium'错误信息的措辞也印证了这一思路——缺失提示中明确建议 "use a locale/Faker instance that has these data",而追加en、base正是补全数据的标准手段。当然,也可以直接复用 自定义 Locales 与回退链 一节的方法。
六、错误处理(二):Not-Applicable Data(数据不适用)
6.1 错误特征与成因
[Error]: The locale data for 'category.entry' aren't applicable to this locale. If you think this is a bug, please report it at: https://github.com/faker-js/faker这个错误意味着当前 locale经过设计考量后确认无法提供合理取值。典型例子:香港没有邮政编码体系,因此en_HK无法提供邮编数据:
import { fakerEN_HK } from '@faker-js/faker'; console.log(fakerEN_HK.location.zipCode()); // Error从仓库源码可直接验证这一设计: src/locales/en_HK/location/postcode.ts 的内容就是export default null(并注释了香港邮政的参考链接)。assertLocaleData检测到null时即抛出该"不适用"错误。
6.2 为什么用 null 而不是空数组
对于这类"想清楚了但没有合法值"的数据,项目显式将条目设置为null。原因有二:
- 明确表达"已考虑过该数据,但无有效值可填"的语义;
- 部分 locale 数据是对象
{}而非数组[],使用null对两者都成立,无需在调用方做额外的缺失数据特殊处理。
6.3 自定义回退数据(注意优先级陷阱)
如果想改用其他回退数据,可像下面这样把自定义条目放在数组最前面:
import { Faker, en, en_HK } from '@faker-js/faker'; const faker = new Faker({ locale: [{ location: { postcode: en.location.postcode } }, en_HK], }); console.log(faker.location.zipCode()); // '17551-0348'::: warning 关键陷阱 由于null被视为已存在的数据,它不会触发回退查找。因此下面这种"把en_HK放前面、自定义条目放后面"的写法是无效的:
import { Faker, en, en_HK } from '@faker-js/faker'; const faker = new Faker({ locale: [en_HK, { location: { postcode: en.location.postcode } }], }); console.log(faker.location.zipCode()); // Error:::
结合 merge-locales.ts 的合并逻辑可以更深刻地理解这一点:en_HK的location.postcode = null属于"已定义"的条目,在合并时不会被视为空缺,因此后置的自定义postcode永远不会覆盖它——null 直接屏蔽了回退链。
七、小结
Faker 的本地化机制可归纳为三条主线:
- 即取即用:超过 70 个预构建实例(
fakerDE、fakerZH_CN等)覆盖主流语言,且内部已按具体 locale → en → base组织好回退; - 深度定制:通过
new Faker({ locale: [...] })传入数组构建自定义回退链,数组顺序即优先级顺序(第一个优先),底层由 merge-locales.ts 合并、locale-proxy.ts 代理访问; - 错误即文档:
missing(undefined 触发)与not applicable(null 触发)两类错误明确区分"没数据"与"无适用数据",前者靠追加回退解决,后者需将自定义条目置于 locale 数组之前才能生效。
无论你是需要在多语言测试场景中切换数据源,还是为特定业务定制专属的假数据定义,这套机制都能在不改动任何源码的前提下,通过配置组合满足需求。
【免费下载链接】fakerGenerate massive amounts of fake data in the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/faker/faker
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考