Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ You can pass the following options via CLI arguments. You can also use `--config
| Set the inspector port (default: 9320) | `-I` | `--debug-port` | `FASTIFY_DEBUG_PORT` |
| Set the inspector host to listen on (default: loopback address or `0.0.0.0` inside Docker or Kubernetes) | | `--debug-host` | `FASTIFY_DEBUG_HOST` |
| Prints pretty logs | `-P` | `--pretty-logs` | `FASTIFY_PRETTY_LOGS` |
| Watch process.cwd() directory for changes, recursively; when that happens, the process will auto reload | `-w` | `--watch` | `FASTIFY_WATCH` |
| Watch for changes and auto reload. Optional dir(s) (e.g. `--watch api`) limit watch to those; default process.cwd(). | `-w` | `--watch` | `FASTIFY_WATCH` |
| Ignore changes to the specified files or directories when watch is enabled. (e.g. `--ignore-watch='node_modules .git logs/error.log'` ) | | `--ignore-watch` | `FASTIFY_IGNORE_WATCH` |
| Prints events triggered by watch listener (useful to debug unexpected reload when using `--watch` ) | `-V` | `--verbose-watch` | `FASTIFY_VERBOSE_WATCH` |
| Use custom options | `-o` | `--options` | `FASTIFY_OPTIONS` |
Expand Down
22 changes: 19 additions & 3 deletions args.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ module.exports = function parseArgs (args) {
'populate--': true
},
number: ['port', 'inspect-port', 'body-limit', 'plugin-timeout', 'close-grace-delay', 'trust-proxy-hop'],
string: ['log-level', 'address', 'socket', 'prefix', 'ignore-watch', 'logging-module', 'debug-host', 'lang', 'require', 'import', 'config', 'method', 'trust-proxy-ips'],
boolean: ['pretty-logs', 'options', 'watch', 'verbose-watch', 'debug', 'standardlint', 'common-prefix', 'include-hooks', 'trust-proxy-enabled'],
string: ['log-level', 'address', 'socket', 'prefix', 'ignore-watch', 'logging-module', 'debug-host', 'lang', 'require', 'import', 'config', 'method', 'trust-proxy-ips', 'watch'],
boolean: ['pretty-logs', 'options', 'verbose-watch', 'debug', 'standardlint', 'common-prefix', 'include-hooks', 'trust-proxy-enabled'],
envPrefix: 'FASTIFY_',
alias: {
port: ['p'],
Expand Down Expand Up @@ -73,6 +73,21 @@ module.exports = function parseArgs (args) {
: parsedArgs.trustProxyEnabled === true || parsedArgs.trustProxyEnabled === 'true'
const trustProxy = trustProxyEnabled || parsedArgs.trustProxyIps || parsedArgs.trustProxyHop

const watchRequested = (parsedArgs.watch !== undefined && parsedArgs.watch !== false &&
(parsedArgs.watch === true || parsedArgs.watch === 'true' || parsedArgs.watch === '')) ||
args.includes('-w') || args.includes('--watch')
let watch = false
let watchPaths
if (watchRequested) {
watch = true
const watchVal = parsedArgs.watch
if (typeof watchVal === 'string' && watchVal !== '' && watchVal !== 'true') {
watchPaths = watchVal.split(/\s+/).map((s) => s.trim()).filter(Boolean)
} else {
watchPaths = []
}
}

return {
_: parsedArgs._,
'--': additionalArgs,
Expand All @@ -83,7 +98,8 @@ module.exports = function parseArgs (args) {
pluginOptions,
prettyLogs: parsedArgs.prettyLogs,
options: parsedArgs.options,
watch: parsedArgs.watch,
watch,
watchPaths,
debug: parsedArgs.debug,
debugPort: parsedArgs.debugPort,
debugHost: parsedArgs.debugHost,
Expand Down
8 changes: 6 additions & 2 deletions help/start.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ OPTS
[env: FASTIFY_OPTIONS]
Use custom options

-w, --watch
-w, --watch [dirs...]
[env: FASTIFY_WATCH]
Watch process.cwd() directory for changes, recursively; when that happens, the process will auto reload.
Watch for file changes and auto reload. With no value, watches process.cwd(); pass dir(s) (e.g. --watch api) to watch only those.

-x, --prefix
[env: FASTIFY_PREFIX]
Expand Down Expand Up @@ -74,3 +74,7 @@ Examples:
start plugin.js passing custom options to it

fastify start plugin.js -- --custom-plugin-option-1 --custom-plugin-option-2

watch only the api directory

fastify start --watch api api/server.js
7 changes: 5 additions & 2 deletions lib/watch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const chokidar = require('chokidar')
const { loadEnvQuitely } = require('../../env-loader.js')
const forkPath = path.join(__dirname, './fork.js')

const watch = function (args, ignoreWatch, verboseWatch) {
const watch = function (args, ignoreWatch, verboseWatch, watchPaths = null) {
const emitter = new EventEmitter()
let allStop = false
let childs = []
Expand Down Expand Up @@ -80,7 +80,10 @@ const watch = function (args, ignoreWatch, verboseWatch) {
const ignoredArr = ignoreWatch.split(' ').map((item) => item.trim()).filter((item) => item.length)
const ignoredPattern = arrayToRegExp(ignoredArr)

const watcher = chokidar.watch(process.cwd(), { ignored: ignoredPattern })
const watchTargets = (watchPaths && watchPaths.length > 0)
? watchPaths.map((dir) => path.resolve(process.cwd(), dir))
: [process.cwd()]
const watcher = chokidar.watch(watchTargets, { ignored: ignoredPattern })
watcher.on('ready', function () {
watcher.on('all', function (event, filepath) {
if (verboseWatch) {
Expand Down
2 changes: 1 addition & 1 deletion start.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function start (args) {
loadModules(opts)

if (opts.watch) {
return watch(args, opts.ignoreWatch, opts.verboseWatch)
return watch(args, opts.ignoreWatch, opts.verboseWatch, opts.watchPaths)
}

return runFastify(args)
Expand Down
34 changes: 33 additions & 1 deletion test/args.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ test('should parse args correctly', t => {
prettyLogs: true,
options: true,
watch: true,
watchPaths: [],
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output ignoreme.js',
verboseWatch: true,
port: 7777,
Expand Down Expand Up @@ -96,6 +97,7 @@ test('should parse args with = assignment correctly', t => {
prettyLogs: true,
options: true,
watch: true,
watchPaths: [],
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output ignoreme.js',
verboseWatch: true,
port: 7777,
Expand Down Expand Up @@ -175,6 +177,7 @@ test('should parse env vars correctly', t => {
prettyLogs: true,
options: true,
watch: true,
watchPaths: [],
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output ignoreme.js',
verboseWatch: true,
address: 'fastify.dev:9999',
Expand All @@ -201,7 +204,7 @@ test('should parse env vars correctly', t => {
})

test('should respect default values', t => {
t.plan(14)
t.plan(15)

const argv = [
'app.js'
Expand All @@ -213,6 +216,7 @@ test('should respect default values', t => {
t.assert.equal(parsedArgs.options, false)
t.assert.equal(parsedArgs.prettyLogs, false)
t.assert.equal(parsedArgs.watch, false)
t.assert.equal(parsedArgs.watchPaths, undefined)
t.assert.equal(parsedArgs.ignoreWatch, 'node_modules build dist .git bower_components logs .swp .nyc_output')
t.assert.equal(parsedArgs.verboseWatch, false)
t.assert.equal(parsedArgs.logLevel, 'fatal')
Expand Down Expand Up @@ -265,6 +269,7 @@ test('should parse custom plugin options', t => {
prettyLogs: true,
options: true,
watch: true,
watchPaths: [],
ignoreWatch: 'node_modules build dist .git bower_components logs .swp .nyc_output ignoreme.js',
verboseWatch: true,
port: 7777,
Expand Down Expand Up @@ -315,6 +320,7 @@ test('should parse config file correctly and prefer config values over default o
prettyLogs: true,
options: false,
watch: true,
watchPaths: [],
debug: false,
debugPort: 4000,
debugHost: '1.1.1.1',
Expand Down Expand Up @@ -359,6 +365,7 @@ test('should prefer command line args over config file options', t => {
prettyLogs: true,
options: false,
watch: true,
watchPaths: [],
debug: false,
debugPort: 9320,
debugHost: '1.1.1.1',
Expand Down Expand Up @@ -405,6 +412,7 @@ test('should favor trust proxy enabled over trust proxy ips and trust proxy hop'
prettyLogs: false,
options: false,
watch: false,
watchPaths: undefined,
debug: false,
debugPort: 1111,
debugHost: '1.1.1.1',
Expand All @@ -425,6 +433,29 @@ test('should favor trust proxy enabled over trust proxy ips and trust proxy hop'
})
})

test('should parse --watch with single directory', t => {
t.plan(4)

const argv = ['--watch', 'api', 'api/server.js']
const parsedArgs = parseArgs(argv)

t.assert.deepStrictEqual(parsedArgs._, ['api/server.js'])
t.assert.equal(parsedArgs.watch, true)
t.assert.deepStrictEqual(parsedArgs.watchPaths, ['api'])
t.assert.equal(parsedArgs.ignoreWatch, 'node_modules build dist .git bower_components logs .swp .nyc_output')
})

test('should parse --watch with multiple space-separated directories', t => {
t.plan(3)

const argv = ['--watch', 'api lib', 'server.js']
const parsedArgs = parseArgs(argv)

t.assert.equal(parsedArgs.watch, true)
t.assert.deepStrictEqual(parsedArgs.watchPaths, ['api', 'lib'])
t.assert.deepStrictEqual(parsedArgs._[0], 'server.js')
})

test('should favor trust proxy ips over trust proxy hop', t => {
t.plan(1)

Expand All @@ -450,6 +481,7 @@ test('should favor trust proxy ips over trust proxy hop', t => {
prettyLogs: false,
options: false,
watch: false,
watchPaths: undefined,
debug: false,
debugPort: 1111,
debugHost: '1.1.1.1',
Expand Down
14 changes: 14 additions & 0 deletions test/watch.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use strict'

const path = require('node:path')
const { arrayToRegExp } = require('../lib/watch/utils')
const watch = require('../lib/watch')

const { test } = require('node:test')

Expand All @@ -12,3 +14,15 @@ test('should equal expect RegExp', t => {

t.assert.deepStrictEqual(regExp, expectRegExp)
})

test('should return emitter when called with watchPaths', t => {
t.plan(2)

const pluginPath = path.join(__dirname, 'plugindir', 'plugin.js')
const emitter = watch([pluginPath], 'node_modules', false, ['lib'])

t.assert.equal(typeof emitter.stop, 'function')
t.assert.equal(typeof emitter.on, 'function')

emitter.stop()
})