oakPath i8n namespace

This commit is contained in:
Wang Kejun 2022-07-18 19:56:22 +08:00
parent f89e509932
commit f51708c06e
4 changed files with 221 additions and 188 deletions

View File

@ -1,9 +1,14 @@
const fs = require('fs');
const { relative } = require('path');
const { relative, resolve } = require('path');
const t = require('@babel/types');
const pull = require('lodash/pull');
const { assert } = require('console');
const oakRegex =
/(\/*[a-zA-Z0-9_-])*\/app\/(pages|components)\/|(\\*[a-zA-Z0-9_-])*\\app\\(pages|components)\\/;
const localRegex =
/(\/*[a-zA-Z0-9_-])*\/src\/(pages|components)+\/|(\\*[a-zA-Z0-9_-])*\\src\/(pages|components)+\\/;
function isOakNamespaceIdentifier(node, name) {
if (t.isJSXNamespacedName(node) && t.isJSXIdentifier(node.namespace) && node.namespace.name === 'oak'
&& t.isJSXIdentifier(node.name) && node.name.name === name) {
@ -160,35 +165,48 @@ module.exports = (babel) => {
}
},
CallExpression(path, state) {
const { cwd, filename } = state;
const res = resolve(cwd, filename).replace(/\\/g, '/');
// this.props.t/this.t/t
// t('common:detail') 不需要处理 t('detail') 需要处理;
// t(`${common}:${cc}`) 不需要处理 t(`${common}cc`) 需要处理
const { node } = path;
if (
node &&
node.callee &&
((t.isIdentifier(node.callee) &&
node.callee.name === 't') ||
(t.isMemberExpression(node.callee) &&
t.isIdentifier(node.callee.property) &&
node.callee.property.name === 't'))
) {
const arguments = node.arguments;
arguments &&
arguments.forEach((node2, index) => {
if (
index === 0 &&
t.isLiteral(node2) &&
node2.value.indexOf(':') === -1
) {
arguments.splice(
index,
1,
t.stringLiteral('house-list:' + node2.value)
);
}
});
}
if (
/(pages|components)[\w|\W]+(.tsx|.ts)$/.test(
res
)
) {
const p = res
.replace(oakRegex, '')
.replace(localRegex, '');
const eP = p.substring(0, p.lastIndexOf('/'));
const ns = eP.split('/').filter(ele => !!ele).join('-');
const { node } = path;
if (
node &&
node.callee &&
((t.isIdentifier(node.callee) &&
node.callee.name === 't') ||
(t.isMemberExpression(node.callee) &&
t.isIdentifier(node.callee.property) &&
node.callee.property.name === 't'))
) {
const arguments = node.arguments;
arguments &&
arguments.forEach((node2, index) => {
if (
index === 0 &&
t.isLiteral(node2) &&
node2.value.indexOf(':') === -1
) {
arguments.splice(
index,
1,
t.stringLiteral(ns + ':' + node2.value)
);
}
});
}
}
},
},
};

View File

@ -4,140 +4,10 @@ const Path = require('path');
const { merge, get, set, setWith } = require('lodash');
const Mode = {
domain: 'domain',
common: 'common',
entity: 'entity',
};
function buildLocales(projectPath, businessProjectPath, buildPath) {
const dataJson = {};
readProject(dataJson, projectPath, true, true, buildPath);
readProject(dataJson, businessProjectPath, false, true, buildPath);
return dataJson;
}
function readProject(json, projectPath, hasDomain, hasCommon, buildPath) {
// 读取oak-app-domain/
if (hasDomain) {
const domainLocalesPath = Path.resolve(
projectPath,
'oak-app-domain'
).replace(/\\/g, '/');
findFiles(json, domainLocalesPath, '', Mode.domain);
}
// 读取business
if (hasCommon) {
const localesPath = Path.resolve(projectPath, 'locales').replace(
/\\/g,
'/'
);
findLocales(json, localesPath, '', Mode.common);
}
const pagesPath = Path.resolve(projectPath, 'pages').replace(/\\/g, '/');
findFiles(json, pagesPath, '', Mode.entity);
// listenerFiles(pagesPath, buildPath);
const componentsPath = Path.resolve(projectPath, 'components').replace(
/\\/g,
'/'
);
findFiles(json, componentsPath, '', Mode.entity);
}
function readLocaleFiles(json, path, name, mode) {
if (!fs.existsSync(path)) {
return;
}
const files = fs.readdirSync(path);
files.forEach((val, index) => {
const lng = val.substring(val, val.indexOf('.'));
const fPath = Path.resolve(path, val).replace(/\\/g, '/');
const dataJson = fs.readJsonSync(fPath);
setWith(json, name ? `${lng}.${name}` : lng, dataJson, Object);
});
}
// pages /house/locales/zh-CN.json 或者 /house/list/locales/zh-CN.json 或者 oak-app-domain
function findFiles(json, path, name = '', mode) {
if (!fs.existsSync(path)) {
return;
}
const files = fs.readdirSync(path);
files
.filter(
(ele) =>
!['.DS_Store', 'package.json'].includes(ele) &&
!/\.(ts|less|jsx|tsx|wxml)$/.test(ele)
)
.forEach((val, index) => {
let fPath = Path.resolve(path, val).replace(/\\/g, '/');
let stats = fs.statSync(fPath);
if (stats.isDirectory()) {
// 文件夹
if (val === 'locales') {
readLocaleFiles(json, fPath, name, mode);
} else {
const name2 = getName(val);
findFiles(
json,
fPath,
name ? `${name}-${name2}` : name2,
mode
);
}
}
});
}
// locales /Common/zh-CN.json 应该没有这种/common/xx/zh-CN.json
function findLocales(json, path, name = '', mode) {
if (!fs.existsSync(path)) {
return;
}
const files = fs.readdirSync(path);
files.forEach((val, index) => {
let fPath = Path.join(path, val).replace(/\\/g, '/');
let stats = fs.statSync(fPath);
if (stats.isDirectory()) {
// 文件夹
const name2 = getName(val);
findLocales(json, fPath, name ? `${name}-${name2}` : name2, mode);
}
if (stats.isFile()) {
readLocaleFiles(json, path, name, mode);
}
});
}
function listenerFiles(path, buildPath) {
fs.watch(path, { recursive: true }, (eventType, filename) => {
console.log('\nThe file', filename, 'was modified!');
console.log('The type of change was:', eventType);
if (
/(\/_locales\/)/.test(filename) ||
/(\/locales\/)|/.test(filename)
) {
if (eventType === 'change') {
//文件内容改变
const { name, lng } = getNameAndLng(filename);
let fPath = Path.resolve(path, filename).replace(/\\/g, '/');
// 需要换成json文件
const locales = fs.readJsonSync(fPath);
const json = {};
setWith(json, name ? `${lng}.${name}` : lng, locales, Object);
mergeJsonFiles(json, buildPath, true);
}
}
});
}
const oakRegex =
/(\/*[a-zA-Z0-9_-])*\/app\/(pages|components)\/|(\\*[a-zA-Z0-9_-])*\\app\\(pages|components)\\/;
const localRegex =
/(\/*[a-zA-Z0-9_-])*\/src\/(pages|components)+\/|(\\*[a-zA-Z0-9_-])*\\src\/(pages|components)+\\/;
function getName(val) {
const name = val.substring(0, 1).toLowerCase() + val.substring(1);
@ -148,7 +18,7 @@ function getNameAndLng(path) {
let name = '';
let lng = '';
const arr = path.split('/').filter(ele => !!ele);
const arr = path.split('/').filter((ele) => !!ele);
let isLocales = false;
for (let n of arr) {
@ -168,8 +38,130 @@ function getNameAndLng(path) {
};
}
function buildLocales({
projectPath,
businessProjectPath,
buildPath,
nodeEnv,
platform,
}) {
const dataJson = {};
const projectPaths = [projectPath, businessProjectPath];
projectPaths.forEach((path) => {
readProject(dataJson, path, buildPath, nodeEnv, platform);
});
return dataJson;
}
function readProject(json, projectPath, buildPath, nodeEnv, platform) {
// 读取oak-app-domain/
const domainLocalesPath = Path.resolve(
projectPath,
'oak-app-domain'
).replace(/\\/g, '/');
findLocaleFiles(json, domainLocalesPath, '', buildPath, nodeEnv, platform);
// 读取business/locales
const localesPath = Path.resolve(projectPath, 'locales').replace(
/\\/g,
'/'
);
findLocaleFiles(json, localesPath, '', buildPath, nodeEnv, platform);
const pagesPath = Path.resolve(projectPath, 'pages').replace(/\\/g, '/');
findLocaleFiles(json, pagesPath, '', buildPath, nodeEnv, platform);
const componentsPath = Path.resolve(projectPath, 'components').replace(
/\\/g,
'/'
);
findLocaleFiles(json, componentsPath, '', buildPath, nodeEnv, platform);
}
function readLocaleFiles(json, path, name) {
if (!fs.existsSync(path)) {
return;
}
const files = fs.readdirSync(path);
files.forEach((val, index) => {
const lng = val.substring(val, val.indexOf('.'));
const fPath = Path.resolve(path, val).replace(/\\/g, '/');
const dataJson = fs.readJsonSync(fPath);
setWith(json, name ? `${lng}.${name}` : lng, dataJson, Object);
});
}
// pages /house/locales/zh-CN.json 或者 /house/list/locales/zh-CN.json 或者 oak-app-domain
function findLocaleFiles(json, path, name = '', buildPath, nodeEnv, platform) {
if (!fs.existsSync(path)) {
return;
}
const files = fs.readdirSync(path);
files
.filter(
(ele) =>
!['.DS_Store', 'package.json'].includes(ele) &&
!/\.(ts|less|jsx|tsx|wxml)$/.test(ele)
)
.forEach((val, index) => {
let fPath = Path.resolve(path, val).replace(/\\/g, '/');
let stats = fs.statSync(fPath);
if (stats.isDirectory()) {
// 文件夹
if (val === 'locales') {
readLocaleFiles(json, fPath, name);
//监听locales文件夹
if (nodeEnv !== 'production') {
listenerLocaleFiles(fPath, buildPath, nodeEnv, platform);
}
} else {
const name2 = getName(val);
findLocaleFiles(
json,
fPath,
name ? `${name}-${name2}` : name2,
buildPath,
nodeEnv,
platform
);
}
}
});
}
function listenerLocaleFiles(path, buildPath, nodeEnv, platform) {
fs.watch(path, { recursive: true }, (eventType, filename) => {
const fPath = Path.resolve(path, filename).replace(/\\/g, '/');
console.log('\nThe file', fPath, 'was modified!');
console.log('The type of change was:', eventType);
if (/(\/locales\/)|/.test(filename) && /\.(json)$/.test(filename)) {
if (eventType === 'change') {
//文件内容改变
const newFilename = fPath.replace(oakRegex, '').replace(localRegex, '');
const { name, lng } = getNameAndLng(newFilename);
const dataJson = fs.readJsonSync(fPath);
const newJson = {};
setWith(
newJson,
name ? `${lng}.${name}` : lng,
dataJson,
Object
);
if (platform === 'wechatMp') {
mergeMpJsonFiles(newJson, buildPath, true);
} else {
mergeWebJsonFiles(newJson, buildPath, true);
}
}
}
});
}
//
function mergeJsonFiles(json, buildPath, isMerge) {
function mergeWebJsonFiles(json, buildPath, isMerge) {
for (let lng in json) {
// lng生成文件夹
const lngPath = Path.resolve(buildPath, lng);
@ -194,19 +186,26 @@ function mergeJsonFiles(json, buildPath, isMerge) {
}
}
function mergeMpJsonFiles(json, buildPath, isMerge) {
for (let lng in json) {
// lng生成文件夹
const lngPath = Path.resolve(buildPath, `${lng}.json`);
// 生成json文件
function generateJsonFiles(buildPath, json) {
if (!fs.existsSync(buildPath)) {
fs.mkdirSync(buildPath);
} else {
fs.emptyDirSync(buildPath);
const data = json[lng] || {};
let dataJson = {};
if (isMerge) {
if (fs.existsSync(lngPath)) {
dataJson = fs.readJSONSync(lngPath);
}
}
merge(dataJson, data);
fs.writeFileSync(lngPath, JSON.stringify(dataJson, null, 2));
}
mergeJsonFiles(json, buildPath, false);
}
module.exports = {
buildLocales,
generateJsonFiles,
mergeWebJsonFiles,
mergeMpJsonFiles,
};

View File

@ -1,7 +1,9 @@
const fs = require('fs-extra');
const Path = require('path');
const paths = require('../../config/mp/paths');
const { buildLocales, generateJsonFiles } = require('./build-locales');
const getClientEnvironment = require('../../config/mp/env');
const env = getClientEnvironment();
const { buildLocales, mergeMpJsonFiles } = require('./build-locales');
const chalk = require('chalk');
const consola = require('consola');
@ -10,14 +12,22 @@ const Locales = 'locales';
function copyLocaleFiles() {
//build locales
consola.start(`${chalk.blueBright('读取locales生成json数据')}`);
const json = buildLocales(
paths.appRootSrc,
paths.oakGeneralBusinessAppPath
);
consola.success(`${chalk.greenBright('json数据已生成准备写入json文件')}`);
// locales到mp/dist下
const buildPath = Path.resolve(paths.appBuild, Locales);
generateJsonFiles(buildPath, json);
const json = buildLocales({
projectPath: paths.appRootSrc,
businessProjectPath: paths.oakGeneralBusinessAppPath,
buildPath,
nodeEnv: env.raw.NODE_ENV,
platform: env.raw.OAK_PLATFORM,
});
consola.success(`${chalk.greenBright('json数据已生成准备写入json文件')}`);
if (!fs.existsSync(buildPath)) {
fs.mkdirSync(buildPath);
} else {
fs.emptyDirSync(buildPath);
}
mergeMpJsonFiles(json, buildPath);
consola.success(
`${chalk.greenBright(
`json数据已写入文件可以在${buildPath}目录下查看`

View File

@ -1,12 +1,13 @@
const fs = require('fs-extra');
const Path = require('path');
const paths = require('../../config/web/paths');
const getClientEnvironment = require('../../config/web/env');
const env = getClientEnvironment();
const { buildLocales, generateJsonFiles } = require('./build-locales');
const { buildLocales, mergeWebJsonFiles } = require('./build-locales');
const chalk = require('chalk');
const consola = require('consola');
const Locales = 'locales'
const Locales = 'locales';
function copyLocaleFiles() {
//build locales
@ -14,16 +15,22 @@ function copyLocaleFiles() {
// locales到web/public下
const buildPath = Path.resolve(paths.appPublic, Locales);
consola.start(`${chalk.blueBright('读取locales生成json数据')}`);
const json = buildLocales(
paths.appRootSrc,
paths.oakGeneralBusinessAppPath,
buildPath
);
const json = buildLocales({
projectPath: paths.appRootSrc,
businessProjectPath: paths.oakGeneralBusinessAppPath,
buildPath,
nodeEnv: env.raw.NODE_ENV,
platform: env.raw.OAK_PLATFORM,
});
consola.success(
`${chalk.greenBright('json数据已生成准备写入json文件')}`
);
generateJsonFiles(buildPath, json);
if (!fs.existsSync(buildPath)) {
fs.mkdirSync(buildPath);
} else {
fs.emptyDirSync(buildPath);
}
mergeWebJsonFiles(json, buildPath);
consola.success(
`${chalk.greenBright(
`json数据已写入文件可以在${buildPath}目录下查看`
@ -33,7 +40,6 @@ function copyLocaleFiles() {
console.log(e);
throw e;
}
}
module.exports = {