From ed2ca0efc77cb12162b638a14040b4d6181b925d Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 8 Dec 2025 17:01:39 -0500 Subject: [PATCH 1/6] feat: provide --no-node-snapshot by default Signed-off-by: aramissennyeydd --- .../build/lib/runner/runBackend.test.ts | 189 ++++++++++++++++++ .../modules/build/lib/runner/runBackend.ts | 8 + .../src/modules/test/commands/package/test.ts | 8 + 3 files changed, 205 insertions(+) create mode 100644 packages/cli/src/modules/build/lib/runner/runBackend.test.ts diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts new file mode 100644 index 0000000000..49fb59ecd9 --- /dev/null +++ b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts @@ -0,0 +1,189 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { runBackend } from './runBackend'; + +// Mock external dependencies +jest.mock('chokidar', () => ({ + watch: jest.fn(() => ({ + on: jest.fn().mockReturnThis(), + add: jest.fn(), + })), +})); + +jest.mock('cross-spawn', () => + jest.fn(() => ({ + on: jest.fn().mockReturnThis(), + once: jest.fn().mockReturnThis(), + kill: jest.fn(), + killed: false, + exitCode: null, + pid: 12345, + })), +); + +jest.mock('../ipc', () => ({ + IpcServer: jest.fn().mockImplementation(() => ({ + addChild: jest.fn(), + })), + ServerDataStore: { + bind: jest.fn(), + }, +})); + +jest.mock('ctrlc-windows', () => ({ + ctrlc: jest.fn(), +})); + +describe('runBackend', () => { + let originalEnv: NodeJS.ProcessEnv; + let originalPlatform: string; + + beforeEach(() => { + // Save original environment + originalEnv = { ...process.env }; + originalPlatform = process.platform; + + // Clear environment variables that we're testing + delete process.env.NODE_ENV; + delete process.env.NODE_OPTIONS; + + // Mock process.stdin.on to prevent actual stdin reading + jest.spyOn(process.stdin, 'on').mockReturnValue(process.stdin); + + // Mock process.once to prevent actual signal handling + jest.spyOn(process, 'once').mockReturnValue(process); + }); + + afterEach(() => { + // Restore original environment + process.env = originalEnv; + Object.defineProperty(process, 'platform', { + value: originalPlatform, + }); + + jest.clearAllMocks(); + }); + + describe('NODE_OPTIONS environment variable', () => { + it('should add --no-node-snapshot when NODE_OPTIONS is not set', async () => { + delete process.env.NODE_OPTIONS; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_OPTIONS).toBe('--no-node-snapshot'); + }); + + it('should append --no-node-snapshot when NODE_OPTIONS exists without it', async () => { + process.env.NODE_OPTIONS = '--max-old-space-size=4096'; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_OPTIONS).toBe( + '--max-old-space-size=4096 --no-node-snapshot', + ); + }); + + it('should not add --no-node-snapshot when --node-snapshot already exists', async () => { + process.env.NODE_OPTIONS = '--node-snapshot --max-old-space-size=4096'; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_OPTIONS).toBe( + '--node-snapshot --max-old-space-size=4096', + ); + }); + + it('should not add --no-node-snapshot when --node-snapshot exists in the middle of NODE_OPTIONS', async () => { + process.env.NODE_OPTIONS = + '--max-old-space-size=4096 --node-snapshot --inspect'; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_OPTIONS).toBe( + '--max-old-space-size=4096 --node-snapshot --inspect', + ); + }); + + it('should handle NODE_OPTIONS with trailing spaces', async () => { + process.env.NODE_OPTIONS = '--max-old-space-size=4096 '; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_OPTIONS).toBe( + '--max-old-space-size=4096 --no-node-snapshot', + ); + }); + }); + + describe('NODE_ENV environment variable', () => { + it('should set NODE_ENV to development when not set', async () => { + delete process.env.NODE_ENV; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_ENV).toBe('development'); + }); + + it('should not override existing NODE_ENV', async () => { + process.env.NODE_ENV = 'production'; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_ENV).toBe('production'); + }); + }); + + describe('combined environment setup', () => { + it('should set both NODE_ENV and NODE_OPTIONS when neither is set', async () => { + delete process.env.NODE_ENV; + delete process.env.NODE_OPTIONS; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_ENV).toBe('development'); + expect(process.env.NODE_OPTIONS).toBe('--no-node-snapshot'); + }); + + it('should handle both environment variables independently', async () => { + process.env.NODE_ENV = 'test'; + process.env.NODE_OPTIONS = '--inspect'; + + runBackend({ + entry: 'src/index', + }); + + expect(process.env.NODE_ENV).toBe('test'); + expect(process.env.NODE_OPTIONS).toBe('--inspect --no-node-snapshot'); + }); + }); +}); diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.ts b/packages/cli/src/modules/build/lib/runner/runBackend.ts index 49dccf804f..d48fb34fc2 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.ts @@ -52,6 +52,14 @@ export async function runBackend(options: RunBackendOptions) { envEnv.NODE_ENV = 'development'; } + // Unless the user explicitly toggles node-snapshot, default to provide --no-node-snapshot to reduce number of steps to run scaffolder + // on Node LTS. + if (!envEnv.NODE_OPTIONS?.includes('--node-snapshot')) { + envEnv.NODE_OPTIONS = + (envEnv.NODE_OPTIONS ? envEnv.NODE_OPTIONS + ' ' : '') + + '--no-node-snapshot'; + } + // Set up the parent IPC server and bind the available services const server = new IpcServer(); ServerDataStore.bind(server); diff --git a/packages/cli/src/modules/test/commands/package/test.ts b/packages/cli/src/modules/test/commands/package/test.ts index 1ecf5b395e..72e78eae7b 100644 --- a/packages/cli/src/modules/test/commands/package/test.ts +++ b/packages/cli/src/modules/test/commands/package/test.ts @@ -78,6 +78,14 @@ export default async (_opts: OptionValues, cmd: Command) => { process.env.TZ = 'UTC'; } + // Unless the user explicitly toggles node-snapshot, default to provide --no-node-snapshot to reduce number of steps to run scaffolder + // on Node LTS. + if (!process.env.NODE_OPTIONS?.includes('--node-snapshot')) { + process.env.NODE_OPTIONS = `${ + process.env.NODE_OPTIONS ? `${process.env.NODE_OPTIONS} ` : '' + }--no-node-snapshot`; + } + // This ensures that the process doesn't exit too early before stdout is flushed if (args.includes('--help')) { (process.stdout as any)._handle.setBlocking(true); From f6f22a95096b48fc7ca43f10159c1b6bea3d4302 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 8 Dec 2025 17:02:54 -0500 Subject: [PATCH 2/6] add changeset Signed-off-by: aramissennyeydd --- .changeset/bright-lions-unite.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/bright-lions-unite.md diff --git a/.changeset/bright-lions-unite.md b/.changeset/bright-lions-unite.md new file mode 100644 index 0000000000..e9bef02e10 --- /dev/null +++ b/.changeset/bright-lions-unite.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': minor +--- + +Provide `--no-node-snapshot` by default when running the `package start` or `package test`. You can disable this behavior by providing `NODE_OPTIONS='--node-snapshot'`. From 0def824b4d05733c3bd68376982be6d34009cc32 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 8 Dec 2025 17:28:19 -0500 Subject: [PATCH 3/6] remove --no-node-snapshots flag Signed-off-by: aramissennyeydd --- .github/workflows/ci.yml | 2 +- .github/workflows/verify_e2e-windows.yml | 2 +- .github/workflows/verify_windows.yml | 2 +- docs/tooling/cli/02-build-system.md | 2 +- .../build/lib/runner/runBackend.test.ts | 108 ++++++++++-------- .../modules/build/lib/runner/runBackend.ts | 14 +-- 6 files changed, 71 insertions(+), 59 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7552898bd0..36b4114efe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -203,7 +203,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=8192 --no-node-snapshot --experimental-vm-modules + NODE_OPTIONS: --max-old-space-size=8192 --experimental-vm-modules INTEGRATION_TEST_GITHUB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITHUB_TOKEN }} INTEGRATION_TEST_GITLAB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITLAB_TOKEN }} INTEGRATION_TEST_BITBUCKET_TOKEN: ${{ secrets.INTEGRATION_TEST_BITBUCKET_TOKEN }} diff --git a/.github/workflows/verify_e2e-windows.yml b/.github/workflows/verify_e2e-windows.yml index 933bbb0840..f63eb5d61b 100644 --- a/.github/workflows/verify_e2e-windows.yml +++ b/.github/workflows/verify_e2e-windows.yml @@ -28,7 +28,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=8192 --no-node-snapshot --experimental-vm-modules + NODE_OPTIONS: --max-old-space-size=8192 --experimental-vm-modules name: E2E Windows ${{ matrix.node-version }} steps: diff --git a/.github/workflows/verify_windows.yml b/.github/workflows/verify_windows.yml index ae2ec477d3..f7de04772d 100644 --- a/.github/workflows/verify_windows.yml +++ b/.github/workflows/verify_windows.yml @@ -21,7 +21,7 @@ jobs: env: CI: true - NODE_OPTIONS: --max-old-space-size=8192 --no-node-snapshot --experimental-vm-modules + NODE_OPTIONS: --max-old-space-size=8192 --experimental-vm-modules INTEGRATION_TEST_GITHUB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITHUB_TOKEN }} INTEGRATION_TEST_GITLAB_TOKEN: ${{ secrets.INTEGRATION_TEST_GITLAB_TOKEN }} INTEGRATION_TEST_BITBUCKET_TOKEN: ${{ secrets.INTEGRATION_TEST_BITBUCKET_TOKEN }} diff --git a/docs/tooling/cli/02-build-system.md b/docs/tooling/cli/02-build-system.md index c8d9034955..25945f73dd 100644 --- a/docs/tooling/cli/02-build-system.md +++ b/docs/tooling/cli/02-build-system.md @@ -610,7 +610,7 @@ With that in mind, here are some IDEs configurations to run backstage components 1. Click on "Edit Configurations" on top panel 2. In the modal dialog click on link "Edit configuration templates..." located in the bottom left corner. 3. "Configuration file": leave empty (`backstage-cli` adds the config) - 4. "Node options": `--no-node-snapshot --experimental-vm-modules` + 4. "Node options": ` --experimental-vm-modules` 5. "Jest package": `~/workspace/backstage/node_modules/@backstage/cli` - the location of the backstage cli package. 6. "Working directory": `~/workspace/backstage` 7. "Jest Options": `repo test --runInBand --watch=false` diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts index 49fb59ecd9..1e2c2190cf 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts @@ -15,6 +15,7 @@ */ import { runBackend } from './runBackend'; +import spawn from 'cross-spawn'; // Mock external dependencies jest.mock('chokidar', () => ({ @@ -51,8 +52,12 @@ jest.mock('ctrlc-windows', () => ({ describe('runBackend', () => { let originalEnv: NodeJS.ProcessEnv; let originalPlatform: string; + const mockSpawn = spawn as jest.MockedFunction; beforeEach(() => { + // Use fake timers to control debounce + jest.useFakeTimers(); + // Save original environment originalEnv = { ...process.env }; originalPlatform = process.platform; @@ -76,44 +81,56 @@ describe('runBackend', () => { }); jest.clearAllMocks(); + jest.useRealTimers(); }); - describe('NODE_OPTIONS environment variable', () => { - it('should add --no-node-snapshot when NODE_OPTIONS is not set', async () => { + describe('--no-node-snapshot argument handling', () => { + it('should pass --no-node-snapshot when NODE_OPTIONS is not set', () => { delete process.env.NODE_OPTIONS; runBackend({ entry: 'src/index', }); - expect(process.env.NODE_OPTIONS).toBe('--no-node-snapshot'); + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).toContain('--no-node-snapshot'); }); - it('should append --no-node-snapshot when NODE_OPTIONS exists without it', async () => { + it('should pass --no-node-snapshot when NODE_OPTIONS exists without --node-snapshot', () => { process.env.NODE_OPTIONS = '--max-old-space-size=4096'; runBackend({ entry: 'src/index', }); - expect(process.env.NODE_OPTIONS).toBe( - '--max-old-space-size=4096 --no-node-snapshot', - ); + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).toContain('--no-node-snapshot'); }); - it('should not add --no-node-snapshot when --node-snapshot already exists', async () => { + it('should not pass --no-node-snapshot when --node-snapshot already exists in NODE_OPTIONS', () => { process.env.NODE_OPTIONS = '--node-snapshot --max-old-space-size=4096'; runBackend({ entry: 'src/index', }); - expect(process.env.NODE_OPTIONS).toBe( - '--node-snapshot --max-old-space-size=4096', - ); + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).not.toContain('--no-node-snapshot'); }); - it('should not add --no-node-snapshot when --node-snapshot exists in the middle of NODE_OPTIONS', async () => { + it('should not pass --no-node-snapshot when --node-snapshot exists in the middle of NODE_OPTIONS', () => { process.env.NODE_OPTIONS = '--max-old-space-size=4096 --node-snapshot --inspect'; @@ -121,26 +138,49 @@ describe('runBackend', () => { entry: 'src/index', }); - expect(process.env.NODE_OPTIONS).toBe( - '--max-old-space-size=4096 --node-snapshot --inspect', - ); + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).not.toContain('--no-node-snapshot'); }); - it('should handle NODE_OPTIONS with trailing spaces', async () => { + it('should pass --no-node-snapshot even with trailing spaces in NODE_OPTIONS', () => { process.env.NODE_OPTIONS = '--max-old-space-size=4096 '; runBackend({ entry: 'src/index', }); - expect(process.env.NODE_OPTIONS).toBe( - '--max-old-space-size=4096 --no-node-snapshot', - ); + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).toContain('--no-node-snapshot'); + }); + + it('should pass --no-node-snapshot alongside other option args like --inspect', () => { + delete process.env.NODE_OPTIONS; + + runBackend({ + entry: 'src/index', + inspectEnabled: true, + }); + + // Fast-forward past the debounce delay (100ms) + jest.advanceTimersByTime(100); + + expect(mockSpawn).toHaveBeenCalled(); + const spawnArgs = mockSpawn.mock.calls[0][1] as string[]; + expect(spawnArgs).toContain('--no-node-snapshot'); + expect(spawnArgs).toContain('--inspect'); }); }); describe('NODE_ENV environment variable', () => { - it('should set NODE_ENV to development when not set', async () => { + it('should set NODE_ENV to development when not set', () => { delete process.env.NODE_ENV; runBackend({ @@ -150,7 +190,7 @@ describe('runBackend', () => { expect(process.env.NODE_ENV).toBe('development'); }); - it('should not override existing NODE_ENV', async () => { + it('should not override existing NODE_ENV', () => { process.env.NODE_ENV = 'production'; runBackend({ @@ -160,30 +200,4 @@ describe('runBackend', () => { expect(process.env.NODE_ENV).toBe('production'); }); }); - - describe('combined environment setup', () => { - it('should set both NODE_ENV and NODE_OPTIONS when neither is set', async () => { - delete process.env.NODE_ENV; - delete process.env.NODE_OPTIONS; - - runBackend({ - entry: 'src/index', - }); - - expect(process.env.NODE_ENV).toBe('development'); - expect(process.env.NODE_OPTIONS).toBe('--no-node-snapshot'); - }); - - it('should handle both environment variables independently', async () => { - process.env.NODE_ENV = 'test'; - process.env.NODE_OPTIONS = '--inspect'; - - runBackend({ - entry: 'src/index', - }); - - expect(process.env.NODE_ENV).toBe('test'); - expect(process.env.NODE_OPTIONS).toBe('--inspect --no-node-snapshot'); - }); - }); }); diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.ts b/packages/cli/src/modules/build/lib/runner/runBackend.ts index d48fb34fc2..a3072c5dd7 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.ts @@ -52,14 +52,6 @@ export async function runBackend(options: RunBackendOptions) { envEnv.NODE_ENV = 'development'; } - // Unless the user explicitly toggles node-snapshot, default to provide --no-node-snapshot to reduce number of steps to run scaffolder - // on Node LTS. - if (!envEnv.NODE_OPTIONS?.includes('--node-snapshot')) { - envEnv.NODE_OPTIONS = - (envEnv.NODE_OPTIONS ? envEnv.NODE_OPTIONS + ' ' : '') + - '--no-node-snapshot'; - } - // Set up the parent IPC server and bind the available services const server = new IpcServer(); ServerDataStore.bind(server); @@ -123,6 +115,12 @@ export async function runBackend(options: RunBackendOptions) { } } + // Unless the user explicitly toggles node-snapshot, default to provide --no-node-snapshot to reduce number of steps to run scaffolder + // on Node LTS. + if (!envEnv.NODE_OPTIONS?.includes('--node-snapshot')) { + optionArgs.push('--no-node-snapshot'); + } + const userArgs = process.argv .slice(['node', 'backstage-cli', 'package', 'start'].length) .filter(arg => !optionArgs.includes(arg)); From 238852ca7d1318e07e192f6c6f0c55995656a0c4 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Mon, 8 Dec 2025 17:44:53 -0500 Subject: [PATCH 4/6] fix build Signed-off-by: aramissennyeydd --- .../build/lib/runner/runBackend.test.ts | 22 ------------------- .../modules/build/lib/runner/runBackend.ts | 2 +- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts index 1e2c2190cf..11018b0783 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts @@ -178,26 +178,4 @@ describe('runBackend', () => { expect(spawnArgs).toContain('--inspect'); }); }); - - describe('NODE_ENV environment variable', () => { - it('should set NODE_ENV to development when not set', () => { - delete process.env.NODE_ENV; - - runBackend({ - entry: 'src/index', - }); - - expect(process.env.NODE_ENV).toBe('development'); - }); - - it('should not override existing NODE_ENV', () => { - process.env.NODE_ENV = 'production'; - - runBackend({ - entry: 'src/index', - }); - - expect(process.env.NODE_ENV).toBe('production'); - }); - }); }); diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.ts b/packages/cli/src/modules/build/lib/runner/runBackend.ts index a3072c5dd7..0550ff2563 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.ts @@ -47,7 +47,7 @@ export type RunBackendOptions = { }; export async function runBackend(options: RunBackendOptions) { - const envEnv = process.env as { NODE_ENV: string }; + const envEnv = process.env as { NODE_ENV: string; NODE_OPTIONS?: string }; if (!envEnv.NODE_ENV) { envEnv.NODE_ENV = 'development'; } From d78945eff946cb8f60e8b7ee92062eadd223ca9e Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Tue, 9 Dec 2025 17:52:18 -0500 Subject: [PATCH 5/6] fix test errors by adding to repo test as well Signed-off-by: aramissennyeydd --- .../cli/src/modules/build/lib/runner/runBackend.test.ts | 5 +---- packages/cli/src/modules/test/commands/repo/test.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts index 11018b0783..fbffec92d3 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts @@ -60,12 +60,9 @@ describe('runBackend', () => { // Save original environment originalEnv = { ...process.env }; + process.env = {}; originalPlatform = process.platform; - // Clear environment variables that we're testing - delete process.env.NODE_ENV; - delete process.env.NODE_OPTIONS; - // Mock process.stdin.on to prevent actual stdin reading jest.spyOn(process.stdin, 'on').mockReturnValue(process.stdin); diff --git a/packages/cli/src/modules/test/commands/repo/test.ts b/packages/cli/src/modules/test/commands/repo/test.ts index fd18ba09fe..40e6666dcf 100644 --- a/packages/cli/src/modules/test/commands/repo/test.ts +++ b/packages/cli/src/modules/test/commands/repo/test.ts @@ -289,6 +289,14 @@ export async function command(opts: OptionValues, cmd: Command): Promise { process.env.TZ = 'UTC'; } + // Unless the user explicitly toggles node-snapshot, default to provide --no-node-snapshot to reduce number of steps to run scaffolder + // on Node LTS. + if (!process.env.NODE_OPTIONS?.includes('--node-snapshot')) { + process.env.NODE_OPTIONS = `${ + process.env.NODE_OPTIONS ? `${process.env.NODE_OPTIONS} ` : '' + }--no-node-snapshot`; + } + // This ensures that the process doesn't exit too early before stdout is flushed if (args.includes('--jest-help')) { removeOptionArg(args, '--jest-help'); From 51a4cd3b7621ba71152bb07a9fb5974ce90900cb Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Wed, 10 Dec 2025 13:58:45 -0500 Subject: [PATCH 6/6] fix type error Signed-off-by: aramissennyeydd --- packages/cli/src/modules/build/lib/runner/runBackend.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts index fbffec92d3..2b97ae352c 100644 --- a/packages/cli/src/modules/build/lib/runner/runBackend.test.ts +++ b/packages/cli/src/modules/build/lib/runner/runBackend.test.ts @@ -60,7 +60,7 @@ describe('runBackend', () => { // Save original environment originalEnv = { ...process.env }; - process.env = {}; + process.env = { NODE_ENV: 'test' }; originalPlatform = process.platform; // Mock process.stdin.on to prevent actual stdin reading