Skip to content

Commit

Permalink
Current behavior of import conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Jun 13, 2024
1 parent d7d5117 commit 8bc09e0
Show file tree
Hide file tree
Showing 20 changed files with 509 additions and 0 deletions.
41 changes: 41 additions & 0 deletions test/e2e/import-conditions/app/app/ClientPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client'
import * as React from 'react'
import * as react from 'library-with-exports/react'
import * as serverFavoringBrowser from 'library-with-exports/server-favoring-browser'
import * as serverFavoringEdge from 'library-with-exports/server-favoring-edge'

export default function ClientPage({
action,
server,
}: {
action: () => Promise<Record<string, string>>
server: unknown
}) {
const [actionValue, formAction, isPending] = React.useActionState(
action,
undefined
)
const [client, setClient] = React.useState<unknown | null>(null)
React.useEffect(() => {
setClient({
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
})
}, [])

return (
<form action={formAction}>
<input type="submit" />
<output aria-busy={client === null || isPending}>
{client === null ? (
<pre>{JSON.stringify({ server }, null, 2)}</pre>
) : (
<pre>
{JSON.stringify({ server, client, action: actionValue }, null, 2)}
</pre>
)}
</output>
</form>
)
}
28 changes: 28 additions & 0 deletions test/e2e/import-conditions/app/app/edge-page/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as react from 'library-with-exports/react'
import * as serverFavoringBrowser from 'library-with-exports/server-favoring-browser'
import * as serverFavoringEdge from 'library-with-exports/server-favoring-edge'
import ClientPage from '../ClientPage'

export const runtime = 'edge'

async function action() {
'use server'
return {
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
}
}

export default function Page() {
return (
<ClientPage
action={action}
server={{
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
}}
/>
)
}
28 changes: 28 additions & 0 deletions test/e2e/import-conditions/app/app/node-page/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as react from 'library-with-exports/react'
import * as serverFavoringBrowser from 'library-with-exports/server-favoring-browser'
import * as serverFavoringEdge from 'library-with-exports/server-favoring-edge'
import ClientPage from '../ClientPage'

export const runtime = 'nodejs'

async function action() {
'use server'
return {
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
}
}

export default function Page() {
return (
<ClientPage
action={action}
server={{
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
}}
/>
)
}
13 changes: 13 additions & 0 deletions test/e2e/import-conditions/app/edge-route/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as react from 'library-with-exports/react'
import * as serverFavoringBrowser from 'library-with-exports/server-favoring-browser'
import * as serverFavoringEdge from 'library-with-exports/server-favoring-edge'

export const runtime = 'edge'

export function GET() {
return Response.json({
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
})
}
7 changes: 7 additions & 0 deletions test/e2e/import-conditions/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Root({ children }: { children: React.ReactNode }) {
return (
<html>
<body>{children}</body>
</html>
)
}
13 changes: 13 additions & 0 deletions test/e2e/import-conditions/app/node-route/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as react from 'library-with-exports/react'
import * as serverFavoringBrowser from 'library-with-exports/server-favoring-browser'
import * as serverFavoringEdge from 'library-with-exports/server-favoring-edge'

export const runtime = 'nodejs'

export function GET() {
return Response.json({
react: react.condition,
serverFavoringBrowser: serverFavoringBrowser.condition,
serverFavoringEdge: serverFavoringEdge.condition,
})
}
228 changes: 228 additions & 0 deletions test/e2e/import-conditions/import-conditions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import { nextTestSetup } from 'e2e-utils'

