next.js
261922df - Show generated code from loaders in parse error messages (#89898)

Commit
52 days ago
Show generated code from loaders in parse error messages (#89898) ## What? When a webpack/turbopack loader produces broken code, error messages now display **both** the original source and the generated code with source map information, making it much easier to debug loader issues. ## Why? Previously, when loaders returned invalid code, error messages only showed the original source file (after source-map remapping). Users had no way to see what the loader actually generated, making it hard to diagnose why the code failed to parse. Showing both sides gives full context about what went wrong. ## How? ### Turbopack Core (`turbopack-core`) - **`Source::description()`** — New method on the `Source` trait providing human-readable descriptions of where code comes from. Implemented across all source types (`FileSource`, `VirtualSource`, `WebpackLoadersProcessedAsset`, `PostCssTransformedAsset`, etc.), producing chains like `"loaders [sass-loader] transform of file content of ./styles.scss"`. - **`AdditionalIssueSource`** — New struct to hold a labeled source location. The `Issue` trait gains an `additional_sources()` method so issues can expose supplementary code frames. - **`GeneratedCodeSource`** — A wrapper that strips `GenerateSourceMap` support from a source, ensuring the *generated* code is displayed as-is rather than being remapped back to the original. - **`IssueSource::to_generated_code_source()`** — Helper that detects sources implementing `GenerateSourceMap` and wraps them in `GeneratedCodeSource` for display. Used by `AnalyzeIssue` and `ParsingIssue` to automatically attach generated code frames. ### Error Formatting - **`turbopack-cli-utils`** — Renders additional sources in CLI issue output. - **`format-issue.ts`** — Renders additional sources in the browser error overlay. Extracted `formatSourceCodeFrame()` helper to deduplicate code-frame rendering between primary and additional sources. - Long-line truncation (e.g. minified CSS from SCSS) is handled natively by the Rust-based `codeFrameColumns` implementation. ### Type Definitions - Added `SourcePosition`, `IssueSource`, and `AdditionalIssueSource` interfaces to TypeScript types. - Updated `PlainSource` (added `file_path`), `PlainIssue` (added `additional_sources`), and NAPI bindings to pass the data through. ### Test Coverage - **E2e tests** (`test/e2e/webpack-loader-parse-error/`) with custom broken JS and CSS loaders, covering all 4 modes: - **Development (Turbopack)** — Verifies parse errors show both original and generated code via browser error overlay - **Development (Webpack)** — Verifies error overlay shows the parse error (webpack doesn't support additional sources) - **Production (Turbopack)** — Verifies build failure output with full error extraction and inline snapshots - **Production (Webpack)** — Verifies build failure output with inline snapshots - Updated `test/development/sass-error/` snapshot to include the new generated code frame for minified SCSS output. ### Example Output When a loader produces broken code, users now see: ``` ⨯ ./app/data.broken.js:3:1 Parsing ecmascript source code failed 1 | // This file will be processed by broken-js-loader 2 | // The loader will return invalid JavaScript with a source map > 3 | export default function Data() { | ^ 4 | return <div>original source content</div> 5 | } 6 | Expected '</', got '{' Generated code of loaders [./broken-js-loader.js] transform of file content of app/data.broken.js: ./app/data.broken.js:3:46 1 | // Generated by broken-js-loader 2 | export default function Page() { > 3 | return <div>this is intentionally broken {{{ invalid jsx | ^ 4 | } 5 | Import trace: Server Component: ./app/data.broken.js ./app/page.js ``` --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com> Co-authored-by: Luke Sandberg <lukeisandberg@gmail.com>
Author
Parents
Loading