From 86837125ee28f0f955e2995d56bc462aebdb1cbf Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 14:44:13 +0700 Subject: [PATCH 01/10] update vite build stats plugin to send bundle bootstrap chunk size and limit --- src/types.ts | 6 ++++++ src/viteBuildStatsPlugin.ts | 21 ++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 1ea73af..0175e2c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -29,7 +29,13 @@ export interface WebpackBuildData extends CommonMetadata { nbrOfRebuiltModules: number; } +export interface ViteBundleStats { + bootstrapChunkSizeBytes: number + bootstrapChunkSizeLimitBytes?: number +} + export interface ViteBuildData extends CommonMetadata { type: 'vite'; viteVersion: string | null; + bundleStats?: ViteBundleStats } diff --git a/src/viteBuildStatsPlugin.ts b/src/viteBuildStatsPlugin.ts index 67b73d0..bb3d239 100644 --- a/src/viteBuildStatsPlugin.ts +++ b/src/viteBuildStatsPlugin.ts @@ -1,12 +1,15 @@ -import type { ViteBuildData } from './types'; +import type { ViteBuildData, ViteBundleStats } from "./types"; import { type Plugin } from 'vite'; +import { NormalizedOutputOptions, OutputBundle } from 'rollup'; import { getCommonMetadata, sendBuildData } from './common'; export function viteBuildStatsPlugin( customIdentifier: string | undefined = process.env.npm_lifecycle_event, + bootstrapBundleSizeLimitKb?: number, ): Plugin { let buildStart: number; let buildEnd: number; + let bootstrapChunkSizeBytes: number; let rollupVersion: string | undefined = undefined; return { @@ -18,11 +21,27 @@ export function viteBuildStatsPlugin( buildEnd: function () { buildEnd = Date.now(); }, + generateBundle: ( + outputOptions: NormalizedOutputOptions, + outputBundle: OutputBundle + ) => { + for (const [_, bundle] of Object.entries(outputBundle)) { + if (bundle.name === 'bootstrap' && bundle.type === 'chunk') { + bootstrapChunkSizeBytes = new Blob([bundle.code]).size; + } + } + }, closeBundle: async function () { + const bundleStats: ViteBundleStats = { + bootstrapChunkSizeBytes: bootstrapChunkSizeBytes, + bootstrapChunkSizeLimitBytes: bootstrapBundleSizeLimitKb != null ? bootstrapBundleSizeLimitKb * 1000 : undefined, + } + const buildStats: ViteBuildData = { ...getCommonMetadata(buildEnd - buildStart, customIdentifier), type: 'vite', viteVersion: rollupVersion ?? null, + bundleStats, }; sendBuildData(buildStats); From ab4bca3b7e1bb8a13e71ecf554f17e06aee128b1 Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 15:17:16 +0700 Subject: [PATCH 02/10] update tests to verify chunk size and limits are sent by plugin --- tests/viteBuildStatsPlugin.spec.ts | 57 +++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/tests/viteBuildStatsPlugin.spec.ts b/tests/viteBuildStatsPlugin.spec.ts index c7b1933..268cd1f 100644 --- a/tests/viteBuildStatsPlugin.spec.ts +++ b/tests/viteBuildStatsPlugin.spec.ts @@ -1,6 +1,7 @@ import type { CommonMetadata, ViteBuildData } from '../src/types'; -import { viteBuildStatsPlugin } from '../src/viteBuildStatsPlugin'; +import { viteBuildStatsPlugin } from "../src"; import { getCommonMetadata, sendBuildData } from '../src/common'; +import { NormalizedOutputOptions, OutputBundle, OutputChunk, OutputAsset } from "rollup"; jest.mock('../src/common', () => ({ getCommonMetadata: jest.fn(), @@ -12,10 +13,54 @@ const mockedGetCommonMetadata = getCommonMetadata as jest.MockedFunction< >; const mockedSendBuildData = sendBuildData as jest.MockedFunction; +function generateOutputBundle(): OutputBundle { + const bootstrapChunk: OutputChunk = { + name: 'bootstrap', + type: 'chunk', + code: 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + } as unknown as OutputChunk; + + const nonBootstrapChunkA: OutputChunk = { + name: 'notBootstrapA', + type: 'chunk', + code: 'random sentence to pass my time' + } as unknown as OutputChunk; + + const nonBootstrapChunkB: OutputChunk = { + name: 'notBootstrapB', + type: 'chunk', + code: 'random sentence to pass my time again' + } as unknown as OutputChunk; + + const assetNamedBootstrap: OutputAsset = { + name: 'bootstrap', + fileName: 'bootstrap.jpg', + type: 'asset', + source: '../../assets/bootstrap.jpg', + needsCodeReference: false + }; + + return { + 'a-not-bootstrap.js': nonBootstrapChunkA, + 'bootstrap.xyz123.js': bootstrapChunk, + 'b-not-bootstrap.js': nonBootstrapChunkB, + 'bootstrap.jpg': assetNamedBootstrap + }; +} + describe('viteBuildStatsPlugin', () => { + const bootstrapChunkSizeLimitKb = 2_000; const expected: ViteBuildData = { type: 'vite', viteVersion: '1.2.3', + bundleStats: { + bootstrapChunkSizeBytes: 430, + bootstrapChunkSizeLimitBytes: bootstrapChunkSizeLimitKb * 1000, + } } as ViteBuildData; beforeEach(() => { @@ -31,14 +76,16 @@ describe('viteBuildStatsPlugin', () => { // mock common utils mockedGetCommonMetadata.mockReturnValue({} as CommonMetadata); mockedSendBuildData.mockReturnValue(Promise.resolve()); + const bundle = generateOutputBundle(); - const plugin = viteBuildStatsPlugin('my custom identifier'); + const plugin = viteBuildStatsPlugin('my custom identifier', bootstrapChunkSizeLimitKb); (plugin.buildStart as () => void).bind({ meta: { rollupVersion: '1.2.3' } })(); + (plugin.generateBundle as (opts: NormalizedOutputOptions, bundle: OutputBundle) => void)({} as NormalizedOutputOptions, bundle); (plugin.buildEnd as () => void)(); await (plugin.closeBundle as () => Promise)(); expect(mockedGetCommonMetadata).toBeCalledWith(100, 'my custom identifier'); - expect(mockedSendBuildData).toBeCalledWith(expect.objectContaining(expected)); + expect(mockedSendBuildData).toBeCalledWith(expected); }); it('should use process.env.npm_lifecycle_event as default custom identifier', async () => { @@ -50,6 +97,7 @@ describe('viteBuildStatsPlugin', () => { // mock common utils mockedGetCommonMetadata.mockReturnValue({} as CommonMetadata); mockedSendBuildData.mockReturnValue(Promise.resolve()); + const bundle = generateOutputBundle(); // mock process object global.process = { @@ -60,10 +108,11 @@ describe('viteBuildStatsPlugin', () => { const plugin = viteBuildStatsPlugin(); (plugin.buildStart as () => void).bind({ meta: { rollupVersion: '1.2.3' } })(); + (plugin.generateBundle as (opts: NormalizedOutputOptions, bundle: OutputBundle) => void)({} as NormalizedOutputOptions, bundle); (plugin.buildEnd as () => void)(); await (plugin.closeBundle as () => Promise)(); expect(mockedGetCommonMetadata).toBeCalledWith(100, 'default_value'); - expect(mockedSendBuildData).toBeCalledWith(expect.objectContaining(expected)); + expect(mockedSendBuildData).toBeCalledWith({ ...expected, bundleStats: { ...expected.bundleStats, bootstrapChunkSizeLimitBytes: undefined } }); }); }); From 000978851f432d7361af3e3a303721b46d5bba6e Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 15:25:16 +0700 Subject: [PATCH 03/10] refactor tests --- tests/viteBuildStatsPlugin.spec.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/viteBuildStatsPlugin.spec.ts b/tests/viteBuildStatsPlugin.spec.ts index 268cd1f..fd1f1cd 100644 --- a/tests/viteBuildStatsPlugin.spec.ts +++ b/tests/viteBuildStatsPlugin.spec.ts @@ -112,7 +112,12 @@ describe('viteBuildStatsPlugin', () => { (plugin.buildEnd as () => void)(); await (plugin.closeBundle as () => Promise)(); + const caseSpecificExpected = { + ...expected, + bundleStats: { ...expected.bundleStats, bootstrapChunkSizeLimitBytes: undefined } + } + expect(mockedGetCommonMetadata).toBeCalledWith(100, 'default_value'); - expect(mockedSendBuildData).toBeCalledWith({ ...expected, bundleStats: { ...expected.bundleStats, bootstrapChunkSizeLimitBytes: undefined } }); + expect(mockedSendBuildData).toBeCalledWith(caseSpecificExpected); }); }); From 9369eb307a2df136b8345e8973c0904becc70d97 Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 16:01:27 +0700 Subject: [PATCH 04/10] refactor imports --- src/viteBuildStatsPlugin.ts | 3 ++- tests/viteBuildStatsPlugin.spec.ts | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/viteBuildStatsPlugin.ts b/src/viteBuildStatsPlugin.ts index bb3d239..e97d100 100644 --- a/src/viteBuildStatsPlugin.ts +++ b/src/viteBuildStatsPlugin.ts @@ -1,6 +1,7 @@ -import type { ViteBuildData, ViteBundleStats } from "./types"; import { type Plugin } from 'vite'; import { NormalizedOutputOptions, OutputBundle } from 'rollup'; + +import type { ViteBuildData, ViteBundleStats } from './types'; import { getCommonMetadata, sendBuildData } from './common'; export function viteBuildStatsPlugin( diff --git a/tests/viteBuildStatsPlugin.spec.ts b/tests/viteBuildStatsPlugin.spec.ts index fd1f1cd..acd9152 100644 --- a/tests/viteBuildStatsPlugin.spec.ts +++ b/tests/viteBuildStatsPlugin.spec.ts @@ -1,7 +1,8 @@ +import { NormalizedOutputOptions, OutputBundle, OutputChunk, OutputAsset } from "rollup"; + +import { viteBuildStatsPlugin } from '../src'; import type { CommonMetadata, ViteBuildData } from '../src/types'; -import { viteBuildStatsPlugin } from "../src"; import { getCommonMetadata, sendBuildData } from '../src/common'; -import { NormalizedOutputOptions, OutputBundle, OutputChunk, OutputAsset } from "rollup"; jest.mock('../src/common', () => ({ getCommonMetadata: jest.fn(), From 9a080787c2d0a6db85843471de06cad5323a89bd Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 16:02:22 +0700 Subject: [PATCH 05/10] fix tests failing in ci because of blob not global in node 16 --- src/viteBuildStatsPlugin.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/viteBuildStatsPlugin.ts b/src/viteBuildStatsPlugin.ts index e97d100..39fc1f5 100644 --- a/src/viteBuildStatsPlugin.ts +++ b/src/viteBuildStatsPlugin.ts @@ -1,5 +1,6 @@ import { type Plugin } from 'vite'; import { NormalizedOutputOptions, OutputBundle } from 'rollup'; +import { Blob } from 'node:buffer'; import type { ViteBuildData, ViteBundleStats } from './types'; import { getCommonMetadata, sendBuildData } from './common'; From 8b763487ddcc418c51b3b65b988a76aa7a0ce38f Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 16:15:31 +0700 Subject: [PATCH 06/10] update readme and examples --- README.md | 6 ++++++ examples/vite.json | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index be5b549..4c85af8 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,12 @@ or for Vite: viteBuildStatsPlugin('vite-build-extraordinaire'); ``` +Wait, there's even more! If you are limiting the bootstrap chunk size of your js bundle (see [anti-chonk](https://www.npmjs.com/package/vite-plugin-anti-chonk)), then you can pass that limit here as well. This will help you track how this limit has changed on your project. + +```javascript +viteBuildStatsPlugin('vite-build-extraordinaire', 1000); // 1 mega byte +``` + ## The F5 Experience: Because Waiting is So Last Year What is the F5 Experience? have a read [here](https://beerandserversdontmix.com/2024/08/15/an-introduction-to-the-f5-experience/) diff --git a/examples/vite.json b/examples/vite.json index 4578cb0..5db4da3 100644 --- a/examples/vite.json +++ b/examples/vite.json @@ -26,6 +26,9 @@ "v8Version": "9.4.146.24", "viteVersion": "4.0.0", "commitSha": "a1b2c3d4e5f678901234567890abcdef12345678", - "customIdentifier": "build-job-12345" + "customIdentifier": "build-job-12345", + "bundleStats": { + "bootstrapChunkSizeBytes": 1000000, + "bootstrapChunkSizeLimitBytes": 2500000 + } } - \ No newline at end of file From 07aced947b6e25512b1a3882c2372d21d69a4644 Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 16:17:50 +0700 Subject: [PATCH 07/10] make chunk size field optional --- src/types.ts | 2 +- src/viteBuildStatsPlugin.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 0175e2c..9b5f358 100644 --- a/src/types.ts +++ b/src/types.ts @@ -30,7 +30,7 @@ export interface WebpackBuildData extends CommonMetadata { } export interface ViteBundleStats { - bootstrapChunkSizeBytes: number + bootstrapChunkSizeBytes?: number bootstrapChunkSizeLimitBytes?: number } diff --git a/src/viteBuildStatsPlugin.ts b/src/viteBuildStatsPlugin.ts index 39fc1f5..82bfaea 100644 --- a/src/viteBuildStatsPlugin.ts +++ b/src/viteBuildStatsPlugin.ts @@ -11,7 +11,7 @@ export function viteBuildStatsPlugin( ): Plugin { let buildStart: number; let buildEnd: number; - let bootstrapChunkSizeBytes: number; + let bootstrapChunkSizeBytes: number | undefined = undefined; let rollupVersion: string | undefined = undefined; return { From dc9b93683f7a6ee0a3e7ffedd20c6a6d64bf4fd5 Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 18:15:18 +0700 Subject: [PATCH 08/10] wrap plugin logic in try catch --- src/viteBuildStatsPlugin.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/viteBuildStatsPlugin.ts b/src/viteBuildStatsPlugin.ts index 82bfaea..bf63d47 100644 --- a/src/viteBuildStatsPlugin.ts +++ b/src/viteBuildStatsPlugin.ts @@ -27,10 +27,14 @@ export function viteBuildStatsPlugin( outputOptions: NormalizedOutputOptions, outputBundle: OutputBundle ) => { - for (const [_, bundle] of Object.entries(outputBundle)) { - if (bundle.name === 'bootstrap' && bundle.type === 'chunk') { - bootstrapChunkSizeBytes = new Blob([bundle.code]).size; + try { + for (const [_, bundle] of Object.entries(outputBundle)) { + if (bundle.name === 'bootstrap' && bundle.type === 'chunk') { + bootstrapChunkSizeBytes = new Blob([bundle.code]).size; + } } + } catch (err) { + console.warn('Failed to measure bootstrap chunk size because of error', err) } }, closeBundle: async function () { From 23f6af207e4a8e94242339305248858ef90d5c6c Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 18:30:20 +0700 Subject: [PATCH 09/10] refactor tests & add more cases --- tests/utils/test-data-generator.ts | 45 +++++++++++++++++ tests/viteBuildStatsPlugin.spec.ts | 77 +++++++++++++----------------- 2 files changed, 79 insertions(+), 43 deletions(-) create mode 100644 tests/utils/test-data-generator.ts diff --git a/tests/utils/test-data-generator.ts b/tests/utils/test-data-generator.ts new file mode 100644 index 0000000..cc57b89 --- /dev/null +++ b/tests/utils/test-data-generator.ts @@ -0,0 +1,45 @@ +import { OutputAsset, OutputBundle, OutputChunk } from "rollup"; + +export function generateViteOutputBundleData(includeBootstrapChunk: boolean): OutputBundle { + const bootstrapChunk: OutputChunk = { + name: 'bootstrap', + type: 'chunk', + code: 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + + 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + } as unknown as OutputChunk; + + const nonBootstrapChunkA: OutputChunk = { + name: 'notBootstrapA', + type: 'chunk', + code: 'random sentence to pass my time' + } as unknown as OutputChunk; + + const nonBootstrapChunkB: OutputChunk = { + name: 'notBootstrapB', + type: 'chunk', + code: 'random sentence to pass my time again' + } as unknown as OutputChunk; + + const assetNamedBootstrap: OutputAsset = { + name: 'bootstrap', + fileName: 'bootstrap.jpg', + type: 'asset', + source: '../../assets/bootstrap.jpg', + needsCodeReference: false + }; + + const bundle = { + 'a-not-bootstrap.js': nonBootstrapChunkA, + 'b-not-bootstrap.js': nonBootstrapChunkB, + 'bootstrap.jpg': assetNamedBootstrap + } + + if (includeBootstrapChunk) { + bundle['bootstrap.xyz123.js'] = bootstrapChunk + } + + return bundle; +} diff --git a/tests/viteBuildStatsPlugin.spec.ts b/tests/viteBuildStatsPlugin.spec.ts index acd9152..92b0671 100644 --- a/tests/viteBuildStatsPlugin.spec.ts +++ b/tests/viteBuildStatsPlugin.spec.ts @@ -1,8 +1,9 @@ -import { NormalizedOutputOptions, OutputBundle, OutputChunk, OutputAsset } from "rollup"; +import { NormalizedOutputOptions, OutputBundle } from "rollup"; import { viteBuildStatsPlugin } from '../src'; import type { CommonMetadata, ViteBuildData } from '../src/types'; import { getCommonMetadata, sendBuildData } from '../src/common'; +import { generateViteOutputBundleData } from "./utils/test-data-generator"; jest.mock('../src/common', () => ({ getCommonMetadata: jest.fn(), @@ -14,45 +15,6 @@ const mockedGetCommonMetadata = getCommonMetadata as jest.MockedFunction< >; const mockedSendBuildData = sendBuildData as jest.MockedFunction; -function generateOutputBundle(): OutputBundle { - const bootstrapChunk: OutputChunk = { - name: 'bootstrap', - type: 'chunk', - code: 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + - 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + - 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + - 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' + - 'console.log("Bygone visions of life asunder, long since quelled by newfound wonder.");' - } as unknown as OutputChunk; - - const nonBootstrapChunkA: OutputChunk = { - name: 'notBootstrapA', - type: 'chunk', - code: 'random sentence to pass my time' - } as unknown as OutputChunk; - - const nonBootstrapChunkB: OutputChunk = { - name: 'notBootstrapB', - type: 'chunk', - code: 'random sentence to pass my time again' - } as unknown as OutputChunk; - - const assetNamedBootstrap: OutputAsset = { - name: 'bootstrap', - fileName: 'bootstrap.jpg', - type: 'asset', - source: '../../assets/bootstrap.jpg', - needsCodeReference: false - }; - - return { - 'a-not-bootstrap.js': nonBootstrapChunkA, - 'bootstrap.xyz123.js': bootstrapChunk, - 'b-not-bootstrap.js': nonBootstrapChunkB, - 'bootstrap.jpg': assetNamedBootstrap - }; -} - describe('viteBuildStatsPlugin', () => { const bootstrapChunkSizeLimitKb = 2_000; const expected: ViteBuildData = { @@ -68,7 +30,7 @@ describe('viteBuildStatsPlugin', () => { jest.resetAllMocks(); }); - it('should send the correct data', async () => { + it('should send the correct data - happy path', async () => { // mock measurement global.Date = { now: jest.fn().mockReturnValueOnce(0).mockReturnValueOnce(100), @@ -77,7 +39,7 @@ describe('viteBuildStatsPlugin', () => { // mock common utils mockedGetCommonMetadata.mockReturnValue({} as CommonMetadata); mockedSendBuildData.mockReturnValue(Promise.resolve()); - const bundle = generateOutputBundle(); + const bundle = generateViteOutputBundleData(true); const plugin = viteBuildStatsPlugin('my custom identifier', bootstrapChunkSizeLimitKb); (plugin.buildStart as () => void).bind({ meta: { rollupVersion: '1.2.3' } })(); @@ -89,6 +51,35 @@ describe('viteBuildStatsPlugin', () => { expect(mockedSendBuildData).toBeCalledWith(expected); }); + it('should send the correct data - bootstrap chunk not found', async () => { + // mock measurement + global.Date = { + now: jest.fn().mockReturnValueOnce(0).mockReturnValueOnce(100), + } as unknown as typeof Date; + + // mock common utils + mockedGetCommonMetadata.mockReturnValue({} as CommonMetadata); + mockedSendBuildData.mockReturnValue(Promise.resolve()); + const bundle = generateViteOutputBundleData(false); + + const plugin = viteBuildStatsPlugin('my custom identifier'); + (plugin.buildStart as () => void).bind({ meta: { rollupVersion: '1.2.3' } })(); + (plugin.generateBundle as (opts: NormalizedOutputOptions, bundle: OutputBundle) => void)({} as NormalizedOutputOptions, bundle); + (plugin.buildEnd as () => void)(); + await (plugin.closeBundle as () => Promise)(); + + const caseSpecificExpected = { + ...expected, + bundleStats: { + generateOutputBundleData: undefined, + bootstrapChunkSizeLimitBytes: undefined + } + } + + expect(mockedGetCommonMetadata).toBeCalledWith(100, 'my custom identifier'); + expect(mockedSendBuildData).toBeCalledWith(caseSpecificExpected); + }); + it('should use process.env.npm_lifecycle_event as default custom identifier', async () => { // mock measurement global.Date = { @@ -98,7 +89,7 @@ describe('viteBuildStatsPlugin', () => { // mock common utils mockedGetCommonMetadata.mockReturnValue({} as CommonMetadata); mockedSendBuildData.mockReturnValue(Promise.resolve()); - const bundle = generateOutputBundle(); + const bundle = generateViteOutputBundleData(true); // mock process object global.process = { From bd536b45a599029267f7edf366d1623e6bb6bf9a Mon Sep 17 00:00:00 2001 From: Sofen Hoque Date: Thu, 31 Oct 2024 18:30:31 +0700 Subject: [PATCH 10/10] update test file pattern --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 24ac341..f13f11e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,6 +2,6 @@ module.exports = { transform: { '^.+\\.(t|j)sx?$': 'ts-jest', }, - testRegex: '(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + testRegex: '/tests/.+\\.spec\\.(jsx?|tsx?)$', moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], };