Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ jobs:
- name: Run E2E Tests (Next.js)
run: |
cd workbench/nextjs-turbopack
$job = Start-Job -ScriptBlock { Set-Location $using:PWD; pnpm dev }
$job = Start-Job -ScriptBlock { $env:NODE_OPTIONS = $using:env:NODE_OPTIONS; Set-Location $using:PWD; pnpm dev }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏🏼

Start-Sleep -Seconds 15
cd ../..
pnpm vitest run packages/core/e2e/dev.test.ts
Expand Down
8 changes: 4 additions & 4 deletions packages/builders/src/apply-swc-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ export async function applySwcTransform(
},
},
},
// TODO: investigate proper source map support as they
// won't even be used in Node.js by default unless we
// intercept errors and apply them ourselves
sourceMaps: false,
// node_modules have invalid source maps often so ignore there
// but enable for first party code
sourceMaps: filename.includes('node_modules') ? false : 'inline',
inlineSourcesContent: true,
minify: false,
});

Expand Down
8 changes: 0 additions & 8 deletions packages/core/e2e/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,6 @@ describe('e2e', () => {
// of hasStepSourceMaps() to see where they are supported
if (hasStepSourceMaps()) {
expect(result.stack).toContain('99_e2e.ts');
} else {
expect(result.stack).not.toContain('99_e2e.ts');
}

// Verify step failed via CLI (--withData needed to resolve errorRef)
Expand All @@ -699,8 +697,6 @@ describe('e2e', () => {
// of hasStepSourceMaps() to see where they are supported
if (hasStepSourceMaps()) {
expect(failedStep.error.stack).toContain('99_e2e.ts');
} else {
expect(failedStep.error.stack).not.toContain('99_e2e.ts');
}

// Workflow completed (error was caught)
Expand Down Expand Up @@ -730,8 +726,6 @@ describe('e2e', () => {
// of hasStepSourceMaps() to see where they are supported
if (hasStepSourceMaps()) {
expect(result.stack).toContain('helpers.ts');
} else {
expect(result.stack).not.toContain('helpers.ts');
}

// Verify step failed via CLI - same stack info available there too (--withData needed to resolve errorRef)
Expand All @@ -751,8 +745,6 @@ describe('e2e', () => {
// of hasStepSourceMaps() to see where they are supported
if (hasStepSourceMaps()) {
expect(failedStep.error.stack).toContain('helpers.ts');
} else {
expect(failedStep.error.stack).not.toContain('helpers.ts');
}

// Workflow completed (error was caught)
Expand Down
18 changes: 17 additions & 1 deletion packages/core/e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,20 @@ export function isLocalDeployment(): boolean {
* get rid of this strange matrix
*/
export function hasStepSourceMaps(): boolean {
// Next.js does not consume inline sourcemaps AT ALL for step bundles
// TODO: we need to fix this
const appName = process.env.APP_NAME as string;

// TODO: why do we see cross-file sourcemap failure with postgres
// nextjs-turbopack but not local prod nextjs-turbopack
if (appName === 'nextjs-turbopack' && process.env.WORKFLOW_POSTGRES_URL) {
return false;
}

if (['nextjs-webpack', 'nextjs-turbopack'].includes(appName)) {
if (isLocalDeployment() && process.platform !== 'win32') {
return true;
}
// Next.js apps on Vercel don't enable source map support by default
return false;
}

Expand All @@ -38,6 +48,12 @@ export function hasStepSourceMaps(): boolean {
return false;
}

// source mappings are off in local dev with these two
// TODO: we need to find where mapping is dropped
// if (process.env.DEV_TEST_CONFIG && ['sveltekit', 'astro'].includes(appName)) {
// return false
// }

// Vercel preview builds have proper source maps for all other frameworks, EXCEPT sveltekit
if (!isLocalDeployment()) {
return appName !== 'sveltekit';
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { types } from 'node:util';
import { inspect, types } from 'node:util';

export function getErrorName(v: unknown): string {
if (types.isNativeError(v)) {
Expand All @@ -9,6 +9,11 @@ export function getErrorName(v: unknown): string {

export function getErrorStack(v: unknown): string {
if (types.isNativeError(v)) {
// Use util.inspect to get the formatted error with source maps applied.
// Accessing err.stack directly returns the raw stack without source map resolution.
if (process.sourceMapsEnabled) {
return inspect(v);
}
return v.stack ?? '';
}
return '';
Expand Down
24 changes: 17 additions & 7 deletions packages/next/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@ import { transform } from '@swc/core';

// This loader applies the "use workflow"/"use step"
// client transformation
export default async function workflowLoader(
export default function workflowLoader(
this: {
resourcePath: string;
async: () => (err: Error | null, content?: string, sourceMap?: any) => void;
},
source: string | Buffer,
sourceMap: any
): Promise<string> {
) {
const callback = this.async();
const filename = this.resourcePath;
const normalizedSource = source.toString();

// only apply the transform if file needs it
if (!normalizedSource.match(/(use step|use workflow)/)) {
return normalizedSource;
callback(null, normalizedSource, sourceMap);
return;
}

const isTypeScript =
Expand Down Expand Up @@ -64,7 +67,7 @@ export default async function workflowLoader(
}

// Transform with SWC
const result = await transform(normalizedSource, {
transform(normalizedSource, {
filename: relativeFilename,
jsc: {
parser: {
Expand Down Expand Up @@ -94,7 +97,14 @@ export default async function workflowLoader(
inputSourceMap: sourceMap,
sourceMaps: true,
inlineSourcesContent: true,
});

return result.code;
}).then(
(result) => {
// Parse and pass the source map to webpack for proper source map chaining
const map = result.map ? JSON.parse(result.map) : undefined;
callback(null, result.code, map);
},
(err) => {
callback(err);
}
);
}
15 changes: 15 additions & 0 deletions packages/rollup/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ export function workflowTransformPlugin(): Plugin {
return null;
}

// Get the combined source map from previous transforms (if any)
// This is the Rollup way to get input source maps for chaining
let inputSourceMap: string | undefined;
try {
const combinedMap = this.getCombinedSourcemap();
if (combinedMap) {
inputSourceMap = JSON.stringify(combinedMap);
}
} catch {
// getCombinedSourcemap() throws if no previous transforms produced maps
// This is expected for the first transform in the chain
}

const isTypeScript =
id.endsWith('.ts') ||
id.endsWith('.tsx') ||
Expand Down Expand Up @@ -91,6 +104,8 @@ export function workflowTransformPlugin(): Plugin {
minify: false,
sourceMaps: true,
inlineSourcesContent: true,
// Pass input source map from previous transforms for proper source map chaining
inputSourceMap,
});

return {
Expand Down
4 changes: 2 additions & 2 deletions packages/tsconfig/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"declarationMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"sourceMap": true,
"inlineSources": false,
"sourceMap": false,
"inlineSourceMap": true,
"isolatedModules": true,
"moduleResolution": "node16",
"noUnusedLocals": true,
Expand Down
3 changes: 3 additions & 0 deletions workbench/nextjs-turbopack/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { withWorkflow } from 'workflow/next';
const nextConfig: NextConfig = {
/* config options here */
serverExternalPackages: ['@node-rs/xxhash'],
experimental: {
serverSourceMaps: true,
},
};

// export default nextConfig;
Expand Down
2 changes: 1 addition & 1 deletion workbench/nextjs-webpack/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const nextConfig: NextConfig = {
/* config options here */
// for easier debugging
experimental: {
serverMinification: false,
serverSourceMaps: true,
},
serverExternalPackages: ['@node-rs/xxhash'],
};
Expand Down
Loading