-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
107 lines (90 loc) · 2.89 KB
/
app.js
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
const fs = require('fs-extra')
const lab = require('linco.lab')
const path = require('path')
const glob = require('glob')
const Gaze = require('gaze').Gaze
const flow = require('flow-bin')
const prettier = require('prettier')
const { execFile, exec, execSync } = require('child_process')
const flowRemoveTypes = require('flow-remove-types')
const flowParser = require('flow-parser')
class Compiler {
constructor(options) {
this.src = options.src
this.dist = options.dist
this.options = options
}
watch() {
const gaze = new Gaze('**/*.*', {cwd: this.src, ignore: this.options.ignore})
// 启动监听的时候
// 1.flow check
// 2.执行一次全量编译,以保证程序可以顺利运行
gaze.on('ready', watcher => {
this.check()
this.compile(this.getFiles())
})
// 后续所有更新事件
// 1.全量 flow check
// 2.执行单文件编译
gaze.on('all', (event, filepath) => {
if (event === 'deleted') {
return fs.unlink(this.getDistFile(filepath))
}
!this.isFlow(filepath) || this.check()
this.compile(filepath)
})
}
run() {
this.watch()
}
/// 清理js文件的flowType标记
compile(files) {
(Array.isArray(files) ? files : [files]).map(filepath => {
this.isFlow(filepath) ? this.flow(filepath) : this.clone(filepath)
})
}
isFlow(filepath) {
return path.extname(filepath) === '.js'
}
/// 这一步清理flow type标记
flow(filepath) {
let dist = this.getDistFile(filepath)
let input = fs.readFileSync(filepath).toString('utf8')
let output = flowRemoveTypes(this.addFlowSign(input)).toString()
lab.mkdir(path.dirname(dist))
// 输出美化后的代码
// 1.去除多余空白
// 2.格式化代码
fs.writeFileSync(dist, prettier.format(this.removeFlowSign(output), {
tabWidth: 4, // 4个空格
useTabs: false, // 使用空格而不使用tab
semi: false, // 不需要分号
parser: "babylon"
}))
}
/// 复制不需要执行flow type清理的文件到dist目录
clone(filepath) {
if (lab.isFile(filepath)) {
let dist = this.getDistFile(filepath)
fs.copySync(filepath, dist)
}
}
getFiles() {
return glob.sync(path.join(this.src, '**/*'), {nodir: true})
}
getDistFile(filepath) {
return filepath.replace(this.src, this.dist)
}
addFlowSign(input) {
return '//@flow\n' + input
}
removeFlowSign(output) {
return output.replace(/\/\/\s+\n/, '')
}
check() {
execFile(flow, ['check', '--color=always'], (err, stdout) => {
console.log(stdout)
})
}
}
module.exports = Compiler