Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add editor links to RSC build error #45179

Merged
merged 27 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7f0c9b7
Add error name
Jan 23, 2023
ccf20a9
Move open editor to helper hook
Jan 23, 2023
560ecc3
Add component that converts file paths to links
Jan 23, 2023
2b5912b
Use new component for build errors
Jan 23, 2023
7459956
Add test
Jan 23, 2023
a691ce4
Merge branch 'canary' into rsc-error-editor-links
hanneslund Jan 23, 2023
999b644
Fix test
Jan 23, 2023
9563a91
Merge branch 'canary' into rsc-error-editor-links
hanneslund Jan 23, 2023
da49b50
Try restarting next
Jan 23, 2023
769cf1b
Add snapshot
Jan 23, 2023
95e52fd
Merge branch 'canary' into rsc-error-editor-links
hanneslund Jan 23, 2023
8af3179
Update snapshot
Jan 23, 2023
bb38829
Remove restart next in test
Jan 23, 2023
43f10da
fix?
Jan 23, 2023
ca3b23a
Merge branch 'canary' into rsc-error-editor-links
ijjk Jan 23, 2023
9299659
Fix test todos
Jan 24, 2023
b66c7de
Merge branch 'canary' into rsc-error-editor-links
hanneslund Jan 24, 2023
d1f0692
Wait for redboxheader
Jan 24, 2023
d911289
Merge branch 'canary' of https://github.com/hanneslund/next.js into r…
Jan 24, 2023
2111183
Refactor to function and find links on full content
Jan 24, 2023
bd3a3c0
Merge branch 'canary' into rsc-error-editor-links
hanneslund Jan 24, 2023
8494c44
add check to test
Jan 24, 2023
d32637b
Update check
Jan 24, 2023
b76ef65
Port rsc tests to acceptance-app to use the helpers
Jan 24, 2023
97495f6
Fix lint
Jan 24, 2023
21e623b
Merge branch 'canary' of https://github.com/hanneslund/next.js into r…
Jan 24, 2023
54d4831
Merge branch 'canary' into rsc-error-editor-links
kodiakhq[bot] Jan 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ export function getRscError(

const error = new SimpleWebpackError(
fileName,
formattedError[0] +
'ReactServerComponentsError:\n' +
formattedError[0] +
formattedError[1] +
moduleTrace
.map((m) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as React from 'react'
import { StackFrame } from 'next/dist/compiled/stacktrace-parser'
import stripAnsi from 'next/dist/compiled/strip-ansi'
import { getFrameSource } from '../../helpers/stack-frame'
import { useOpenInEditor } from '../../helpers/use-open-in-editor'

export type CodeFrameProps = { stackFrame: StackFrame; codeFrame: string }

Expand Down Expand Up @@ -44,25 +45,11 @@ export const CodeFrame: React.FC<CodeFrameProps> = function CodeFrame({
})
}, [formattedFrame])

const open = React.useCallback(() => {
const params = new URLSearchParams()
for (const key in stackFrame) {
params.append(key, ((stackFrame as any)[key] ?? '').toString())
}

self
.fetch(
`${
process.env.__NEXT_ROUTER_BASEPATH || ''
}/__nextjs_launch-editor?${params.toString()}`
)
.then(
() => {},
() => {
console.error('There was an issue opening this code in your editor.')
}
)
}, [stackFrame])
const open = useOpenInEditor({
file: stackFrame.file,
lineNumber: stackFrame.lineNumber,
column: stackFrame.column,
})

// TODO: make the caret absolute
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Anser from 'next/dist/compiled/anser'
import * as React from 'react'
import { WithOpenInEditorLinks } from '../WithOpenInEditorLinks'

export type TerminalProps = { content: string }

Expand Down Expand Up @@ -29,7 +30,7 @@ export const Terminal: React.FC<TerminalProps> = function Terminal({
: undefined),
}}
>
{entry.content}
<WithOpenInEditorLinks content={entry.content} />
</span>
))}
</pre>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react'
import { useOpenInEditor } from '../../helpers/use-open-in-editor'

function EditorLink({ file }: { file: string }) {
const open = useOpenInEditor({
file,
column: 1,
lineNumber: 1,
})

return (
<div
data-with-open-in-editor-link
tabIndex={10}
role={'link'}
onClick={open}
title={'Click to open in your editor'}
>
{file}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
<polyline points="15 3 21 3 21 9"></polyline>
<line x1="10" y1="14" x2="21" y2="3"></line>
</svg>
</div>
)
}

export function WithOpenInEditorLinks({ content }: { content: string }) {
if (/ReactServerComponentsError:/.test(content)) {
// It's an RSC Build Error
const lines = content.split('\n')

// Grab the lines at the end containing the files
const files = []
while (/app\/.+\./.test(lines[lines.length - 1])) {
const file = lines.pop()!.trim()
files.unshift(file)
}

return (
<>
{lines.join('\n')}
{files.map((file) => (
<EditorLink key={file} file={file} />
))}
</>
)
}

return <>{content}</>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { WithOpenInEditorLinks } from './WithOpenInEditorLinks'
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { noop as css } from '../../helpers/noop-template'

const styles = css`
[data-with-open-in-editor-link] svg {
width: auto;
height: var(--size-font-small);
margin-left: var(--size-gap);
}
[data-with-open-in-editor-link] {
cursor: pointer;
}
[data-with-open-in-editor-link]:hover {
text-decoration: underline dotted;
}
[data-with-open-in-editor-link] {
margin-left: var(--size-gap-double);
}
`

export { styles }
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
getFrameSource,
type OriginalStackFrame,
} from '../../helpers/stack-frame'
import { useOpenInEditor } from '../../helpers/use-open-in-editor'

