From 9908c4f75c83061c2167fd786466df2aeba3c88f Mon Sep 17 00:00:00 2001 From: crayon Date: Mon, 26 Aug 2019 23:17:11 +0800 Subject: [PATCH] fix: rollup watch #148 --- packages/remax-cli/package.json | 1 + packages/remax-cli/src/build/index.ts | 56 ++-------- .../src/build/utils/checkChokidar.ts | 17 +++ packages/remax-cli/src/build/utils/output.ts | 14 +++ packages/remax-cli/src/build/watcher.ts | 104 ++++++++++++++++++ 5 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 packages/remax-cli/src/build/utils/checkChokidar.ts create mode 100644 packages/remax-cli/src/build/utils/output.ts create mode 100644 packages/remax-cli/src/build/watcher.ts diff --git a/packages/remax-cli/package.json b/packages/remax-cli/package.json index da0c170150..51f3af0d17 100644 --- a/packages/remax-cli/package.json +++ b/packages/remax-cli/package.json @@ -27,6 +27,7 @@ "@meck/rollup-plugin-postcss": "^2.0.3", "@remax/postcss-px2units": "^0.2.0", "acorn-walk": "^7.0.0", + "chokidar": "^2.1.8", "commander": "^2.19.0", "ejs": "^2.6.1", "lodash": "^4.17.11", diff --git a/packages/remax-cli/src/build/index.ts b/packages/remax-cli/src/build/index.ts index a96b141981..63e5b13954 100644 --- a/packages/remax-cli/src/build/index.ts +++ b/packages/remax-cli/src/build/index.ts @@ -2,21 +2,8 @@ import * as rollup from 'rollup'; import rollupConfig from './rollupConfig'; import getConfig from '../getConfig'; import { Context } from '../types'; - -const COLORS = { - red: '\x1b[31m', - green: '\x1b[32m', - blue: '\x1b[34m', -}; -const RESET = '\x1b[0m'; - -const output = ( - content: string | string[], - color: 'red' | 'green' | 'blue' -) => { - const message = Array.isArray(content) ? content : [content]; - console.log(`${COLORS[color]}%s${RESET}`, ...message); -}; +import runWatcher from './watcher'; +import { output } from './utils/output'; export default async (argv: any, context?: Context) => { const options = { @@ -32,38 +19,15 @@ export default async (argv: any, context?: Context) => { throw new Error(`Target ${argv.target} is not supported yet.`); } - const rollupOptions = rollupConfig(options, argv, targetConfig, context); - if (argv.watch) { - const watcher = rollup.watch([ - { - ...rollupOptions, - watch: { - include: ['src/**', 'app.js', '*.config.js'], - }, - }, - ]); - - console.log('\x1b[34m%s\x1b[0m', '๐Ÿš€ ๅฏๅŠจ watch'); + const rollupOptions: rollup.RollupOptions = rollupConfig( + options, + argv, + targetConfig, + context + ); - watcher.on('event', (event: any) => { - switch (event.code) { - case 'START': - output('๐Ÿšš ็ผ–่ฏ‘...', 'blue'); - break; - case 'END': - output('๐Ÿ’ก ๅฎŒๆˆ', 'green'); - break; - case 'ERROR': - case 'FATAL': - const { error } = event; - const name = - error.code === 'PLUGIN_ERROR' ? error.plugin : error.code; - output(`\n๐Ÿšจ [${name}]: ${error.message}`, 'red'); - throw error; - default: - break; - } - }); + if (argv.watch) { + runWatcher(rollupOptions, argv, context); } else { try { output('๐Ÿš€ ๅผ€ๅง‹ build...', 'blue'); diff --git a/packages/remax-cli/src/build/utils/checkChokidar.ts b/packages/remax-cli/src/build/utils/checkChokidar.ts new file mode 100644 index 0000000000..32d4a224f8 --- /dev/null +++ b/packages/remax-cli/src/build/utils/checkChokidar.ts @@ -0,0 +1,17 @@ +import path from 'path'; + +let isFirstCheckFailed = true; +export const checkChokidar = () => { + try { + require(path.resolve(process.cwd(), './node_modules/chokidar')); + return true; + } catch (e) { + if (isFirstCheckFailed) { + isFirstCheckFailed = false; + console.log( + '\n ๅฎ‰่ฃ… `chokidar` ่Žทๅพ—ๆ›ดๅฅฝ็š„ๅผ€ๅ‘ไฝ“้ชŒ๏ฝž๏ฝž ๐Ÿ˜Ž\n\n > npm install chokidar --save \n' + ); + } + return false; + } +}; diff --git a/packages/remax-cli/src/build/utils/output.ts b/packages/remax-cli/src/build/utils/output.ts new file mode 100644 index 0000000000..aa628b7df5 --- /dev/null +++ b/packages/remax-cli/src/build/utils/output.ts @@ -0,0 +1,14 @@ +const COLORS = { + red: '\x1b[31m', + green: '\x1b[32m', + blue: '\x1b[34m', +}; +const RESET = '\x1b[0m'; + +export const output = ( + content: string | string[], + color: 'red' | 'green' | 'blue' +) => { + const message = Array.isArray(content) ? content : [content]; + console.log(`${COLORS[color]}%s${RESET}`, ...message); +}; diff --git a/packages/remax-cli/src/build/watcher.ts b/packages/remax-cli/src/build/watcher.ts new file mode 100644 index 0000000000..2178e8ed57 --- /dev/null +++ b/packages/remax-cli/src/build/watcher.ts @@ -0,0 +1,104 @@ +import chokidar from 'chokidar'; +import { RollupOptions, watch, RollupWatcher } from 'rollup'; +import { output } from './utils/output'; +import { checkChokidar } from './utils/checkChokidar'; +import { CliOptions } from '../getConfig'; +import { Context } from '../types'; +import build from './index'; + +let isBundleRunning = false; +let isFirstRunWatcher = true; + +const rollupWatchFiles = ['src/**', 'app.js']; +// ้…็ฝฎ้‡ๆ–ฐbuild็š„่ทฏๅพ„ +const extraFiles = ['src/app.config.js']; +// chokidar config +const chokidarConfig = { + usePolling: true, +}; + +let extraFilesWatcher: RollupWatcher | null; +let watcher: RollupWatcher | null; + +export default function runWather( + rollupOptions: RollupOptions, + cli: CliOptions, + context?: Context +) { + if (isBundleRunning) { + return; + } + + isBundleRunning = true; + + watcher = watch([ + { + ...rollupOptions, + watch: { + chokidar: checkChokidar() && chokidarConfig, + include: rollupWatchFiles, + }, + }, + ]); + + const watchEventHandle = (event: any) => { + switch (event.code) { + case 'START': + output('๐Ÿšš ็ผ–่ฏ‘...', 'blue'); + break; + case 'END': + isBundleRunning = false; + output('๐Ÿ’ก ๅฎŒๆˆ', 'green'); + break; + case 'ERROR': + case 'FATAL': + isBundleRunning = false; + const { error } = event; + const name = error.code === 'PLUGIN_ERROR' ? error.plugin : error.code; + output(`\n๐Ÿšจ [${name}]: ${error.message}`, 'red'); + throw error; + default: + break; + } + }; + + watcher.on('event', watchEventHandle); + + if (isFirstRunWatcher) { + isFirstRunWatcher = false; + console.log('\x1b[34m%s\x1b[0m', '๐Ÿš€ ๅฏๅŠจ watch'); + } + + const close = (err?: Error) => { + if (watcher) { + watcher.close(); + watcher = null; + } + if (extraFilesWatcher) { + extraFilesWatcher.close(); + watcher = null; + } + + process.removeListener('uncaughtException', close); + + if (err) { + process.exit(1); + console.error(err); + } + }; + + process.on('uncaughtException', close); + // ็›‘ๅฌ้ขๅค–็š„ๆ–‡ไปถ + extraFilesWatcher = chokidar.watch(extraFiles); + + const reloadWatcher = () => { + if (isFirstRunWatcher || isBundleRunning) return; + close(); + build(cli, context); + }; + + extraFilesWatcher + .on('add', reloadWatcher) + .on('unlink', reloadWatcher) + .on('change', reloadWatcher); +}