watch-cli.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. @license
  3. Rollup.js v2.56.3
  4. Mon, 23 Aug 2021 05:06:39 GMT - commit c41d17ceedfa6c1d7430da70c6c80d86a91e9434
  5. https://github.com/rollup/rollup
  6. Released under the MIT License.
  7. */
  8. 'use strict';
  9. var fs = require('fs');
  10. var index = require('./index.js');
  11. var loadConfigFile_js = require('./loadConfigFile.js');
  12. var cli = require('../bin/rollup');
  13. var require$$0 = require('assert');
  14. var require$$0$1 = require('events');
  15. var rollup = require('./rollup.js');
  16. require('path');
  17. require('util');
  18. require('stream');
  19. require('os');
  20. require('url');
  21. require('./mergeOptions.js');
  22. require('module');
  23. require('crypto');
  24. function timeZone(date = new Date()) {
  25. const offset = date.getTimezoneOffset();
  26. const absOffset = Math.abs(offset);
  27. const hours = Math.floor(absOffset / 60);
  28. const minutes = absOffset % 60;
  29. const minutesOut = minutes > 0 ? ':' + ('0' + minutes).slice(-2) : '';
  30. return (offset < 0 ? '+' : '-') + hours + minutesOut;
  31. }
  32. function dateTime(options = {}) {
  33. let {
  34. date = new Date(),
  35. local = true,
  36. showTimeZone = false,
  37. showMilliseconds = false
  38. } = options;
  39. if (local) {
  40. // Offset the date so it will return the correct value when getting the ISO string.
  41. date = new Date(date.getTime() - (date.getTimezoneOffset() * 60000));
  42. }
  43. let end = '';
  44. if (showTimeZone) {
  45. end = ' UTC' + (local ? timeZone(date) : '');
  46. }
  47. if (showMilliseconds && date.getUTCMilliseconds() > 0) {
  48. end = ` ${date.getUTCMilliseconds()}ms${end}`;
  49. }
  50. return date
  51. .toISOString()
  52. .replace(/T/, ' ')
  53. .replace(/\..+/, end);
  54. }
  55. var signalExit = {exports: {}};
  56. var signals$1 = {exports: {}};
  57. (function (module) {
  58. // This is not the set of all possible signals.
  59. //
  60. // It IS, however, the set of all signals that trigger
  61. // an exit on either Linux or BSD systems. Linux is a
  62. // superset of the signal names supported on BSD, and
  63. // the unknown signals just fail to register, so we can
  64. // catch that easily enough.
  65. //
  66. // Don't bother with SIGKILL. It's uncatchable, which
  67. // means that we can't fire any callbacks anyway.
  68. //
  69. // If a user does happen to register a handler on a non-
  70. // fatal signal like SIGWINCH or something, and then
  71. // exit, it'll end up firing `process.emit('exit')`, so
  72. // the handler will be fired anyway.
  73. //
  74. // SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
  75. // artificially, inherently leave the process in a
  76. // state from which it is not safe to try and enter JS
  77. // listeners.
  78. module.exports = [
  79. 'SIGABRT',
  80. 'SIGALRM',
  81. 'SIGHUP',
  82. 'SIGINT',
  83. 'SIGTERM'
  84. ];
  85. if (process.platform !== 'win32') {
  86. module.exports.push(
  87. 'SIGVTALRM',
  88. 'SIGXCPU',
  89. 'SIGXFSZ',
  90. 'SIGUSR2',
  91. 'SIGTRAP',
  92. 'SIGSYS',
  93. 'SIGQUIT',
  94. 'SIGIOT'
  95. // should detect profiler and enable/disable accordingly.
  96. // see #21
  97. // 'SIGPROF'
  98. );
  99. }
  100. if (process.platform === 'linux') {
  101. module.exports.push(
  102. 'SIGIO',
  103. 'SIGPOLL',
  104. 'SIGPWR',
  105. 'SIGSTKFLT',
  106. 'SIGUNUSED'
  107. );
  108. }
  109. }(signals$1));
  110. // Note: since nyc uses this module to output coverage, any lines
  111. // that are in the direct sync flow of nyc's outputCoverage are
  112. // ignored, since we can never get coverage for them.
  113. var assert = require$$0;
  114. var signals = signals$1.exports;
  115. var isWin = /^win/i.test(process.platform);
  116. var EE = require$$0$1;
  117. /* istanbul ignore if */
  118. if (typeof EE !== 'function') {
  119. EE = EE.EventEmitter;
  120. }
  121. var emitter;
  122. if (process.__signal_exit_emitter__) {
  123. emitter = process.__signal_exit_emitter__;
  124. } else {
  125. emitter = process.__signal_exit_emitter__ = new EE();
  126. emitter.count = 0;
  127. emitter.emitted = {};
  128. }
  129. // Because this emitter is a global, we have to check to see if a
  130. // previous version of this library failed to enable infinite listeners.
  131. // I know what you're about to say. But literally everything about
  132. // signal-exit is a compromise with evil. Get used to it.
  133. if (!emitter.infinite) {
  134. emitter.setMaxListeners(Infinity);
  135. emitter.infinite = true;
  136. }
  137. signalExit.exports = function (cb, opts) {
  138. assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler');
  139. if (loaded === false) {
  140. load();
  141. }
  142. var ev = 'exit';
  143. if (opts && opts.alwaysLast) {
  144. ev = 'afterexit';
  145. }
  146. var remove = function () {
  147. emitter.removeListener(ev, cb);
  148. if (emitter.listeners('exit').length === 0 &&
  149. emitter.listeners('afterexit').length === 0) {
  150. unload();
  151. }
  152. };
  153. emitter.on(ev, cb);
  154. return remove
  155. };
  156. signalExit.exports.unload = unload;
  157. function unload () {
  158. if (!loaded) {
  159. return
  160. }
  161. loaded = false;
  162. signals.forEach(function (sig) {
  163. try {
  164. process.removeListener(sig, sigListeners[sig]);
  165. } catch (er) {}
  166. });
  167. process.emit = originalProcessEmit;
  168. process.reallyExit = originalProcessReallyExit;
  169. emitter.count -= 1;
  170. }
  171. function emit (event, code, signal) {
  172. if (emitter.emitted[event]) {
  173. return
  174. }
  175. emitter.emitted[event] = true;
  176. emitter.emit(event, code, signal);
  177. }
  178. // { <signal>: <listener fn>, ... }
  179. var sigListeners = {};
  180. signals.forEach(function (sig) {
  181. sigListeners[sig] = function listener () {
  182. // If there are no other listeners, an exit is coming!
  183. // Simplest way: remove us and then re-send the signal.
  184. // We know that this will kill the process, so we can
  185. // safely emit now.
  186. var listeners = process.listeners(sig);
  187. if (listeners.length === emitter.count) {
  188. unload();
  189. emit('exit', null, sig);
  190. /* istanbul ignore next */
  191. emit('afterexit', null, sig);
  192. /* istanbul ignore next */
  193. if (isWin && sig === 'SIGHUP') {
  194. // "SIGHUP" throws an `ENOSYS` error on Windows,
  195. // so use a supported signal instead
  196. sig = 'SIGINT';
  197. }
  198. process.kill(process.pid, sig);
  199. }
  200. };
  201. });
  202. signalExit.exports.signals = function () {
  203. return signals
  204. };
  205. signalExit.exports.load = load;
  206. var loaded = false;
  207. function load () {
  208. if (loaded) {
  209. return
  210. }
  211. loaded = true;
  212. // This is the number of onSignalExit's that are in play.
  213. // It's important so that we can count the correct number of
  214. // listeners on signals, and don't wait for the other one to
  215. // handle it instead of us.
  216. emitter.count += 1;
  217. signals = signals.filter(function (sig) {
  218. try {
  219. process.on(sig, sigListeners[sig]);
  220. return true
  221. } catch (er) {
  222. return false
  223. }
  224. });
  225. process.emit = processEmit;
  226. process.reallyExit = processReallyExit;
  227. }
  228. var originalProcessReallyExit = process.reallyExit;
  229. function processReallyExit (code) {
  230. process.exitCode = code || 0;
  231. emit('exit', process.exitCode, null);
  232. /* istanbul ignore next */
  233. emit('afterexit', process.exitCode, null);
  234. /* istanbul ignore next */
  235. originalProcessReallyExit.call(process, process.exitCode);
  236. }
  237. var originalProcessEmit = process.emit;
  238. function processEmit (ev, arg) {
  239. if (ev === 'exit') {
  240. if (arg !== undefined) {
  241. process.exitCode = arg;
  242. }
  243. var ret = originalProcessEmit.apply(this, arguments);
  244. emit('exit', process.exitCode, null);
  245. /* istanbul ignore next */
  246. emit('afterexit', process.exitCode, null);
  247. return ret
  248. } else {
  249. return originalProcessEmit.apply(this, arguments)
  250. }
  251. }
  252. var onExit = signalExit.exports;
  253. const CLEAR_SCREEN = '\u001Bc';
  254. function getResetScreen(configs, allowClearScreen) {
  255. let clearScreen = allowClearScreen;
  256. for (const config of configs) {
  257. if (config.watch && config.watch.clearScreen === false) {
  258. clearScreen = false;
  259. }
  260. }
  261. if (clearScreen) {
  262. return (heading) => loadConfigFile_js.stderr(CLEAR_SCREEN + heading);
  263. }
  264. let firstRun = true;
  265. return (heading) => {
  266. if (firstRun) {
  267. loadConfigFile_js.stderr(heading);
  268. firstRun = false;
  269. }
  270. };
  271. }
  272. async function watch(command) {
  273. process.env.ROLLUP_WATCH = 'true';
  274. const isTTY = process.stderr.isTTY;
  275. const silent = command.silent;
  276. let configs;
  277. let warnings;
  278. let watcher;
  279. let configWatcher;
  280. const configFile = command.config ? cli.getConfigPath(command.config) : null;
  281. onExit(close);
  282. process.on('uncaughtException', close);
  283. if (!process.stdin.isTTY) {
  284. process.stdin.on('end', close);
  285. process.stdin.resume();
  286. }
  287. async function loadConfigFromFileAndTrack(configFile) {
  288. let reloadingConfig = false;
  289. let aborted = false;
  290. let configFileData = null;
  291. configWatcher = index.chokidar.watch(configFile).on('change', () => reloadConfigFile());
  292. await reloadConfigFile();
  293. async function reloadConfigFile() {
  294. try {
  295. const newConfigFileData = fs.readFileSync(configFile, 'utf-8');
  296. if (newConfigFileData === configFileData) {
  297. return;
  298. }
  299. if (reloadingConfig) {
  300. aborted = true;
  301. return;
  302. }
  303. if (configFileData) {
  304. loadConfigFile_js.stderr(`\nReloading updated config...`);
  305. }
  306. configFileData = newConfigFileData;
  307. reloadingConfig = true;
  308. ({ options: configs, warnings } = await loadConfigFile_js.loadAndParseConfigFile(configFile, command));
  309. reloadingConfig = false;
  310. if (aborted) {
  311. aborted = false;
  312. reloadConfigFile();
  313. }
  314. else {
  315. if (watcher) {
  316. watcher.close();
  317. }
  318. start(configs);
  319. }
  320. }
  321. catch (err) {
  322. configs = [];
  323. reloadingConfig = false;
  324. loadConfigFile_js.handleError(err, true);
  325. }
  326. }
  327. }
  328. if (configFile) {
  329. await loadConfigFromFileAndTrack(configFile);
  330. }
  331. else {
  332. ({ options: configs, warnings } = await cli.loadConfigFromCommand(command));
  333. start(configs);
  334. }
  335. const resetScreen = getResetScreen(configs, isTTY);
  336. function start(configs) {
  337. try {
  338. watcher = rollup.watch(configs);
  339. }
  340. catch (err) {
  341. return loadConfigFile_js.handleError(err);
  342. }
  343. watcher.on('event', event => {
  344. switch (event.code) {
  345. case 'ERROR':
  346. warnings.flush();
  347. loadConfigFile_js.handleError(event.error, true);
  348. break;
  349. case 'START':
  350. if (!silent) {
  351. resetScreen(loadConfigFile_js.underline(`rollup v${rollup.version}`));
  352. }
  353. break;
  354. case 'BUNDLE_START':
  355. if (!silent) {
  356. let input = event.input;
  357. if (typeof input !== 'string') {
  358. input = Array.isArray(input)
  359. ? input.join(', ')
  360. : Object.values(input).join(', ');
  361. }
  362. loadConfigFile_js.stderr(loadConfigFile_js.cyan(`bundles ${loadConfigFile_js.bold(input)} → ${loadConfigFile_js.bold(event.output.map(rollup.relativeId).join(', '))}...`));
  363. }
  364. break;
  365. case 'BUNDLE_END':
  366. warnings.flush();
  367. if (!silent)
  368. loadConfigFile_js.stderr(loadConfigFile_js.green(`created ${loadConfigFile_js.bold(event.output.map(rollup.relativeId).join(', '))} in ${loadConfigFile_js.bold(cli.ms(event.duration))}`));
  369. if (event.result && event.result.getTimings) {
  370. cli.printTimings(event.result.getTimings());
  371. }
  372. break;
  373. case 'END':
  374. if (!silent && isTTY) {
  375. loadConfigFile_js.stderr(`\n[${dateTime()}] waiting for changes...`);
  376. }
  377. }
  378. if ('result' in event && event.result) {
  379. event.result.close().catch(error => loadConfigFile_js.handleError(error, true));
  380. }
  381. });
  382. }
  383. function close(code) {
  384. process.removeListener('uncaughtException', close);
  385. // removing a non-existent listener is a no-op
  386. process.stdin.removeListener('end', close);
  387. if (watcher)
  388. watcher.close();
  389. if (configWatcher)
  390. configWatcher.close();
  391. if (code) {
  392. process.exit(code);
  393. }
  394. }
  395. }
  396. exports.watch = watch;
  397. //# sourceMappingURL=watch-cli.js.map