diff --git a/packages/esbuild/src/stylable-esbuild-plugin.ts b/packages/esbuild/src/stylable-esbuild-plugin.ts index b2fc64348..99c397736 100644 --- a/packages/esbuild/src/stylable-esbuild-plugin.ts +++ b/packages/esbuild/src/stylable-esbuild-plugin.ts @@ -187,13 +187,24 @@ export const stylablePlugin = (initialPluginOptions: ESBuildOptions = {}): Plugi build.onLoad( { filter: /.*/, namespace: namespaces.jsModule }, wrapDebug('onLoad stylable module', (args) => { + let res: StylableResults; const cacheResults = checkCache(args.path); if (cacheResults) { return cacheResults; } onLoadCalled = true; - - const res = stylable.transform(args.path); + try { + res = stylable.transform(args.path); + } catch (e) { + return { + errors: [ + { + text: String(e), + }, + ], + watchFiles: [args.path], + }; + } const { errors, warnings } = esbuildEmitDiagnostics(res, diagnosticsMode); const { imports, collector } = importsCollector(res); const { cssDepth = 1, deepDependencies } = res.meta.transformCssDepth!; @@ -315,7 +326,7 @@ export const stylablePlugin = (initialPluginOptions: ESBuildOptions = {}): Plugi * process the generated bundle and optimize the css output */ build.onEnd( - wrapDebug(`onEnd generate cssInjection: ${cssInjection}`, ({ metafile }) => { + wrapDebug(`onEnd generate cssInjection: ${cssInjection}`, ({ metafile, errors }) => { transferBuildInfo(); if (!onLoadCalled) { lazyDebugPrint(); @@ -325,6 +336,9 @@ export const stylablePlugin = (initialPluginOptions: ESBuildOptions = {}): Plugi let mapping: OptimizationMapping; if (devTypes.enabled) { if (!metafile) { + if (errors.length) { + return; + } throw new Error('metafile is required for css injection'); } const absSrcDir = join(projectRoot, devTypes.srcDir); @@ -354,6 +368,9 @@ export const stylablePlugin = (initialPluginOptions: ESBuildOptions = {}): Plugi if (cssInjection === 'css') { if (!metafile) { + if (errors.length) { + return; + } throw new Error('metafile is required for css injection'); } mapping ??= buildUsageMapping(metafile, stylable); diff --git a/packages/esbuild/test/e2e/esbuild-testkit.ts b/packages/esbuild/test/e2e/esbuild-testkit.ts index c6ee5cea9..5ae618d75 100644 --- a/packages/esbuild/test/e2e/esbuild-testkit.ts +++ b/packages/esbuild/test/e2e/esbuild-testkit.ts @@ -1,7 +1,7 @@ import { dirname, join } from 'node:path'; import { readFileSync, symlinkSync, writeFileSync } from 'node:fs'; import fs from '@file-services/node'; -import { BuildContext, BuildOptions, context } from 'esbuild'; +import { BuildContext, BuildOptions, context, Plugin } from 'esbuild'; import { createTempDirectorySync, runServer } from '@stylable/e2e-test-kit'; import playwright from 'playwright-core'; @@ -21,11 +21,13 @@ export class ESBuildTestKit { buildExport, tmp = true, overrideOptions = {}, + extraPlugins = [], }: { project: string; buildExport?: string; tmp?: boolean; overrideOptions?: BuildOptions; + extraPlugins?: Array; }) { let openServerUrl: string | undefined; let buildFile = require.resolve(`@stylable/esbuild/test/e2e/${project}/build.js`); @@ -54,7 +56,7 @@ export class ESBuildTestKit { const buildContext = await run(context, (options: BuildOptions) => ({ ...options, - plugins: [...(options.plugins ?? [])], + plugins: [...(options.plugins ?? []), ...extraPlugins], absWorkingDir: projectDir, loader: { '.png': 'file', diff --git a/packages/esbuild/test/e2e/rebuild/rebuild.spec.ts b/packages/esbuild/test/e2e/rebuild/rebuild.spec.ts index 2d2f1e1f7..82036561f 100644 --- a/packages/esbuild/test/e2e/rebuild/rebuild.spec.ts +++ b/packages/esbuild/test/e2e/rebuild/rebuild.spec.ts @@ -21,4 +21,21 @@ describe('Stylable ESBuild plugin rebuild on change', function () { const css2 = read('dist/index.js'); expect(css2, 'color after change').to.includes('color: green'); }); + + it('should stay alive after error', async function () { + const { context, read, write } = await tk.build({ + project: 'rebuild', + tmp: true, + }); + const css1 = read('dist/index.js'); + expect(css1, 'initial color').to.includes('color: red'); + await context.watch(); + await sleep(2222); + write('a.st.css', `.root{}}}}}`); + await sleep(2222); + write('a.st.css', `.root{color: green}`); + await sleep(2222); + const css2 = read('dist/index.js'); + expect(css2, 'color after change').to.includes('color: green'); + }); });