Skip to content

Commit f40532a

Browse files
fix(builders): Inline Next.js pseudo‑packages and strip server-only/client-only requires in workflow bundles (#911)
* Fix bundling behavior for dynamic imports and server-only, client-only imports * Generate changeset * Filter tsconfig to only pull in code from within the current working directory(workflow dir) * Rewrite server-only and client-only * add additional pseudo directives * upmerge * fix failing unit test
1 parent 3dde14d commit f40532a

8 files changed

Lines changed: 488 additions & 6 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@workflow/builders": patch
3+
---
4+
5+
Fix workflow bundle to inline pseudo-packages instead of marking them external

‎packages/builders/src/base-builder.ts‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
} from './apply-swc-transform.js';
1515
import { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';
1616
import { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';
17+
import { createPseudoPackagePlugin } from './pseudo-package-esbuild-plugin.js';
1718
import { createSwcPlugin } from './swc-esbuild-plugin.js';
1819
import type { WorkflowConfig } from './types.js';
1920
import { extractWorkflowGraphs } from './workflows-extractor.js';
@@ -371,6 +372,9 @@ export abstract class BaseBuilder {
371372
// occur in deeply nested function calls across multiple files.
372373
sourcemap: 'inline',
373374
plugins: [
375+
// Handle pseudo-packages like 'server-only' and 'client-only' by providing
376+
// empty modules. Must run first to intercept these before other resolution.
377+
createPseudoPackagePlugin(),
374378
createSwcPlugin({
375379
mode: 'step',
376380
entriesToBundle: externalizeNonSteps
@@ -539,6 +543,9 @@ export abstract class BaseBuilder {
539543
'.cjs',
540544
],
541545
plugins: [
546+
// Handle pseudo-packages like 'server-only' and 'client-only' by providing
547+
// empty modules. Must run first to intercept these before other resolution.
548+
createPseudoPackagePlugin(),
542549
createSwcPlugin({
543550
mode: 'workflow',
544551
workflowManifest,
@@ -547,8 +554,14 @@ export abstract class BaseBuilder {
547554
// happens first, preventing false positives on Node.js imports in unused code paths
548555
createNodeModuleErrorPlugin(),
549556
],
550-
// External packages that should not be bundled (e.g., server-only, client-only for Next.js)
551-
external: this.config.externalPackages || [],
557+
// NOTE: We intentionally do NOT use the external option here for workflow bundles.
558+
// When packages are marked external with format: 'cjs', esbuild generates require() calls.
559+
// However, the workflow VM (vm.runInContext) does not have require() defined - it only
560+
// provides module.exports and exports. External packages would fail at runtime with:
561+
// ReferenceError: require is not defined
562+
// Instead, we bundle everything and rely on:
563+
// - createPseudoPackagePlugin() to handle server-only/client-only with empty modules
564+
// - createNodeModuleErrorPlugin() to catch Node.js builtin imports at build time
552565
});
553566
const interimBundle = await interimBundleCtx.rebuild();
554567

‎packages/builders/src/index.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export {
1010
export { STEP_QUEUE_TRIGGER, WORKFLOW_QUEUE_TRIGGER } from './constants.js';
1111
export { createDiscoverEntriesPlugin } from './discover-entries-esbuild-plugin.js';
1212
export { createNodeModuleErrorPlugin } from './node-module-esbuild-plugin.js';
13+
export {
14+
createPseudoPackagePlugin,
15+
PSEUDO_PACKAGES,
16+
} from './pseudo-package-esbuild-plugin.js';
1317
export { NORMALIZE_REQUEST_CODE } from './request-converter.js';
1418
export { StandaloneBuilder } from './standalone.js';
1519
export { createSwcPlugin } from './swc-esbuild-plugin.js';

0 commit comments

Comments
 (0)