-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.ts
170 lines (148 loc) · 5.35 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import path from 'path'
import fs from 'fs-extra'
import { buildLangPrefix, findMax$tNumber, findMax$tNumberByLangFile, JsonMap, setObjectAttr } from './common'
import { generatorHTML } from './html-generator'
import { generateJavascript } from './javascript-generator'
import _ from 'lodash'
const targetFileList: string[] = []
// 主方法
function main(targetDir: string, langPath: string) {
// 语言包
let topLanguageJson = JSON.parse(fs.readFileSync(langPath, 'utf-8'))
const commonLang = topLanguageJson
// Vue 专属解析器
function parseVueFile(code: string) {
const tplStart = code.indexOf('<template>')
const tplEnd = code.lastIndexOf('</template>') + 11
const template = code.slice(tplStart, tplEnd)
const jsStart = code.indexOf('<script>')
const jsEnd = code.lastIndexOf('</script>') + 9
const script = code.slice(jsStart, jsEnd)
code = code.replace(template, '')
code = code.replace(script, '')
return {
template: tplStart === -1 ? '' : template.slice(10, -11),
script: script.slice(8, -9),
other: code,
}
}
// 根据目录和文件来生成不同的文件列表
let files: string[] = []
if (fs.statSync(targetDir).isDirectory()) {
files = fs.readdirSync(targetDir)
} else {
const filename = targetDir.replace(path.dirname(targetDir), '')
targetDir = path.dirname(targetDir)
files = [filename]
}
for (const filename of files) {
if (targetFileList.length > 0) {
let f = false
targetFileList.forEach((v) => {
if (v === filename) f = true
})
if (!f) {
console.log('过滤文件:', filename)
continue
}
}
const filePath = path.join(targetDir, filename)
if (fs.statSync(path.join(filePath)).isDirectory()) continue
const fileData = fs.readFileSync(filePath, 'utf-8')
// 语言文件前缀生成
const langPrefix = buildLangPrefix(filePath)
const startIndex = findMax$tNumberByLangFile(topLanguageJson, langPrefix) + 1
let outputCode = ''
let tmpLangMap: JsonMap = {}
// Vue File
if (path.extname(filename) === '.vue') {
const { script, template, other: otherCode } = parseVueFile(fileData)
console.log('\n----------\n正在处理 Vue 文件:', filename, '| 开始序号:', startIndex)
const { code, lang } = startGenerator(langPrefix, template, script, otherCode, 'vue', startIndex, commonLang)
tmpLangMap = _.merge(tmpLangMap, lang)
outputCode = code
}
// JS File
if (path.extname(filename) === '.js') {
console.log('\n----------\n正在处理 Javascript 文件:', filename, '| 开始序号:', startIndex)
const { code, lang } = startGenerator(langPrefix, '', fileData, '', 'js', startIndex, commonLang)
tmpLangMap = _.merge(tmpLangMap, lang)
outputCode = code
}
// 将语言文件的最终产物合并到现有语言文件
topLanguageJson = _.merge(topLanguageJson, tmpLangMap)
// 覆盖原文件
if (outputCode) fs.writeFileSync(filePath, outputCode, 'utf-8')
fs.writeFileSync(languageFilePath, JSON.stringify(topLanguageJson, null, 2), 'utf-8')
}
}
// 针对单个文件的生成器
function startGenerator(filePrefix: string, html: string, javascript: string, otherCode: string, fileType = 'vue', startIndex = 1, commonLang: JsonMap) {
console.log('语言文件前缀:', filePrefix)
const { index, output: outHtml, lang: htmlLang } = generatorHTML(html, filePrefix, startIndex, commonLang)
const { output: outJs, lang: jsLang } = generateJavascript(javascript, filePrefix, index, commonLang)
// 合并HTML,JS代码片段的语言文件
const jsonLangMap: JsonMap = {}
let mergeLangMap: JsonMap = {}
mergeLangMap = _.merge(htmlLang, jsLang)
// 按照语言文件前缀生成最终产物
for (const key in mergeLangMap) {
jsonLangMap[key] = mergeLangMap[key]
}
// Vue文件代码模板
if (fileType === 'vue') {
const newVueFileCode = `<template>
${outHtml}
</template>
<script>
${outJs}
</script>
${otherCode}
`
return {
commonLang,
code: newVueFileCode,
lang: jsonLangMap,
}
} else {
// 其他类型文件代码模板
return {
commonLang,
code: outJs,
lang: jsonLangMap,
}
}
}
let targetDir = ''
let languageFilePath = ''
for (const i in process.argv) {
const keyword = process.argv
if (keyword[i] == 'exec') {
languageFilePath = keyword[Number(i) + 1]
targetDir = keyword[Number(i) + 2]
}
}
if (!path.isAbsolute(languageFilePath.trim())) {
languageFilePath = path.normalize(path.join(process.cwd(), languageFilePath.trim()))
}
if (!path.isAbsolute(targetDir.trim())) {
targetDir = path.normalize(path.join(process.cwd(), targetDir.trim()))
}
if (targetDir && languageFilePath && path.isAbsolute(targetDir.trim()) && path.isAbsolute(languageFilePath.trim())) {
if (!fs.existsSync(languageFilePath)) {
fs.writeFileSync(languageFilePath, '{}', 'utf-8')
}
if (!fs.existsSync(targetDir)) {
console.log('参数指定的文件不存在')
process.exit(-1)
}
console.log('语言文件:', `"${languageFilePath.trim()}"`)
console.log('目标目录/文件:', `"${targetDir.trim()}"`)
// console.log('请检查是否参数正确,脚本将在3秒后执行...')
main(targetDir, languageFilePath)
process.exit(0)
} else {
console.log('参数错误!!!')
process.exit(-1)
}
export { languageFilePath }