UNPKG

3.56 kBJavaScriptView Raw
1var _ = require('lodash');
2var async = require('async');
3var chalk = require('chalk');
4var chokidar = require('chokidar');
5var freeport = require('freeport');
6var fs = require('fs-extra');
7var mutil = require('miaow-util');
8var path = require('path');
9
10var compile = require('./compile');
11var config = require('./config');
12var LiveReload = require('./livereload');
13var Module = require('./module');
14
15function watch(options) {
16 options = config(options);
17
18 compile(options, function (err, cache) {
19 if (err) {
20 mutil.log(chalk.red.bold('编译失败, 不能启动文件监听模式'));
21
22 err.showStack = false;
23 console.error(err.toString());
24
25 process.exit(1);
26 return;
27 }
28
29 // 自动刷新
30 var liveload = new LiveReload(options.liveReloadPort);
31
32 // 编译队列
33 var compileQueue = async.queue(function (srcPath, cb) {
34 var modifyTime = new Date().getTime();
35 mutil.log('开始编译 ' + chalk.green.underline.bold(srcPath));
36 var module = new Module(srcPath, options, cache);
37 module.compile(function (err) {
38 if (err) {
39 err.showStack = false;
40 console.error(err.toString());
41 return cb();
42 }
43
44 liveload.change(srcPath, modifyTime);
45 mutil.log('成功编译 ' + chalk.green.underline.bold(srcPath));
46 cb();
47 });
48 }, 1);
49
50 // 获取依赖这个文件的文件列表
51 function getDependedList(srcPath) {
52 var modules = cache.modules;
53 var dependedList = [];
54 var searchList = [srcPath];
55
56 function isDepend(module, item) {
57 return _.includes(module.dependencies, item);
58 }
59
60 while (searchList.length) {
61 var _searchList = searchList;
62 searchList = [];
63
64 _.each(modules, function (module, srcPath) {
65 if (_.any(_searchList, isDepend.bind(this, module))) {
66 dependedList.push(srcPath);
67 searchList.push(srcPath);
68 }
69 });
70 }
71
72 dependedList.push(srcPath);
73
74 return dependedList;
75 }
76
77 // 编译修改的文件
78 function compileChangedFile(filePath) {
79 var srcPath = path.relative(options.cwd, filePath);
80 var fileList = getDependedList(srcPath);
81
82 _.each(fileList, function (srcPath) {
83 var module = cache.get(srcPath);
84
85 if (module) {
86 module.remove();
87 }
88 });
89
90 mutil.log('修改文件 ' + chalk.underline.bold(srcPath));
91 compileQueue.push(fileList);
92 }
93
94 function compileAddedFile(filePath) {
95 var srcPath = path.relative(options.cwd, filePath);
96
97 mutil.log('新增文件 ' + chalk.underline.bold(srcPath));
98 compileQueue.push(srcPath);
99 }
100
101 function compileDeletedFile(filePath) {
102 var srcPath = path.relative(options.cwd, filePath);
103
104 var module = cache.get(srcPath);
105
106 if (module) {
107 module.remove();
108 }
109
110 mutil.log('删除文件 ' + chalk.red.underline.bold(srcPath));
111 }
112
113 var watcher = chokidar.watch('**/*', {cwd: options.cwd, ignored: options.exclude || []})
114 .on('ready', function () {
115 mutil.log('开始监听');
116
117 watcher.on('add', compileAddedFile);
118 watcher.on('change', compileChangedFile);
119 watcher.on('unlink', compileDeletedFile);
120 });
121 });
122}
123
124module.exports = function (options) {
125 freeport(function (err, port) {
126 if (err) {
127 mutil.log(chalk.red.bold('获取端口失败, 不能启动自动刷新功能'));
128 } else {
129 options.liveReloadPort = port;
130 }
131
132 watch(options);
133 });
134};