From 9c659cebf1fc05ad9a87e9a0071f2895f76a3460 Mon Sep 17 00:00:00 2001 From: Lazy <2818242447@qq.com> Date: Tue, 12 May 2026 20:18:27 +0800 Subject: [PATCH] fix: handle fatal rollup watch events --- src/index.ts | 9 ++++--- test/watch.test.ts | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 test/watch.test.ts diff --git a/src/index.ts b/src/index.ts index 2121a089..6d061d64 100644 --- a/src/index.ts +++ b/src/index.ts @@ -463,8 +463,8 @@ export class Bundler { // Since we only output to `.js` now // Probably remove it in the future .replace(/\[ext\]/, '.js') - - if (rollupFormat === 'esm') { + + if (rollupFormat === 'esm') { fileName = fileName.replace(/\[format\]/, 'esm') } @@ -629,8 +629,9 @@ export class Bundler { ) const watcher = watch(configs) watcher.on('event', (e) => { - if (e.code === 'ERROR') { - logger.error(e.error.message) + const code = e.code as string + if (code === 'ERROR' || code === 'FATAL') { + logger.error((e as { error: Error }).error.message) } }) } else { diff --git a/test/watch.test.ts b/test/watch.test.ts new file mode 100644 index 00000000..083e287d --- /dev/null +++ b/test/watch.test.ts @@ -0,0 +1,65 @@ +import { Bundler } from '../src' +import logger from '../src/logger' +import { watch } from 'rollup' + +jest.mock('rollup', () => ({ + rollup: jest.fn(), + watch: jest.fn(), +})) + +const mockWatch = watch as jest.Mock + +describe('watch mode', () => { + beforeEach(() => { + mockWatch.mockReset() + jest.spyOn(logger, 'error').mockImplementation(() => {}) + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + + it('logs fatal Rollup watch events', async () => { + const error = new Error('watch failed') + + mockWatch.mockReturnValue({ + on(event: string, listener: (payload: any) => void) { + expect(event).toBe('event') + listener({ code: 'FATAL', error }) + }, + }) + + await new Bundler( + { input: 'index.js' }, + { + configFile: false, + logLevel: 'quiet', + rootDir: __dirname, + } + ).run({ watch: true }) + + expect(logger.error).toHaveBeenCalledWith('watch failed') + }) + + it('keeps logging normal Rollup watch errors', async () => { + const error = new Error('build failed') + + mockWatch.mockReturnValue({ + on(event: string, listener: (payload: any) => void) { + expect(event).toBe('event') + listener({ code: 'ERROR', error }) + }, + }) + + await new Bundler( + { input: 'index.js' }, + { + configFile: false, + logLevel: 'quiet', + rootDir: __dirname, + } + ).run({ watch: true }) + + expect(logger.error).toHaveBeenCalledWith('build failed') + }) +})