UNPKG

2.28 kBJavaScriptView Raw
1const fs = require('fs')
2const path = require('path')
3const { EventEmitter } = require('events')
4
5const mkdirp = require('mkdirp')
6const minimatch = require('minimatch')
7const babel = require('@babel/core')
8const chokidar = require('chokidar')
9
10const DEFAULT_OPTIONS = {
11 persistent: true,
12 delete: true,
13 babel: {},
14 glob: '**/*.js'
15}
16
17class BabelCompiler extends EventEmitter {
18 constructor(src, dest, options) {
19 super()
20
21 const optionsWithDefault = Object.assign({}, DEFAULT_OPTIONS, options)
22
23 this.src = src
24 this.dest = dest
25 this.options = optionsWithDefault
26 this.ready = false
27
28 mkdirp.sync(dest)
29
30 const chokidarOptions = {
31 cwd: src,
32 persistent: optionsWithDefault.persistent
33 }
34
35 this.watcher = chokidar
36 .watch('**/*.*', chokidarOptions)
37 .on('all', (event, filepath) => this.onWatchEvent(event, filepath))
38 .on('error', e => this.onError(e))
39 .on('ready', () => this.onReady())
40 }
41
42 onWatchEvent(event, filepath = '.') {
43 const srcPath = path.join(this.src, filepath)
44 const destPath = path.join(this.dest, filepath)
45
46 if (event === 'add' || event === 'change') {
47 mkdirp.sync(path.dirname(destPath))
48 if (minimatch(filepath, this.options.glob)) {
49 this.compileJsFile(filepath, srcPath, destPath)
50 } else {
51 this.copyFile(filepath, srcPath, destPath)
52 }
53 }
54
55 if (event === 'unlink') {
56 if (this.options.delete) return
57 fs.removeSync(destPath)
58 this.emit('delete', filepath)
59 }
60
61 if (event === 'unlinkDir') {
62 if (!this.options.delete) return
63 fs.removeSync(destPath)
64 }
65 }
66
67 onReady() {
68 this.emit('ready')
69 }
70
71 onError(e) {
72 this.emit('error', e)
73 }
74
75 compileJsFile(filepath, srcPath, destPath) {
76 const babelOptions = this.options.sourceMaps
77 ? {
78 ...this.options.babel,
79 sourceMaps: 'inline',
80 sourceFileName: srcPath
81 }
82 : this.options.babel
83
84 let result
85 try {
86 result = babel.transformFileSync(srcPath, babelOptions)
87 } catch (error) {
88 this.emit('error', filepath, error)
89 return
90 }
91
92 fs.writeFileSync(destPath, result.code)
93 this.emit('success', filepath)
94 }
95
96 copyFile(filepath, srcPath, destPath) {
97 fs.copyFileSync(srcPath, destPath)
98 this.emit('copy', filepath)
99 }
100
101 close() {
102 this.watcher.close()
103 this.removeAllListeners()
104 }
105}
106
107module.exports = BabelCompiler