1. 环境

Snipaste_2020-11-16_17-32-04.png

2. 图片抽取还原脚本

  1. const fs = require('fs')
  2. const path = require('path')
  3. // const TYPE = 'collect' // restore 恢复 collect 收集
  4. const TYPE = 'restore' // restore 恢复 collect 收集
  5. const filePath = path.resolve('./')
  6. let index = 0
  7. const sliceLength = 5
  8. const IMAGE_FORMAT = [
  9. 'gif',
  10. 'jpg',
  11. 'png',
  12. 'jpeg',
  13. 'webp'
  14. ]
  15. const EXCLUDE_DIR = [
  16. 'collectImage',
  17. '.idea',
  18. 'node_modules'
  19. ]
  20. if (!(fs.existsSync('./collectImage'))) {
  21. fs.mkdirSync('collectImage')
  22. }
  23. /**
  24. * 文件遍历方法
  25. * @param filePath 需要遍历的文件路径
  26. */
  27. function run(filePath) {
  28. // 根据文件路径读取文件,返回文件列表
  29. fs.readdir(filePath, function (err, files) {
  30. if (err) return console.warn(err)
  31. // 遍历读取到的文件列表
  32. files.forEach(function (filename) {
  33. // 获取当前文件的绝对路径
  34. const filedir = path.join(filePath, filename)
  35. // 根据文件路径获取文件信息,返回一个fs.Stats对象
  36. fs.stat(filedir, function (eror, stats) {
  37. if (eror) {
  38. console.warn('获取文件stats失败')
  39. } else {
  40. const isFile = stats.isFile()// 是文件
  41. const isDir = stats.isDirectory()// 是文件夹
  42. if (isFile) {
  43. if (!isImage(filename)) return
  44. console.log(index++, filedir, 'filedir ')
  45. switch (TYPE) {
  46. case 'collect':
  47. collectImageHandle(filePath, filename)
  48. break
  49. case 'restore':
  50. renewalImageHandle(filePath, filename)
  51. }
  52. }
  53. if (isDir && excludeDir(filename)) {
  54. run(filedir)
  55. }
  56. }
  57. })
  58. })
  59. })
  60. }
  61. const isImage = function (filename) {
  62. const suffix = filename.slice(filename.lastIndexOf('.') + 1)
  63. // 常用图片格式
  64. return IMAGE_FORMAT.includes(suffix)
  65. }
  66. const excludeDir = function (filename) {
  67. return !(
  68. EXCLUDE_DIR.includes(filename)
  69. )
  70. }
  71. const collectImageHandle = function (filePath, filename) {
  72. const fileDir = path.join(filePath, filename)
  73. const newName = fileDir.slice(sliceLength)
  74. const encodeName = encodeURI(newName)
  75. // eslint-disable-next-line handle-callback-err
  76. fs.readFile(fileDir, function (err, originBuffer) { // 读取图片位置(路径)
  77. fs.writeFile(`./collectImage/${encodeName}`, originBuffer, function (err) { // 生成图片2(把buffer写入到图片文件)
  78. if (err) {
  79. console.log(err)
  80. }
  81. })
  82. })
  83. }
  84. const renewalImageHandle = function (filePath, filename) {
  85. const fileDir = path.join(filePath, filename)
  86. const newName = fileDir.slice(sliceLength)
  87. const encodeName = encodeURI(newName)
  88. // eslint-disable-next-line handle-callback-err
  89. fs.readFile(`./collectImage/${encodeName}`, function (err, originBuffer) { // 读取图片位置(路径)
  90. fs.writeFile(fileDir, originBuffer, function (err) { // 生成图片2(把buffer写入到图片文件)
  91. if (err) {
  92. console.log(err)
  93. }
  94. })
  95. })
  96. }
  97. // 调用文件遍历方法
  98. run(filePath)

3. chart-cli

功能: 通过命令选择预设, 生成一系列文件, code 在github

4. 文件内容拆分

功能, 把i18n下的语言拆分到各个业务模块里面

  1. 主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 }

  1. const businessLangPath = path.join(cwdPath, '\\src\\pages\\business', u, 'lang', `${key}.js`)
  2. if (fs.existsSync(businessLangPath)) {
  3. hasFile.includes('' + u) || hasFile.push('' + u)
  4. continue
  5. }
  6. try {
  7. const ejsFile = renderEjs(u, file[u])
  8. const _path = path.join(cwdPath, '\\src\\pages\\business', u, 'lang', `${key}.js`)
  9. fs.ensureDirSync(path.dirname(_path))
  10. console.log('创建文件路径: ', _path)
  11. fs.writeFileSync(_path, ejsFile)
  12. finish[key].push('' + u)
  13. finishBussinessType.includes('' + u) || finishBussinessType.push('' + u)
  14. } catch (e) {
  15. console.log(e, 'e ')
  16. }

} } 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]%>',
    <%}%>
  }
}
  1. 重构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'))
})