Skip to content

Commit b51daf8

Browse files
authored
feat(dev-mode): add --reflection flag (#797)
1 parent d6b835b commit b51daf8

File tree

5 files changed

+35
-9
lines changed

5 files changed

+35
-9
lines changed

src/cli/commands/dev.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const DEV_ARGS = {
1818
'--inspect-brk': String,
1919
'--entrypoint': String,
2020
'-e': '--entrypoint',
21+
'--reflection': Boolean,
22+
'-r': '--reflection',
2123
'--help': Boolean,
2224
'-h': '--help',
2325
}
@@ -52,8 +54,16 @@ export class Dev implements Command {
5254

5355
log.info('start', { version: ownPackage.version })
5456

55-
const runDebouncedReflection = simpleDebounce((layout: Layout.Layout) => {
56-
return Reflection.reflect(layout, { artifacts: true })
57+
const runDebouncedReflection = simpleDebounce(async (layout: Layout.Layout) => {
58+
const reflectionResult = await Reflection.reflect(layout, { artifacts: true })
59+
if (args['--reflection']) {
60+
if (reflectionResult.success) {
61+
log.info('reflection done')
62+
log.info('waiting for file changes to run reflection...')
63+
} else {
64+
log.error('reflection failed', { error: reflectionResult.error })
65+
}
66+
}
5767
})
5868

5969
const devPlugin: Plugin.WorktimeHooks = {
@@ -74,6 +84,10 @@ export class Dev implements Command {
7484
layout = await Layout.create({ entrypointPath })
7585
}
7686

87+
if (args['--reflection']) {
88+
log.info('running reflection')
89+
}
90+
7791
runDebouncedReflection(layout)
7892
},
7993
},
@@ -97,8 +111,14 @@ export class Dev implements Command {
97111
target: ts.ScriptTarget.ES2015,
98112
})
99113

114+
/**
115+
* We use an empty script when in reflection mode so that the user's app doesn't run.
116+
* The watcher will keep running though and so will reflection in the devPlugin.onBeforeWatcherStartOrRestart hook above
117+
*/
118+
const entrypointScript = args['--reflection'] ? '' : transpiledStartModule
119+
100120
const watcher = await createWatcher({
101-
entrypointScript: transpiledStartModule,
121+
entrypointScript,
102122
sourceRoot: layout.sourceRoot,
103123
cwd: process.cwd(),
104124
plugins: [devPlugin].concat(worktimePlugins.map((p) => p.hooks)),
@@ -116,6 +136,7 @@ export class Dev implements Command {
116136
117137
Flags:
118138
-e, --entrypoint Custom entrypoint to your app (default: app.ts)
139+
-r, --reflection Run dev mode for reflection only (eg: typegen, sdl file etc..)
119140
-h, --help Show this help message
120141
`
121142
}

src/lib/watcher/runner.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ require('../tty-linker').create().child.install()
55
import { rootLogger } from '../nexus-logger'
66
import hook from './hook'
77
import * as IPC from './ipc'
8+
import * as DevMode from '../../runtime/dev-mode'
89

910
const log = rootLogger.child('dev').child('runner')
1011

1112
main()
1213

1314
async function main() {
14-
if (!process.env.ENTRYPOINT_SCRIPT) {
15+
if (process.env.ENTRYPOINT_SCRIPT === undefined) {
1516
throw new Error('process.env.ENTRYPOINT_SCRIPT needs to be defined')
1617
}
1718

1819
// Enable dev mode code paths for IPC interaction
19-
process.env.NEXUS_DEV_MODE = 'true'
20+
process.env[DevMode.DEV_MODE_ENV_VAR_NAME] = 'true'
2021

2122
// TODO perhaps we should move these unhandled error/rejections
2223
// to start module because we probably want them just as much from production as

src/lib/watcher/watcher.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export async function createWatcher(options: Options): Promise<Watcher> {
5151
}
5252

5353
options.events?.({ type: 'server_listening' })
54-
watcher.resume()
5554
},
5655
onRunnerStdioMessage({ stdio, data }) {
5756
options.events?.({ type: 'runner_stdio', stdio, data })
@@ -180,22 +179,25 @@ export async function createWatcher(options: Options): Promise<Watcher> {
180179
}
181180
restarting = true
182181
clearConsole()
183-
log.trace('hook', { name: 'beforeWatcherStartOrRestart' })
182+
log.info('restarting', change)
184183

184+
log.trace('hook', { name: 'beforeWatcherStartOrRestart' })
185185
for (const plugin of plugins) {
186186
const runnerChanges = await plugin.dev.onBeforeWatcherStartOrRestart?.(change)
187187
if (runnerChanges) {
188188
link.updateOptions(runnerChanges)
189189
}
190190
}
191+
191192
log.trace('hook', { name: 'beforeWatcherRestart' })
192193
plugins.forEach((p) => {
193194
p.dev.onBeforeWatcherRestart?.()
194195
})
195-
log.info('restarting', change)
196+
196197
options.events?.({ type: 'restart', file: change.file, reason: change.type })
197198
await link.startOrRestart()
198199
restarting = false
200+
watcher.resume()
199201
}
200202

201203
let resolveWatcherPromise: null | (() => void) = null

src/runtime/dev-mode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { fatal } from '../lib/process'
1515
/**
1616
* Data
1717
*/
18-
const DEV_MODE_ENV_VAR_NAME = 'NEXUS_DEV_MODE'
18+
export const DEV_MODE_ENV_VAR_NAME = 'NEXUS_DEV_MODE'
1919

2020
/**
2121
* Eager integrity check.

src/runtime/server/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as Net from 'net'
66
import stripAnsi from 'strip-ansi'
77
import * as Plugin from '../../lib/plugin'
88
import { AppState } from '../app'
9+
import * as DevMode from '../dev-mode'
910
import { ContextContributor } from '../schema/schema'
1011
import { log } from './logger'
1112
import { createRequestHandlerPlayground } from './request-handler-playground'
@@ -88,6 +89,7 @@ export function create(appState: AppState) {
8889
path: settings.data.path,
8990
playgroundPath: settings.data.playground ? settings.data.playground.path : undefined,
9091
})
92+
DevMode.sendServerReadySignalToDevModeMaster()
9193
},
9294
async stop() {
9395
if (!state.running) {

0 commit comments

Comments
 (0)