五分钟实现React国际化

549 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情 响应式数据的基本实现

自动全局替换所有中文

i18n-pick

npm install i18n-pick --save-dev

  1. 在根目录新建i18n.config.json文件 配置如下。
{
    // 替换的页面要配置导的包
    "importStatement": "import intl from 'react-intl-universal'",
    // 中文替换为其他语言调用的方法
    "callStatement": "intl.get",
    "targetDir": "i18n-messages",
    // 不扫描替换的目录,文件
    "exclude": [
        "**/demo.{js,jsx}",
        "**/test.{js,jsx}",
        "**/pdf.worker.js"
    ],
    "callExpression": false,
    "autoZhKey": true
}

  1. package.json 增加命令
 "scripts": {
        "i18n-scan": "i18n-pick scan './src'",
        "i18n-pick": "i18n-pick pick",
 }

3. 查找所有中文

先运行

npm run i18n-scan

得到文件

image.png

并且更改为init('中文')的形式。

4. 替换所有中文的地方

先运行

npm run i18n-pick

替换前

render() {
    return(
        <div>我是中文</div>
    )
}

替换后

import intl from 'react-intl-universal'
 render() {
    return(
        <div>{{intl.get('我是中文')}}</div>
    )
}

至此国际化已经完成了一大半了。最繁琐的部分全部完成。

国际化部分

language.js页面

import en_US from './en_US.json';
import zh_CN from './zh_CN.json';
import vi_VN from './vi_VN.json';

import ant_zh_CN from 'antd/lib/locale-provider/zh_CN'
import ant_en_US from 'antd/lib/locale-provider/en_US'
import ant_vi_VN from 'antd/lib/locale-provider/vi_VN'

import 'moment/locale/zh-cn';
import 'moment/locale/en-in';
import 'moment/locale/vi';
import moment from 'moment';
import intl from 'react-intl-universal';
import React from 'react';

const momentLocalDic = {
    'zh_CN': 'zh-cn',
    'en_US': 'en-in',
    'vi_VN': 'vi',
};

const antLocalDic = {
    'zh_CN': ant_zh_CN,
    'en_US': ant_en_US,
    'vi_VN': ant_vi_VN,
};

const locales = {
    "en_US": en_US,
    "zh_CN": zh_CN,
    "vi_VN": vi_VN
}

export const localLangDic = {
    "en_US": 'English',
    "zh_CN": "简体中文",
    "vi_VN": "Tiếng Việt"
}

// 获取当前的语言,没获取到就获取浏览器的对应的语言。
export const loadLang = function () {
    const storedLang = localStorage.getItem('local')
    if (storedLang) {
        return storedLang
    }
    const navigatorLang = (window.navigator.language || '').toLocaleLowerCase()
    if (navigatorLang.indexOf('en') !== -1) {
        return "en_US"
    } else if (navigatorLang.indexOf('vi') !== -1) {
        return "vi_VN"
    } else {
        return "zh_CN"
    }
}

let currentLang = ''
export const setLanguage = function (lang) {
    localStorage.setItem('local', lang)
    moment.locale(momentLocalDic[lang]);
    intl.init({ currentLocale: lang, locales, })
}

export const getAntLang = () => antLocalDic[currentLang];
export const initLang = function () {
    setLanguage(loadLang())
}
export const getCurrentLang = function () {
    if (!currentLang) {
        currentLang = loadLang()
    }
    return currentLang
}

//transfer.js

const fs = require('fs');
const path = require('path');
let data = fs.readFileSync('./zh-CH.json', 'utf8')
const json = JSON.parse(data)

let keyDic = {}
json.map(item => {
   keyDic[item.id] = item.id
})

fs.writeFileSync(path.resolve('../src/local', 'zh_CN.json'), JSON.stringify(keyDic), function (err) {
   console.log(err)
});


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情 响应式数据的基本实现