UNPKG

wodax-umi-plugin-locale

Version:

A umi plugin for provide internationalization function.

145 lines (132 loc) 4.48 kB
// // TODOLIST: // - 单元测试 // - example 里面的 antd 依赖改为 umi 插件 // import { join, dirname, basename } from 'path'; import { existsSync, readFileSync, writeFileSync } from 'fs'; import { winPath } from 'umi-utils'; import Mustache from 'mustache'; import globby from 'globby'; import groupBy from 'lodash.groupby'; const momentLocation = require.resolve('moment/locale/zh-cn').replace(/zh\-cn\.js$/, ''); function getMomentLocale(lang, country) { if (existsSync(join(momentLocation, `${lang}-${country.toLocaleLowerCase()}.js`))) { return `${lang}-${country.toLocaleLowerCase()}`; } if (existsSync(join(momentLocation, `${lang}.js`))) { return lang; } return ''; } // export for test export function getLocaleFileList(absSrcPath, absPagesPath, singular) { const localeFileMath = /^([a-z]{2})-([A-Z]{2})\.(js|ts)$/; const localeFolder = singular ? 'locale' : 'locales'; const localeFiles = globby .sync('*.{ts,js}', { cwd: join(absSrcPath, localeFolder), }) .map(name => join(absSrcPath, localeFolder, name)) .concat( globby .sync(`**/${localeFolder}/*.{ts,js}`, { cwd: absPagesPath, }) .map(name => join(absPagesPath, name)), ) .filter(p => localeFileMath.test(basename(p))) .map(fullname => { const fileName = basename(fullname); const fileInfo = localeFileMath.exec(fileName); return { name: `${fileInfo[1]}-${fileInfo[2]}`, path: fullname, }; }); const groups = groupBy(localeFiles, 'name'); return Object.keys(groups).map(name => { const fileInfo = name.split('-'); return { lang: fileInfo[0], name, country: fileInfo[1], paths: groups[name].map(item => winPath(item.path)), momentLocale: getMomentLocale(fileInfo[0], fileInfo[1]), }; }); } // data come from https://caniuse.com/#search=intl // you can find all browsers in https://github.com/browserslist/browserslist#browsers const polyfillTargets = { ie: 10, firefox: 28, chrome: 23, safari: 9.1, opera: 12.1, ios: 9.3, ios_saf: 9.3, operamini: Infinity, op_mini: Infinity, android: 4.3, blackberry: Infinity, operamobile: 12.1, op_mob: 12.1, explorermobil: 10, ie_mob: 10, ucandroid: Infinity, }; export function isNeedPolyfill(targets = {}) { return ( Object.keys(targets).find(key => { const lowKey = key.toLocaleLowerCase(); return polyfillTargets[lowKey] && polyfillTargets[lowKey] >= targets[key]; }) !== undefined ); } export default function(api, options = {}) { const { config, paths } = api; const { targets } = config; if (isNeedPolyfill(targets)) { api.addEntryPolyfillImports({ source: 'intl', }); } api.addRuntimePluginKey('locale'); api.addPageWatcher(join(paths.absSrcPath, config.singular ? 'locale' : 'locales')); api.onOptionChange(newOpts => { options = newOpts; api.rebuildTmpFiles(); }); api.addRendererWrapperWithComponent(() => { const localeFileList = getLocaleFileList(paths.absSrcPath, paths.absPagesPath, config.singular); const wrapperTpl = readFileSync(join(__dirname, '../template/wrapper.jsx.tpl'), 'utf-8'); const defaultLocale = options.default || 'zh-CN'; const [lang, country] = defaultLocale.split('-'); const wrapperContent = Mustache.render(wrapperTpl, { localeList: localeFileList, antd: options.antd === undefined ? true : options.antd, baseNavigator: options.baseNavigator === undefined ? true : options.baseNavigator, useLocalStorage: options.useLocalStorage || true, defaultLocale, defaultLang: lang, defaultAntdLocale: `${lang}_${country}`, defaultMomentLocale: getMomentLocale(lang, country), }); const wrapperPath = join(paths.absTmpDirPath, './LocaleWrapper.jsx'); writeFileSync(wrapperPath, wrapperContent, 'utf-8'); return wrapperPath; }); api.modifyAFWebpackOpts(memo => { return { ...memo, alias: { ...(memo.alias || {}), // umi/locale is deprecated // recommend use `import { getLocale } from 'umi-plugin-locale';` now. 'umi/locale': join(__dirname, './locale.js'), 'react-intl': dirname(require.resolve('react-intl/package.json')), }, }; }); }