1. 环境
2. 图片抽取还原脚本
const fs = require('fs')
const path = require('path')
// const TYPE = 'collect' // restore 恢复 collect 收集
const TYPE = 'restore' // restore 恢复 collect 收集
const filePath = path.resolve('./')
let index = 0
const sliceLength = 5
const IMAGE_FORMAT = [
'gif',
'jpg',
'png',
'jpeg',
'webp'
]
const EXCLUDE_DIR = [
'collectImage',
'.idea',
'node_modules'
]
if (!(fs.existsSync('./collectImage'))) {
fs.mkdirSync('collectImage')
}
/**
* 文件遍历方法
* @param filePath 需要遍历的文件路径
*/
function run(filePath) {
// 根据文件路径读取文件,返回文件列表
fs.readdir(filePath, function (err, files) {
if (err) return console.warn(err)
// 遍历读取到的文件列表
files.forEach(function (filename) {
// 获取当前文件的绝对路径
const filedir = path.join(filePath, filename)
// 根据文件路径获取文件信息,返回一个fs.Stats对象
fs.stat(filedir, function (eror, stats) {
if (eror) {
console.warn('获取文件stats失败')
} else {
const isFile = stats.isFile()// 是文件
const isDir = stats.isDirectory()// 是文件夹
if (isFile) {
if (!isImage(filename)) return
console.log(index++, filedir, 'filedir ')
switch (TYPE) {
case 'collect':
collectImageHandle(filePath, filename)
break
case 'restore':
renewalImageHandle(filePath, filename)
}
}
if (isDir && excludeDir(filename)) {
run(filedir)
}
}
})
})
})
}
const isImage = function (filename) {
const suffix = filename.slice(filename.lastIndexOf('.') + 1)
// 常用图片格式
return IMAGE_FORMAT.includes(suffix)
}
const excludeDir = function (filename) {
return !(
EXCLUDE_DIR.includes(filename)
)
}
const collectImageHandle = function (filePath, filename) {
const fileDir = path.join(filePath, filename)
const newName = fileDir.slice(sliceLength)
const encodeName = encodeURI(newName)
// eslint-disable-next-line handle-callback-err
fs.readFile(fileDir, function (err, originBuffer) { // 读取图片位置(路径)
fs.writeFile(`./collectImage/${encodeName}`, originBuffer, function (err) { // 生成图片2(把buffer写入到图片文件)
if (err) {
console.log(err)
}
})
})
}
const renewalImageHandle = function (filePath, filename) {
const fileDir = path.join(filePath, filename)
const newName = fileDir.slice(sliceLength)
const encodeName = encodeURI(newName)
// eslint-disable-next-line handle-callback-err
fs.readFile(`./collectImage/${encodeName}`, function (err, originBuffer) { // 读取图片位置(路径)
fs.writeFile(fileDir, originBuffer, function (err) { // 生成图片2(把buffer写入到图片文件)
if (err) {
console.log(err)
}
})
})
}
// 调用文件遍历方法
run(filePath)
3. chart-cli
功能: 通过命令选择预设, 生成一系列文件, code 在github
4. 文件内容拆分
功能, 把i18n下的语言拆分到各个业务模块里面
- 主splitScript.js 运行文件 ```javascript // const fs = require(‘fs’) const US = require(‘./src/i18n/lang/en-Us’) const CN = require(‘./src/i18n/lang/zh-CN’) const path = require(‘path’) const fs = require(‘fs-extra’) const ejs = require(‘ejs’)
const finishBussinessType = [] const hasFile = [] const notExist = [] const finish = { ‘en-US’: [], ‘zh-CN’: [] } function renderEjs(type, data) { const template = fs.readFileSync(‘./i18nTemplate.js’, ‘utf8’) let content = ejs.render(template, { type, data }) content = content.replace(/,([^,]+?)$/, ‘$1’) return content }
function traverseFile(file, key) { for (const u of Object.keys(file)) { const cwdPath = process.cwd() // 判断业务文件夹是否存在 const businessPath = path.join(cwdPath, ‘\src\pages\business’, u) if (!fs.existsSync(businessPath)) { notExist.includes(‘’ + u) || notExist.push(‘’ + u) continue }
const businessLangPath = path.join(cwdPath, '\\src\\pages\\business', u, 'lang', `${key}.js`)
if (fs.existsSync(businessLangPath)) {
hasFile.includes('' + u) || hasFile.push('' + u)
continue
}
try {
const ejsFile = renderEjs(u, file[u])
const _path = path.join(cwdPath, '\\src\\pages\\business', u, 'lang', `${key}.js`)
fs.ensureDirSync(path.dirname(_path))
console.log('创建文件路径: ', _path)
fs.writeFileSync(_path, ejsFile)
finish[key].push('' + u)
finishBussinessType.includes('' + u) || finishBussinessType.push('' + u)
} catch (e) {
console.log(e, 'e ')
}
} } traverseFile(US, ‘en-US’) traverseFile(CN, ‘zh-CN’) console.log(‘抽离完成success…… ‘) console.log(‘创建en-US’ + finish[‘en-US’].length) console.log(‘创建zh-CN’ + finish[‘zh-CN’].length) // fs.writeFileSync(‘script-finish.js’, ‘const arr = [\n\’’ + finishBussinessType.join(‘\’,\n\’’) + ‘\’\n]’) // fs.writeFileSync(‘script-hasFile.js’, ‘const arr = [\n\’’ + hasFile.join(‘\’,\n\’’) + ‘\’\n]’) // fs.writeFileSync(‘script-notExist.js’, ‘const arr = [\n\’’ + notExist.join(‘\’,\n\’’) + ‘\’\n]’)
fs.writeFileSync(‘script-finish.json’, JSON.stringify({ arr: finishBussinessType })) fs.writeFileSync(‘script-hasFile.json’, JSON.stringify({ arr: hasFile })) fs.writeFileSync(‘script-notExist.json’, JSON.stringify({ arr: notExist }))
2. 配合文件i18nTemplate.js
```javascript
export default {
<%=type %>: {
<%for (let key in data){%><%-key%>: '<%-data[key]%>',
<%}%>
}
}
- 重构i18n文件脚本 把已迁移的业务删除 script-delete-key.js ```javascript // const fs = require(‘fs’) const US = require(‘./src/i18n/lang/en-Us’) const CN = require(‘./src/i18n/lang/zh-CN’) const path = require(‘path’) const fs = require(‘fs-extra’) const ejs = require(‘ejs’)
let finishJson = fs.readFileSync(‘./script-finish.json’, ‘utf8’) let hasFileJson = fs.readFileSync(‘./script-hasFile.json’, ‘utf8’)
finishJson = JSON.parse(finishJson) hasFileJson = JSON.parse(hasFileJson) const deleteKeys = finishJson.arr.concat(hasFileJson.arr) function renderEjs(arr) { const template = fs.readFileSync(‘./i18nTemplateAll.js’, ‘utf8’) let content = ejs.render(template, { arr }) content = content.replace(/,([^,]+?)$/, ‘$1’) return content }
function traverseFile(file, key) {
const surPlus = {}
for (const keys of Object.keys(file)) {
const isDel = deleteKeys.includes(keys)
if (!isDel) {
surPlus[keys] = file[keys]
}
}
const ejsFile = renderEjs(surPlus)
const _path = lang/${key}.js
fs.ensureDirSync(path.dirname(_path))
fs.writeFileSync(_path, ejsFile)
}
traverseFile(US, ‘en-US’) traverseFile(CN, ‘zh-CN’) console.log(‘ 删除完成success…’)
4. 配合文件 i18nTemplateAll.js
```javascript
// const fs = require('fs')
const US = require('./src/i18n/lang/en-Us')
const CN = require('./src/i18n/lang/zh-CN')
const path = require('path')
const fs = require('fs-extra')
const ejs = require('ejs')
let finishJson = fs.readFileSync('./script-finish.json', 'utf8')
let hasFileJson = fs.readFileSync('./script-hasFile.json', 'utf8')
finishJson = JSON.parse(finishJson)
hasFileJson = JSON.parse(hasFileJson)
const deleteKeys = finishJson.arr.concat(hasFileJson.arr)
function renderEjs(arr) {
const template = fs.readFileSync('./i18nTemplateAll.js', 'utf8')
let content = ejs.render(template, { arr })
content = content.replace(/,([^,]+?)$/, '$1')
return content
}
function traverseFile(file, key) {
const surPlus = {}
for (const keys of Object.keys(file)) {
const isDel = deleteKeys.includes(keys)
if (!isDel) {
surPlus[keys] = file[keys]
}
}
const ejsFile = renderEjs(surPlus)
const _path = `lang/${key}.js`
fs.ensureDirSync(path.dirname(_path))
fs.writeFileSync(_path, ejsFile)
}
traverseFile(US, 'en-US')
traverseFile(CN, 'zh-CN')
console.log(' 删除完成success...')
5. 正则匹配中文脚本
const fs = require('fs')
const path = require('path')
const map = {}
const excludes = ['.css', 'assets', 'swiper', '.png', 'dist', 'node_modules', 'dll', 'h5static', 'static', 'ico', 'tests', '.lock', '.md', 'package', '.jpg', 'images', '.git', 'chinese', 'build', 'main.js', 'areaData.js', 'area.vue', 'area.js', 'area']
const chineseMap = {}
const repets = []
let uid = 0
function run(url) {
fs.stat(url, (err, stats) => {
if (err) return console.log(err)
if (stats.isDirectory()) {
fs.readdir(url, (err, paths) => {
if (err) return console.log(err)
paths.forEach(p => {
if (!excludes.some(v => p.includes(v))) run(path.resolve(url, p))
})
})
} else {
uid++
console.log(uid)
fs.readFile(url, 'utf-8', (err, data) => {
uid--
if (err) return console.log(err)
console.log(url + ' is readed')
let dirName = ''
const [, appType] = url.match(/\\(\d+)\\/) || []
if (appType) {
dirName = appType
} else {
const ps = url.split(path.sep)
if (ps[ps.length - 3] === 'src' || ps[ps.length - 2] !== 'components') {
dirName = ps[ps.length - 3] + '/' + ps[ps.length - 2]
} else {
dirName = ps[ps.length - 4] + '/' + ps[ps.length - 3]
}
}
data = data.replace(/(\s\/\/[\S\s]*?[\r\n])|(\/\*[\S\s]*?\*\/)|(<!--[\S\s]*?-->)/g, '')
// map[url] = (data.match(/['"][\u4e00-\u9fa5\s,:;?!]+?['"]/g) || [])
// .concat((data.match(/`.+?`/g) || []).filter(v => /[\u4e00-\u9fa5]/.test(v)))
// .join('\n')
const res = []
const reg = /({{[\S\s]*?}})|(`[\S\s]*?`)|('[\S\s]*?')|("[\S\s]*?")|([\u4e00-\u9fa5,]+)/
const chineseReg = /[\u4e00-\u9fa5]/
let str = data
let match = reg.exec(str)
let tmp
while (match) {
tmp = match[0]
if (tmp[0] === '{') {
tmp = tmp.slice(2, -2)
} else if (tmp[0] === '"' || tmp[0] === "'") {
tmp = tmp.slice(1, -1)
}
if (chineseReg.test(tmp)) {
if (chineseMap[tmp]) {
if (chineseMap[tmp] !== dirName && chineseMap[tmp] !== '_isRecorded') {
map[chineseMap[tmp]] = map[chineseMap[tmp]].filter(v => v !== tmp)
repets.push(tmp)
chineseMap[tmp] = '_isRecorded'
}
} else {
chineseMap[tmp] = dirName
res.push(tmp)
}
}
str = str.replace(match[0], '')
match = reg.exec(str)
}
map[dirName] = map[dirName] ? map[dirName].concat(res) : res
if (uid === 0) { // completed
fs.writeFile(path.resolve(process.cwd(), 'repets.txt'), repets.join('\n'), 'utf-8', () => { })
fs.writeFile(path.resolve(process.cwd(), 'chinese.txt'), Object.entries(map).reduce((res, [dir, values = []]) => {
if (!values.length) return res
return res + '\n\n' +
'----------------' + dir + '---------------'
+ '\n' + values.join('\n')
}, ''), 'utf-8', () => { })
}
})
}
})
}
// run(path.resolve(process.cwd(), 'src', 'pages', 'business', '1058', 'Detail.vue'));
// run(path.resolve(process.cwd(), 'src'))
[
'h5-index',
'h5-component',
'web-component',
'web-index',
'web-basic-admin'
].forEach(v => {
run(path.resolve(process.cwd(), v, 'src'))
})