forked from vercel/next.js
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve client-only imported in external package error (vercel#45484)
Currently if an external package imports `'client-only'` it's difficult to figure out why the error occured. This change adds an explanation of which import caused the error. The errors in the images are from using `<style jsx>` in a Server Component. Before, runtime error on the server ![image](https://user-images.githubusercontent.com/25056922/216080617-9eebf99e-2899-4d7e-80b6-ef7ded0831ce.png) After, webpack error with added stack trace ![image](https://user-images.githubusercontent.com/25056922/216303311-05c2f3ca-2857-4fe7-b55c-caaccf5f46bb.png) Fixes NEXT-409 ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] [e2e](https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs) tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md) ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm build && pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md)
- Loading branch information
1 parent
2e4ef53
commit 39e1670
Showing
10 changed files
with
236 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
packages/next/src/build/webpack/loaders/next-invalid-import-error-loader.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export default function nextInvalidImportErrorLoader(this: any) { | ||
const { message } = this.getOptions() | ||
throw new Error(message) | ||
} |
46 changes: 46 additions & 0 deletions
46
packages/next/src/build/webpack/plugins/wellknown-errors-plugin/getModuleTrace.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import type { webpack } from 'next/dist/compiled/webpack/webpack' | ||
import { relative } from 'path' | ||
|
||
export function formatModule(compiler: webpack.Compiler, module: any) { | ||
return relative(compiler.context, module.resource).replace(/\?.+$/, '') | ||
} | ||
|
||
export function getImportTraceForOverlay( | ||
compiler: webpack.Compiler, | ||
moduleTrace: any[] | ||
) { | ||
return moduleTrace | ||
.map((m) => (m.resource ? ' ' + formatModule(compiler, m) : '')) | ||
.filter(Boolean) | ||
.join('\n') | ||
} | ||
|
||
export function getModuleTrace( | ||
module: any, | ||
compilation: webpack.Compilation, | ||
compiler: webpack.Compiler | ||
) { | ||
// Get the module trace: | ||
// https://cs.github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/lib/stats/DefaultStatsFactoryPlugin.js#L414 | ||
const visitedModules = new Set() | ||
const moduleTrace = [] | ||
|
||
let current = module | ||
let isPagesDir = false | ||
while (current) { | ||
if (visitedModules.has(current)) break | ||
if (/[\\/]pages/.test(current.resource.replace(compiler.context, ''))) { | ||
isPagesDir = true | ||
} | ||
visitedModules.add(current) | ||
moduleTrace.push(current) | ||
const origin = compilation.moduleGraph.getIssuer(current) | ||
if (!origin) break | ||
current = origin | ||
} | ||
|
||
return { | ||
moduleTrace, | ||
isPagesDir, | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
...ges/next/src/build/webpack/plugins/wellknown-errors-plugin/parseNextInvalidImportError.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import type { webpack } from 'next/dist/compiled/webpack/webpack' | ||
import { formatModule, getModuleTrace } from './getModuleTrace' | ||
import { SimpleWebpackError } from './simpleWebpackError' | ||
|
||
export function getNextInvalidImportError( | ||
err: Error, | ||
module: any, | ||
compilation: webpack.Compilation, | ||
compiler: webpack.Compiler | ||
): SimpleWebpackError | false { | ||
try { | ||
if ( | ||
!module.loaders.find((loader: any) => | ||
loader.loader.includes('next-invalid-import-error-loader.js') | ||
) | ||
) { | ||
return false | ||
} | ||
|
||
const { moduleTrace } = getModuleTrace(module, compilation, compiler) | ||
|
||
let importTrace: string[] = [] | ||
let firstExternalModule: any | ||
for (let i = moduleTrace.length - 1; i >= 0; i--) { | ||
const mod = moduleTrace[i] | ||
if (!mod.resource) continue | ||
|
||
if (!mod.resource.includes('node_modules/')) { | ||
importTrace.unshift(formatModule(compiler, mod)) | ||
} else { | ||
firstExternalModule = mod | ||
break | ||
} | ||
} | ||
|
||
let invalidImportMessage = '' | ||
if (firstExternalModule) { | ||
let formattedExternalFile = | ||
firstExternalModule.resource.split('node_modules') | ||
formattedExternalFile = | ||
formattedExternalFile[formattedExternalFile.length - 1] | ||
|
||
invalidImportMessage += `\n\nThe error was caused by importing '${formattedExternalFile.slice( | ||
1 | ||
)}' in '${importTrace[0]}'.` | ||
} | ||
|
||
return new SimpleWebpackError( | ||
importTrace[0], | ||
err.message + | ||
invalidImportMessage + | ||
(importTrace.length > 0 | ||
? `\n\nImport trace for requested module:\n${importTrace | ||
.map((mod) => ' ' + mod) | ||
.join('\n')}` | ||
: '') | ||
) | ||
} catch { | ||
return false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
...pment/acceptance-app/fixtures/rsc-build-errors/app/server-with-errors/styled-jsx/comp1.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { Comp2 } from './comp2' | ||
|
||
export function Comp1() { | ||
return <Comp2 /> | ||
} |
11 changes: 11 additions & 0 deletions
11
...pment/acceptance-app/fixtures/rsc-build-errors/app/server-with-errors/styled-jsx/comp2.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export function Comp2() { | ||
return ( | ||
<div> | ||
<style jsx>{` | ||
p { | ||
color: red; | ||
} | ||
`}</style> | ||
</div> | ||
) | ||
} |
13 changes: 4 additions & 9 deletions
13
...opment/acceptance-app/fixtures/rsc-build-errors/app/server-with-errors/styled-jsx/page.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,6 @@ | ||
'use client' | ||
import { Comp1 } from './comp1' | ||
|
||
export default function Page() { | ||
return ( | ||
<div> | ||
<style jsx>{` | ||
p { | ||
color: red; | ||
} | ||
`}</style> | ||
</div> | ||
) | ||
return <Comp1 /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters