-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwatcher.js
More file actions
84 lines (77 loc) · 2.96 KB
/
watcher.js
File metadata and controls
84 lines (77 loc) · 2.96 KB
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
const chokidar = require('chokidar');
const path = require('path');
const fs = require('fs');
const rimraf = require('rimraf');
const { AnyFileMerge, Html, Js, Css } = require('any-file-merge');
const { resolvePath } = require('corresponding-path');
const { createHooks } = require('./hooks');
const replaceSlashes = pathString => `./${pathString.split(/[\\\/]/).join('/')}`;
const pathMatches = list => filepath => list.some(ext => ext === path.extname(filepath));
const pathContains = pattern => path => path.indexOf(pattern) !== -1
const relativePaths = (files) => {
return Object.keys(files)
.map(filepath => files[filepath]
.filter(path.extname)
.map(file => replaceSlashes(`${filepath}/${file}`))
)
.reduce((result, paths) => result.concat(paths), [])
};
const defaultProcessors = [
new Html(),
new Js(),
new Css()
];
const mapRequiredProcessors = processors => processors
.filter(type => type.isRequired())
.map(type => `.${type.extension()}`);
exports.watcher = (
{
watch,
patterns,
output,
processors = defaultProcessors,
hooks,
fileName,
quiet
}
) => {
const hook = createHooks(hooks, quiet);
const requiredExtensions = mapRequiredProcessors(processors);
const sc = new AnyFileMerge(fs, { output, fileName, processors });
const compile = relativePath => {
try {
sc.combine(relativePath);
hook.compile(relativePath);
} catch (error) {
hook.error(`File ${relativePath} could not be saved due to error: ${error.message}`);
}
};
const onDeleted = (relativePath, relativeWatched) => {
const path = resolvePath(relativePath, output);
const ext = fileName.substr(0, fileName.lastIndexOf('.')) || fileName;
if (path.input.ext === '') {
rimraf.sync(path.output.dir.join('/'));
} else {
rimraf.sync(path.output.full.replace(/\.[^.]*$/, ext));
// Recompile if part of the module was removed
relativeWatched.filter(pathContains(`${path.input.modulePath.join('/')}`)).forEach(compile);
}
};
const on = (watcher, eventType, callback) => watcher.on(eventType, (relativePath) => {
const inputPath = replaceSlashes(relativePath);
const watched = relativePaths(watcher.getWatched()).filter(pathMatches(requiredExtensions));
hook[eventType](inputPath, watched);
callback(inputPath, watched);
});
const watcher = chokidar.watch(patterns, { persistent: watch, cwd: process.cwd() });
watcher.on('error', hook.error);
on(watcher, 'unlink', onDeleted);
on(watcher, 'unlinkDir', onDeleted);
on(watcher, 'change', compile);
watcher.on('ready', () => {
const watched = relativePaths(watcher.getWatched()).filter(pathMatches(requiredExtensions));
hook.ready(watched);
watched.forEach(compile);
on(watcher, 'add', compile);
});
}