i18n-auto-react
Version:
基于百度翻译API服务的自动翻译插件
153 lines (149 loc) • 5.01 kB
JavaScript
;
var fs = require('fs');
var path = require('path');
var utils_log = require('./log.js');
var ignore = require('ignore');
var prettier = require('prettier');
var parser = require('@babel/parser');
var t = require('@babel/types');
var crypto = require('crypto');
var _traverse = require('@babel/traverse');
const traverse = getDefault(_traverse);
const tplRegexp = /(?<!\\)\$\{([\s\S]+?)\}/g;
function getDefault(data) {
return typeof data === 'function' ? data : data.default;
}
// 获取配置文件
const getConfiguration = () => {
let filePath = path.resolve(process.cwd(), 'i18n.config.js');
if (!fs.existsSync(filePath)) {
utils_log.logger.error(`配置文件不存在,请执行 npx i18n init`);
process.exit(0);
}
let config = require(filePath);
config.__rootPath = process.cwd();
config.include = Array.isArray(config.include)
? config.include
: [config.include];
config.exclude = Array.isArray(config.exclude)
? config.exclude
: [config.exclude];
return config;
};
// 创建文件夹
const mkdir = (dir) => {
if (!fs.existsSync(dir)) {
mkdir(path.dirname(dir));
fs.mkdirSync(dir);
}
};
// 创建文件
const createLanguageFile = async (filePath, template, data = {}) => {
mkdir(path.dirname(filePath));
const fileName = path.basename(filePath, path.extname(filePath));
const file = template
.replace('$name', `'${fileName}'`)
.replace('$data', () => JSON.stringify(data));
let code = await prettierJs(file);
fs.writeFileSync(filePath, code, { encoding: 'utf-8' });
};
async function prettierJs(code) {
const filePath = await prettier.resolveConfigFile();
const prettierConfig = (await prettier.resolveConfig(filePath)) || {};
return prettier.format(code, { parser: 'babel-ts', ...prettierConfig });
}
// 获取需要翻译的列表
function scanFile(dirPath, config, fn) {
const dirOrFiles = fs.readdirSync(dirPath, { encoding: 'utf8' });
let fileRegex = config.test;
if (typeof fileRegex === 'string')
fileRegex = new RegExp(fileRegex);
const ig = ignore().add(config.exclude);
const includes = ignore().add(config.include);
for (let item of dirOrFiles) {
const relativePath = path.relative(config.__rootPath, path.resolve(dirPath, item));
if (!ig.ignores(relativePath) || includes.ignores(relativePath)) {
const filePath = path.resolve(dirPath, item);
if (fs.lstatSync(filePath).isFile()) {
if (fileRegex.test(item))
fn(filePath);
}
else {
scanFile(filePath, config, fn);
}
}
}
}
function babelParse(code) {
try {
const ast = parser.parse(code, {
sourceType: 'module',
errorRecovery: true,
plugins: ['jsx', 'typescript', 'decorators-legacy'].filter((n) => n)
});
if (ast.errors.length > 0) {
ast.errors.forEach((err) => utils_log.logger.error(err));
return;
}
return ast;
}
catch (error) {
utils_log.logger.error(error);
}
}
function isCallExpression(path, importInfo) {
let { imported, local } = importInfo;
if (t.isCallExpression(path.parent)) {
let name = path.parent.callee.name;
if (name === imported || local === name)
return true;
}
return false;
}
function md5Hash(str, secretKey) {
let md5;
if (secretKey) {
md5 = crypto.createHmac('md5', secretKey);
}
else {
md5 = crypto.createHash('md5');
}
return md5.update(str).digest('hex');
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function readLanguages(name, config, isExit = false) {
const { output } = config;
const { dir: outputPath, ext = 'js' } = output;
let curFilePath = path.resolve(config.__rootPath, outputPath, `${name}.${ext}`);
if (!fs.existsSync(curFilePath) && isExit) {
utils_log.logger.error(`${curFilePath} 文件不存在!`);
// process.exit(0)
}
const file = fs.readFileSync(curFilePath, { encoding: 'utf-8' });
const ast = parser.parse(file, {
sourceType: 'module',
plugins: ['typescript']
});
const res = {};
traverse(ast, {
ObjectProperty(path) {
const key = path.node.key.value || path.node.key.name;
const value = path.node.value.value || path.node.value.name;
res[key] = value || '';
}
});
return res;
}
exports.babelParse = babelParse;
exports.createLanguageFile = createLanguageFile;
exports.getConfiguration = getConfiguration;
exports.getDefault = getDefault;
exports.isCallExpression = isCallExpression;
exports.md5Hash = md5Hash;
exports.prettierJs = prettierJs;
exports.readLanguages = readLanguages;
exports.scanFile = scanFile;
exports.sleep = sleep;
exports.tplRegexp = tplRegexp;