UNPKG

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