describe('react version', () => {
const { next } = nextTestSetup({
files: __dirname,
dependencies: {
'library-with-exports': 'link:./library-with-exports',
},
})

it('Pages Router page headers with edge runtime', async () => {
const response = await next.fetch('/pages/edge-page')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
expect(middlewareHeaders).toEqual({
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
})
})

it('Pages Router page with edge runtime', async () => {
const browser = await next.browser('/pages/edge-page')

const json = await browser.elementByCss('output').text()
expect(JSON.parse(json)).toEqual({
server: {
react: 'default',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
client: {
react: 'default',
serverFavoringBrowser: 'browser',
serverFavoringEdge: 'browser',
},
})
})

it('Pages Router page headers with nodejs runtime', async () => {
const response = await next.fetch('/pages/node-page')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
expect(middlewareHeaders).toEqual({
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
})
})

it('Pages Router page with nodejs runtime after hydration', async () => {
const browser = await next.browser('/pages/node-page')

const json = await browser.elementByCss('output').text()
expect(JSON.parse(json)).toEqual({
server: {
react: 'default',
serverFavoringBrowser: 'node',
serverFavoringEdge: 'node',
},
client: {
react: 'default',
serverFavoringBrowser: 'browser',
serverFavoringEdge: 'browser',
},
})
})

it('App Router page headers with edge runtime', async () => {
const response = await next.fetch('/app/edge-page')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
expect(middlewareHeaders).toEqual({
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
})
})

it('App Router page with edge runtime', async () => {
const browser = await next.browser('/app/edge-page')

await browser.waitForElementByCss('input[type="submit"]').click()
await browser.waitForElementByCss('output[aria-busy="false"]')

const json = await browser.elementByCss('output').text()
expect(JSON.parse(json)).toEqual({
server: {
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
client: {
react: 'default',
serverFavoringBrowser: 'browser',
serverFavoringEdge: 'browser',
},
action: {
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
})
})

it('App Router page headers with nodejs runtime', async () => {
const response = await next.fetch('/app/node-page')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
expect(middlewareHeaders).toEqual({
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
})
})

it('App Router page with nodejs runtime', async () => {
const browser = await next.browser('/app/node-page')

await browser.waitForElementByCss('input[type="submit"]').click()
await browser.waitForElementByCss('output[aria-busy="false"]')

const json = await browser.elementByCss('output').text()
expect(JSON.parse(json)).toEqual({
server: {
react: 'react-server',
serverFavoringBrowser: 'node',
serverFavoringEdge: 'node',
},
client: {
react: 'default',
serverFavoringBrowser: 'browser',
serverFavoringEdge: 'browser',
},
action: {
react: 'react-server',
serverFavoringBrowser: 'node',
serverFavoringEdge: 'node',
},
})
})

it('App Router Route Handler with nodejs runtime', async () => {
const response = await next.fetch('/node-route')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
const data = await response.json()
expect({ middlewareHeaders, data }).toEqual({
middlewareHeaders: {
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
data: {
react: 'react-server',
serverFavoringBrowser: 'node',
serverFavoringEdge: 'node',
},
})
})

it('App Router Route Handler with edge runtime', async () => {
const response = await next.fetch('/edge-route')

const middlewareHeaders = {
react: response.headers.get('x-react-condition'),
serverFavoringBrowser: response.headers.get(
'x-server-favoring-browser-condition'
),
serverFavoringEdge: response.headers.get(
'x-server-favoring-edge-condition'
),
}
const data = await response.json()
expect({ middlewareHeaders, data }).toEqual({
middlewareHeaders: {
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
data: {
react: 'react-server',
serverFavoringBrowser: 'worker',
serverFavoringEdge: 'worker',
},
})
})
})
1 change: 1 addition & 0 deletions test/e2e/import-conditions/library-with-exports/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const condition = 'browser'
1 change: 1 addition & 0 deletions test/e2e/import-conditions/library-with-exports/default.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const condition = 'default'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const condition = 'edge-light'
1 change: 1 addition & 0 deletions test/e2e/import-conditions/library-with-exports/netlify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const condition = 'netlify'
3 changes: 3 additions & 0 deletions test/e2e/import-conditions/library-with-exports/never.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
throw new Error(
'Imported entrypoint that should never be used. This is a bug in Next.js'
)
1 change: 1 addition & 0 deletions test/e2e/import-conditions/library-with-exports/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const condition = 'node'
Loading

0 comments on commit 8bc09e0

Please sign in to comment.