UNPKG

lint-fix-nodemon

Version:

watch files and run eslint+fix+nodemon without double restarts

114 lines (93 loc) 3.23 kB
#!/usr/bin/env node // This script just watches files and chains a run of eslint (with fixes enabled) and then restarting nodemon // However we fix 2 problems that are common with using these packages, especially together // 1 - when eslint fixes files, we dont trigger an extra nodemon restart (we skip the first one by hooking into eslint and detecting fixes) // 2 - if linting fails or starting the server fails, we still just watch the files and start/restart properly, rather than dying const fs = require('fs'); const _ = require('lodash'); const nodemon = require('nodemon'); const chokidar = require('chokidar'); const { CLIEngine } = require('eslint'); const colors = require('colors'); const [node, script, ...args] = process.argv; // eslint-disable-line no-unused-vars // try to load config from package.json - looking for `nodemonConfig` key const packageJson = JSON.parse(fs.readFileSync(__dirname + '/../../package.json')); const { nodemonConfig } = packageJson; // you can pass in the script to run or it will default to the "main" in package.json const mainScript = args[0] || packageJson.main; const eslintCLI = new CLIEngine({ fix: true, cache: true, ignorePath: '.gitignore', // if nodemon has extensions set, we'll copy those, otherwise default to just js (as eslint does already) extensions: (nodemonConfig.ext || 'js').split(','), }); const formatter = eslintCLI.getFormatter(); let appProcess; function runLinter() { // run eslint w/ fixes const report = eslintCLI.executeOnFiles(nodemonConfig.watch); CLIEngine.outputFixes(report); // output Lint results console.log(formatter(report.results)); // return info on whether any fixes were made return { fixes: _.some(report.results, 'output'), fatal: _.some(report.results, (file) => _.some(file.messages, { fatal: true })), }; } function startServer() { if (process.env.LINT_ONLY) return; if (appProcess) { console.log('>> Restarting server <<'.green); appProcess.restart(); } else { console.log('>> Starting server <<'.green); appProcess = nodemon({ script: mainScript, watch: false, inspect: true, }); } } function stopServer() { nodemon.emit('quit'); appProcess = null; } let ignoreNextChange = false; function lintAndRun() { if (ignoreNextChange) { ignoreNextChange = false; return; } const lintResults = runLinter(); if (lintResults.fatal) { console.log('>> Fatal error detected by lint <<'.red); stopServer(); console.log('>> FIX FATAL ERRORS TO START SERVER <<'.red); return; } if (lintResults.fixes) ignoreNextChange = true; startServer(); } // watch files for changes, run linter and restart server chokidar.watch(nodemonConfig.watch, { ignored: [ 'node_modules', // ignore node_modules /(^|[/\\])\../, // ignore anything starting with . ...nodemonConfig.ignore || [], ], }).on('change', (event, path) => { lintAndRun(); }); lintAndRun(); // // pass through exit to running app process function exit() { console.log('>>> Shutting down dev server <<<'.red); nodemon.emit('quit'); process.exit(); } // explicitly exit on signal process.on('SIGTERM', exit); process.on('SIGINT', exit);