Skip to content

Commit

Permalink
Refactor to function and find links on full content
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Bornö committed Jan 24, 2023
1 parent d911289 commit 2111183
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { useOpenInEditor } from '../../helpers/use-open-in-editor'

function EditorLink({ file }: { file: string }) {
export function EditorLink({ file }: { file: string }) {
const open = useOpenInEditor({
file,
column: 1,
Expand Down Expand Up @@ -33,28 +33,3 @@ function EditorLink({ file }: { file: string }) {
</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
@@ -1,19 +1,42 @@
import Anser from 'next/dist/compiled/anser'
import * as React from 'react'
import { WithOpenInEditorLinks } from '../WithOpenInEditorLinks'
import { EditorLink } from './EditorLink'

export type TerminalProps = { content: string }

function getImportTraceFiles(content: string): [string, 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]
}

return [content, []]
}

export const Terminal: React.FC<TerminalProps> = function Terminal({
content,
}) {
const [source, editorLinks] = React.useMemo(
() => getImportTraceFiles(content),
[content]
)

const decoded = React.useMemo(() => {
return Anser.ansiToJson(content, {
return Anser.ansiToJson(source, {
json: true,
use_classes: true,
remove_empty: true,
})
}, [content])
}, [source])

return (
<div data-nextjs-terminal>
Expand All @@ -30,9 +53,12 @@ export const Terminal: React.FC<TerminalProps> = function Terminal({
: undefined),
}}
>
<WithOpenInEditorLinks content={entry.content} />
{entry.content}
</span>
))}
{editorLinks.map((file) => (
<EditorLink key={file} file={file} />
))}
</pre>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@ const styles = css`
white-space: pre-wrap;
word-break: break-word;
}
[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 }

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ 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 @@ -23,7 +22,6 @@ export function ComponentStyles() {
${leftRightDialogHeader}
${codeFrame}
${terminal}
${openInEditorLinks}
${buildErrorStyles}
${rootLayoutErrorStyles}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@

import dynamic from 'next/dynamic'

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

export default function Page() {
return (
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/app-dir/rsc-errors/app/editor-links/component.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// import { useState } from 'react'
export default function Component() {
return <div id="component-editor-links">Component</div>
return <div>Component</div>
}
36 changes: 7 additions & 29 deletions test/e2e/app-dir/rsc-errors/rsc-errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,7 @@ if (!(globalThis as any).isNextDev) {

await next.patchFile(
file,
content.replace(
'() => <p id="dynamic-world">hello dynamic world</p>',
'undefined'
)
content.replace('() => <p>hello dynamic world</p>', 'undefined')
)

expect(await hasRedbox(browser, true)).toBe(true)
Expand All @@ -199,7 +196,7 @@ if (!(globalThis as any).isNextDev) {
)

await next.patchFile(file, content)
await browser.waitForElementByCss('#dynamic-world')
expect(await hasRedbox(browser, false)).toBe(false)
})

it('should be possible to open the import trace files in your editor', async () => {
Expand All @@ -225,27 +222,6 @@ if (!(globalThis as any).isNextDev) {
)

expect(await hasRedbox(browser, true)).toBe(true)
await check(() => getRedboxHeader(browser), /Failed to compile/)

expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"./app/editor-links/component.js
ReactServerComponentsError:
You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with \\"use client\\", so they're Server Components by default.
,-[1:1]
1 | import { useState } from 'react'
: ^^^^^^^^
2 | export default function Component() {
3 | return <div id=\\"component-editor-links\\">Component</div>
4 | }
\`----
Maybe one of these should be marked as a client entry with \\"use client\\":
app/editor-links/component.js
app/editor-links/page.js"
`)

await browser.waitForElementByCss('[data-with-open-in-editor-link]')
const collapsedFrameworkGroups = await browser.elementsByCss(
'[data-with-open-in-editor-link]'
Expand All @@ -258,7 +234,7 @@ if (!(globalThis as any).isNextDev) {

// Fix file
await next.patchFile(componentFile, fileContent)
await browser.waitForElementByCss('#component-editor-links')
expect(await hasRedbox(browser, false)).toBe(false)
})

it('should throw an error when error file is a server component', async () => {
Expand All @@ -272,6 +248,7 @@ if (!(globalThis as any).isNextDev) {
expect(await hasRedbox(browser, true)).toBe(true)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"./app/server-with-errors/error-file/error.js
ReactServerComponentsError:
./app/server-with-errors/error-file/error.js must be a Client Component. Add the \\"use client\\" directive the top of the file to resolve this issue.
Expand All @@ -281,7 +258,7 @@ if (!(globalThis as any).isNextDev) {
\`----
Import path:
app/server-with-errors/error-file/error.js"
app/server-with-errors/error-file/error.js"
`)

// Add "use client"
Expand All @@ -296,6 +273,7 @@ if (!(globalThis as any).isNextDev) {
expect(await hasRedbox(browser, true)).toBe(true)
expect(await getRedboxSource(browser)).toMatchInlineSnapshot(`
"./app/server-with-errors/error-file/error.js
ReactServerComponentsError:
./app/server-with-errors/error-file/error.js must be a Client Component. Add the \\"use client\\" directive the top of the file to resolve this issue.
Expand All @@ -305,7 +283,7 @@ if (!(globalThis as any).isNextDev) {
\`----
Import path:
app/server-with-errors/error-file/error.js"
app/server-with-errors/error-file/error.js"
`)

// Fix
Expand Down

0 comments on commit 2111183

Please sign in to comment.