Skip to content

Commit 3fa23e3

Browse files
committed
Add runtime warning on supported Node versions
1 parent d8333b8 commit 3fa23e3

7 files changed

Lines changed: 115 additions & 0 deletions

File tree

node-src/index.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,3 +904,29 @@ describe('parsing package.json', () => {
904904
expect(result.code).toBeDefined();
905905
});
906906
});
907+
908+
describe('Node version warning', () => {
909+
it('logs a warning when the current Node version is unsupported', async () => {
910+
vi.spyOn(process, 'versions', 'get').mockReturnValue({
911+
...process.versions,
912+
node: '18.0.0',
913+
});
914+
const log = new TestLogger();
915+
916+
await run({ flags: { dryRun: true }, options: { log } });
917+
918+
expect(log.warnings.some((w) => w.includes('Unsupported Node.js version'))).toBe(true);
919+
});
920+
921+
it('does not log a warning when the current Node version is supported', async () => {
922+
vi.spyOn(process, 'versions', 'get').mockReturnValue({
923+
...process.versions,
924+
node: '22.0.0',
925+
});
926+
const log = new TestLogger();
927+
928+
await run({ flags: { dryRun: true }, options: { log } });
929+
930+
expect(log.warnings.some((w) => w.includes('Unsupported Node.js version'))).toBe(false);
931+
});
932+
});

node-src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
getUserEmail,
1717
} from './git/git';
1818
import checkForUpdates from './lib/checkForUpdates';
19+
import checkNodeVersion from './lib/checkNodeVersion';
1920
import checkPackageJson from './lib/checkPackageJson';
2021
import { isE2EBuild } from './lib/e2eUtils';
2122
import { emailHash } from './lib/emailHash';
@@ -115,6 +116,8 @@ export async function run({
115116
log = createLogger(config.flags, config.extraOptions),
116117
} = extraOptions || {};
117118

119+
checkNodeVersion(log, config.pkg.engines?.node);
120+
118121
// We don't normalize because if the `version` field isn't a proper semver string, the process
119122
// silently exits.
120123
const packageInfo = await readPackageUp({ cwd: process.cwd(), normalize: false });
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { afterEach, describe, expect, it, vi } from 'vitest';
2+
3+
import checkNodeVersion from './checkNodeVersion';
4+
import TestLogger from './testLogger';
5+
6+
const stubNodeVersion = (version: string) => {
7+
vi.spyOn(process, 'versions', 'get').mockReturnValue({
8+
...process.versions,
9+
node: version,
10+
});
11+
};
12+
13+
describe('checkNodeVersion', () => {
14+
afterEach(() => {
15+
vi.restoreAllMocks();
16+
});
17+
18+
it('logs a warning when the current Node version is below the supported range', () => {
19+
stubNodeVersion('20.20.1');
20+
const log = new TestLogger();
21+
22+
checkNodeVersion(log, '>=22.0.0');
23+
24+
expect(log.warnings.some((w) => w.includes('Unsupported Node.js version'))).toBe(true);
25+
});
26+
27+
it('does not log when the current Node version satisfies the supported range', () => {
28+
stubNodeVersion('22.10.0');
29+
const log = new TestLogger();
30+
31+
checkNodeVersion(log, '>=22.0.0');
32+
33+
expect(log.warnings).toHaveLength(0);
34+
});
35+
36+
it('does not log when no supported range is provided', () => {
37+
stubNodeVersion('20.20.1');
38+
const log = new TestLogger();
39+
40+
checkNodeVersion(log, undefined);
41+
42+
expect(log.warnings).toHaveLength(0);
43+
});
44+
});

node-src/lib/checkNodeVersion.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { satisfies } from 'semver';
2+
3+
import unsupportedNodeVersion from '../ui/messages/warnings/unsupportedNodeVersion';
4+
import { Logger } from './log';
5+
6+
/**
7+
* Warn the user if the current Node.js runtime does not satisfy the supported range declared in
8+
* the CLI's `engines.node` field in `package.json`.
9+
*
10+
* @param log The logger to emit the warning to.
11+
* @param supportedRange The semver range of Node.js versions Chromatic supports.
12+
*/
13+
export default function checkNodeVersion(log: Logger, supportedRange: string | undefined) {
14+
if (!supportedRange) {
15+
return;
16+
}
17+
18+
if (!satisfies(process.versions.node, supportedRange)) {
19+
log.warn(unsupportedNodeVersion(process.versions.node, supportedRange));
20+
}
21+
}

node-src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ export interface Context {
312312
description: string;
313313
bugs: { url: string; email: string };
314314
docs: string;
315+
engines?: { node?: string };
315316
};
316317
sessionId: string;
317318
packageJson: Record<string, any>;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import unsupportedNodeVersion from './unsupportedNodeVersion';
2+
3+
export default {
4+
title: 'CLI/Messages/Warnings',
5+
};
6+
7+
export const UnsupportedNodeVersion = () => unsupportedNodeVersion('20.20.1', '>=22.0.0');
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import chalk from 'chalk';
2+
import { dedent } from 'ts-dedent';
3+
4+
import { warning } from '../../components/icons';
5+
import link from '../../components/link';
6+
7+
export default (currentVersion: string, supportedRange: string) =>
8+
dedent(chalk`
9+
${warning} {bold Unsupported Node.js version}
10+
You are running Node.js {bold v${currentVersion}}, but Chromatic supports {bold ${supportedRange}}.
11+
Chromatic may not work as expected. Please upgrade Node.js to a supported version based on Node's release schedule:
12+
${link('https://github.com/nodejs/release#release-schedule')}
13+
`);

0 commit comments

Comments
 (0)