export const CallStackFrame: React.FC<{ frame: OriginalStackFrame }> =
function CallStackFrame({ frame }) {
Expand All @@ -12,30 +13,15 @@ export const CallStackFrame: React.FC<{ frame: OriginalStackFrame }> =

const f: StackFrame = frame.originalStackFrame ?? frame.sourceStackFrame
const hasSource = Boolean(frame.originalCodeFrame)

const open = React.useCallback(() => {
if (!hasSource) return

const params = new URLSearchParams()
for (const key in f) {
params.append(key, ((f as any)[key] ?? '').toString())
}

self
.fetch(
`${
process.env.__NEXT_ROUTER_BASEPATH || ''
}/__nextjs_launch-editor?${params.toString()}`
)
.then(
() => {},
() => {
console.error(
'There was an issue opening this code in your editor.'
)
const open = useOpenInEditor(
hasSource
? {
file: f.file,
lineNumber: f.lineNumber,
column: f.column,
}
)
}, [hasSource, f])
: undefined
)

return (
<div data-nextjs-call-stack-frame>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useCallback } from 'react'

export function useOpenInEditor({
file,
lineNumber,
column,
}: {
file?: string | null
lineNumber?: number | null
column?: number | null
} = {}) {
const openInEditor = useCallback(() => {
if (file == null || lineNumber == null || column == null) return

const params = new URLSearchParams()
params.append('file', file)
params.append('lineNumber', String(lineNumber))
params.append('column', String(column))

self
.fetch(
`${
process.env.__NEXT_ROUTER_BASEPATH || ''
}/__nextjs_launch-editor?${params.toString()}`
)
.then(
() => {},
() => {
console.error('There was an issue opening this code in your editor.')
}
)
}, [file, lineNumber, column])

return openInEditor
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { styles as leftRightDialogHeader } from '../components/LeftRightDialogHe
import { styles as overlay } from '../components/Overlay/styles'
import { styles as terminal } from '../components/Terminal/styles'
import { styles as toast } from '../components/Toast'
import { styles as openInEditorLinks } from '../components/WithOpenInEditorLinks/styles'
import { styles as buildErrorStyles } from '../container/BuildError'
import { styles as rootLayoutErrorStyles } from '../container/RootLayoutError'
import { styles as containerErrorStyles } from '../container/Errors'
Expand All @@ -22,6 +23,7 @@ export function ComponentStyles() {
${leftRightDialogHeader}
${codeFrame}
${terminal}
${openInEditorLinks}

${buildErrorStyles}
${rootLayoutErrorStyles}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ createNextDescribe(
)
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./components/Comp.js
ReactServerComponentsError:

You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://beta.nextjs.org/docs/rendering/server-and-client-components

Expand Down Expand Up @@ -91,6 +92,7 @@ createNextDescribe(
)
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./components/Comp.js
ReactServerComponentsError:

You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://beta.nextjs.org/docs/rendering/server-and-client-components

Expand Down Expand Up @@ -131,6 +133,7 @@ createNextDescribe(
)
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./components/Comp.js
ReactServerComponentsError:

You have tried to use the \\"use client\\" directive which is not supported in the pages/ directory. Read more: https://beta.nextjs.org/docs/rendering/server-and-client-components

Expand Down Expand Up @@ -171,6 +174,7 @@ createNextDescribe(
)
expect(await session.getRedboxSource()).toMatchInlineSnapshot(`
"./components/Comp.js
ReactServerComponentsError:

You have tried to use the \\"use client\\" directive which is not supported in the pages/ directory. Read more: https://beta.nextjs.org/docs/rendering/server-and-client-components

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

import dynamic from 'next/dynamic'

const Component = dynamic(async () => undefined, { ssr: false })
const Component = dynamic(
async () => () => <p id="dynamic-world">hello dynamic world</p>,
{
ssr: false,
}
)

export default function Page() {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'server-only'
// import 'server-only'
timneutkens marked this conversation as resolved.
Show resolved Hide resolved

export default function ServerOnlyLib() {
return 'server-only-lib'
Expand Down
4 changes: 4 additions & 0 deletions test/e2e/app-dir/rsc-errors/app/editor-links/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// import { useState } from 'react'
export default function Component() {
return <div id="component-editor-links">Component</div>
}
5 changes: 5 additions & 0 deletions test/e2e/app-dir/rsc-errors/app/editor-links/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Component from './component'

export default function Page() {
return <Component />
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'client-only'
// import 'client-only'

export default function ClientOnlyLib() {
return 'client-only-lib'
Expand Down