Commit graph

245 commits

Author SHA1 Message Date
OJ Kwon
1105501287
test(integration): fix --turbo tests fixture setup (#55293)
### What?

Update few test fixture setup doesn't invoke --turbo based on the conditions.

Closes WEB-1543
2023-09-18 17:46:07 +00:00
Jimmy Lai
bd705537a3
server: bundle vendored react (#55362)
## What

This PR changes Next.js to bundle its vendored React libraries so that the App Router pages can use those built-in versions.

## Why

Next.js supports both Pages and App Router and we've gone through a lot of iteration to make sure that Next.js stays flexible wrt to the version of React used: in Pages, we want to use the React provided by the user and in the App Router, to be able to use it, we need to use the canary version of React, which we've built into Next.js for convenience.

The problem stems from the fact that you can't run two different instances of React (by design).

Previously we have a dual worker setup, where we would separate completely each Next.js versions (App and Pages) so that they would not overlap with each other, however this approach was not great performance and memory wise.

We've recently tried using an ESM loader and a single process, but this change would still opt you into the React canary version if you had an app page, which breaks some assumptions.

## How

A list of the changes in this PR:

### New versions of the Next.js runtime

Since we now compile a runtime per type of page (app/route/api/pages), in order to bundle the two versions of React that we vendored, we introduced a new type of bundle suffixed by `-experimental`. This bundle will have the bleeding edge React needed for Server Actions and Next.js will opt you in into that runtime automatically.

For internal contributors, it means that we now run a compiler for 10 subparts of Next.js:
- next_bundle_server
- next_bundle_pages_prod
- next_bundle_pages_turbo
- next_bundle_pages_dev
- next_bundle_app_turbo_experimental
- next_bundle_app_prod
- next_bundle_app_prod_experimental
- next_bundle_app_turbo
- next_bundle_app_dev_experimental
- next_bundle_app_dev

![image](https://github.com/vercel/next.js/assets/11064311/f340417d-845e-45b9-8e86-5b287a295c82)

### Simplified require-hook

Since the versions of React are correctly re-routed at build time for app pages, we don't need the require hook anymore

### Turbopack changes

The bundling logic in Turbopack has been addressed to properly follow the new logic

### Changes to the shared contexts system

Some context files need to have a shared instance between the rendering runtime and the user code, like the one that powers the `next/image` component. In general, the aliasing setup takes care of that but we need the require hook for code that is not compiled to reroute to the correct runtime. This only happens for pages node_modules.

A new Turbopack resolving plugin has been added to handle that logic in Turbopack.

### Misc changes

- `runtime-config` (that powers `next/config`) has been converted to an `.external` file, as it should have been
- there are some rules that have been added to the aliases to support the usage of `react-dom/server` in a server-components. We can do that now since the runtime takes care of separating the versions of React.



Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2023-09-15 19:49:39 +00:00
JJ Kasper
7d93808c43
Remove render workers in favor of esm loader (#54813)
Currently we create separate workers to isolate `pages` and `app`
routers due to differing react versions being used between the two. This
adds overhead and complexity in the rendering process which we can avoid
by leveraging an `esm-loader` similar to our `require-hook` to properly
alias `pages` router to the bundled react version to match `app` router
when both are leveraged together.

This aims to seamlessly inject the `esm-loader` by restarting the
process with the loader arg added whenever `next` is imported so that
this also works with custom-servers and fixes the issue with custom
req/res fields not working after upgrading.


x-ref: https://github.com/vercel/next.js/issues/53883
x-ref: https://github.com/vercel/next.js/issues/54288
x-ref: https://github.com/vercel/next.js/issues/54129
x-ref: https://github.com/vercel/next.js/issues/54435
closes: https://github.com/vercel/next.js/issues/54440
closes: https://github.com/vercel/next.js/issues/52702
x-ref: [slack
thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1693348443932499?thread_ts=1693275196.347509&cid=C03KAR5DCKC)

---------

Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: Zack Tanner <zacktanner@gmail.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-09-11 22:17:52 +02:00
Jiachi Liu
60d3ab3e47
Filter out pages tree view for app dir only output (#55120)
Only output app routes if there's no pages routes in next build output


For hello world app you'll only see app dir routes
```
Route (app)                              Size     First Load JS
+ First Load JS shared by all            78.1 kB
  ├ chunks/main-app-e4c0616da69beffe.js  76.5 kB
  └ chunks/webpack-bf1a64d1eafd2816.js   1.61 kB


○  (Static)  automatically rendered as static HTML (uses no initial props)
```

Also filter out `/favicon.ico` static route as it's confusing
2023-09-08 00:06:05 +00:00
Jiachi Liu
e117c000e4
Redesign nextjs logging (#54713)
The current logging styles has been existed for a while, this PR gives a fresh impression for the logging output from Next.js.
We want to achieve few new goals that makes the output clean, modernized, sweet 🍫 .

Few goals are addressed with this redesign:

## Refresh Impression & Simplification

The new design of logging is much more information centralized and streamlined.

* Given a `ready` message at the begining when compilers are bootstrapped.
* Only show `compiled` event with green check mark indicating succesful compilation, this will merge the unclear `compiling` event which shows `(client and server)` before, now tell you the route compilation info in one line.

hello world app

### `next dev`

#### After vs Before


<img src="https://github.com/vercel/next.js/assets/4800338/9649b340-8241-4756-a2b3-a989f0b74003" height="120"> 
<img src="https://github.com/vercel/next.js/assets/4800338/ee181263-3dd4-40d0-9ffc-819a56b45900" height="120">  

 


 

### `next build`

#### After vs Before


<img src="https://github.com/vercel/next.js/assets/4800338/5db9829a-9ffc-49f0-b030-93ee92f5c248" width="360"> 
<img src="https://github.com/vercel/next.js/assets/4800338/b9527b83-27c8-4426-9c0d-c0d4072b7d58" width="360">





### error status

#### After vs Before

<img src="https://github.com/vercel/next.js/assets/4800338/00455226-ace7-468b-8d90-0d36bf038489" height="120"> 
<img src="https://github.com/vercel/next.js/assets/4800338/1be8c451-d3f0-465c-9ef7-6b0dde7cff85" height="120"> 



## Streamlization

If you have customized envs and experiments Next.js will give the brief in the early summary about your network information, env vars, and enabled experimental features

<img src="https://github.com/vercel/next.js/assets/4800338/ca1a7409-1532-46cb-850f-687e61e587b2" width="400">


## Polish

### fetching logging structure 

#### After vs Before
<img src="https://github.com/vercel/next.js/assets/4800338/97526397-dffe-4736-88ed-e5cbe5e945bd" width="400">
<img src="https://github.com/vercel/next.js/assets/4800338/ab77c907-5ab5-48bb-8347-6146d2e60932" width="400">


### Dedupe Duplicates

The logging is moved from `@next/env` to `next` itself, `@next/env` will only notify the invoker that the env is reloaded. Then the duplicated logs for the env reloading cases can be avoid.

#### After vs Before
<img src="https://github.com/vercel/next.js/assets/4800338/04799295-e739-4035-87aa-61cec962fc39" width="400">
<img src="https://github.com/vercel/next.js/assets/4800338/e29020c9-0031-4bf3-a21b-8b64633f43a2" width="400"> 


### Different indicators

Use unicode text icons for different situation: 
* passed -> check mark
* warning -> warning
* error -> red cross
* loading -> circle

<img src="https://github.com/vercel/next.js/assets/4800338/715c34bd-298f-4990-a5d7-e12e455ead44" width="400">



Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
2023-09-05 11:40:00 +00:00
Damien Simonin Feugas
3338dd0b31
fix(next-swc): skips client/server only checks when running with Jest to unblock testing (#54891)
Co-authored-by: Jiachi Liu <inbox@huozhi.im>
2023-09-04 13:53:41 +02:00
JJ Kasper
2eef775472
Update tag handling for app cache (#53321)
Optimizes how we handle cache tags for soft tags (auto-added by Next.js)
and normal tags (added manually) and adds differentiating between
`revalidatePath('/blog/first')` and page/layout.

Soft tags are not stored across cache entry and instead auto sent along
when checking cache entries. This allows us to prevent storing
exponential amounts of tags across cache entries while still having the
relationship between them so that single path revalidation can work
properly.

x-ref: [slack
thread](https://vercel.slack.com/archives/C042LHPJ1NX/p1690586837903309)
2023-08-31 15:17:40 -07:00
JJ Kasper
8487278c52
Fix failing TS test from new release (#54523)
Fixes: 

![CleanShot 2023-08-24 at 11 20
41@2x](https://github.com/vercel/next.js/assets/22380829/00d7e646-f41f-43ed-a18a-4532d0b7f5dc)

x-ref:
https://github.com/vercel/next.js/actions/runs/5967378932/job/16188975903?pr=54515#step:28:256
2023-08-24 11:36:38 -07:00
Zack Tanner
803bbe5c93
fix process.env not being available in standalone mode (#54203)
### What?
When running Next in standalone mode, `process.env` is not made
available to the render workers, making it impossible to access
environment variables that aren't provided in `.env` files.

### Why?
`initialEnv` is undefined in `createWorkers` when the server is started
in standalone mode.

### How?
This initializes the workers with `process.env` in case `initialEnv` is
unavailable, similar to the behavior of `loadEnvConfig()`

Closes NEXT-1508
Fixes #53367
2023-08-18 16:04:48 +02:00
Zack Tanner
c676f9357e
fix bfcache restoration behavior (#54198)
Follow up to https://github.com/vercel/next.js/pull/54081 -- this was
restoring the router tree improperly causing an error on bfcache hits

Had to override some default behaviors to prevent `forward` / `back` in
playwright from hanging indefinitely since no load event is firing in
these cases

Fixes #54184
Closes NEXT-1528
2023-08-18 00:05:26 +02:00
Jiachi Liu
02c258dd91
Revert "fix(47299): allow testing pages with metadata in jsdom test environment" (#54160)
Reverts vercel/next.js#53578

This PR (#53578) will break client components test, revert it for now.

Can repro by adding `"use client"` to `app/page.tsx` in `test/production/jest/server-only.test.ts`

```
    FAIL app/page.test.jsx
      ● Test suite failed to run·
        Cannot find module 'private-next-rsc-mod-ref-proxy' from 'app/page.jsx'·
        Require stack:
```
2023-08-17 08:49:08 +00:00
Zack Tanner
0b3e366f32
fix routing bug when bfcache is hit following an mpa navigation (#54081)
When an mpa navigation takes place, we currently push the user to the new route and suspend the page indefinitely (x-ref: #49058). When navigating back, if the browser opts into using the [bfcache](https://web.dev/bfcache/), it will remain suspended and `pushRef.mpaNavigation` will be true. This means that anything that would cause the component to re-render will trigger the mpa navigation again (such as hovering over another `Link`, as reported in #53347)

This PR checks to see if bfcache is being used by observing `PageTransitionEvent.persisted` and if so, resets the router state to clear out `pushRef`. 

Closes NEXT-1511
Fixes #53347
2023-08-16 17:55:06 +00:00
Damien Simonin Feugas
77acd164d3
fix(47299): allow testing pages with metadata in jsdom test environment (#53578)
### 🧐 What's in there?

This is another attempt to allow testing server-only code with Jest.

### 🧪 How to test?

There's an integration tests which can be triggered with `pnpm testheadless server-only`

Here is a more comprehensive setup:
<details>
<summary><code>app/lib/index.ts</code></summary>

```ts
import 'server-only'

export function add(num1: number, num2: number) {
  return num1 + num2
}
```
</details>
<details>
<summary><code>app/lib/index.test.ts</code></summary>

```ts
import { add } from '.'

it('adds two numbers', () => {
  expect(add(1, 3)).toEqual(4)
})
```
</details>
<details>
<summary><code>app/client-component.tsx</code></summary>

```ts
'use client'

import { useState } from 'react'

export default function ClientComponent() {
  const [text, setText] = useState('not clicked yet')
  return <button onClick={() => setText('clicked!')}>{text}</button>
}
```
</details>
<details>
<summary><code>app/client-component.test.tsx</code></summary>

```ts
import { fireEvent, render, screen } from '@testing-library/react'
import ClientComponent from './client-component'

it('can be clicked', async () => {
  render(<ClientComponent />)
  const button = screen.getByRole('button')
  expect(button).toHaveTextContent('not clicked yet')
  await fireEvent.click(button)
  expect(button).toHaveTextContent('clicked!')
})
```
</details>
<details>
<summary><code>app/server-component.tsx</code></summary>

```ts
import { add } from '@/lib'

export default function ServerComponent({ a, b }: { a: number; b: number }) {
  return (
    <code role="comment">
      {a} + {b} = {add(a, b)}
    </code>
  )
}
```
</details>
<details>
<summary><code>app/server-component.test.tsx</code></summary>

```ts
import { render, screen } from '@testing-library/react'
import ServerComponent from './server-component'

it('renders', () => {
  render(<ServerComponent a={2} b={3} />)
  expect(screen.getByRole('comment')).toHaveTextContent('2 + 3 = 5')
})
```
</details>
<details>
<summary><code>app/page.tsx</code></summary>

```ts
import Link from 'next/link'
import ClientComponent from './client-component'
import ServerComponent from './server-component'

export default function Page() {
  return (
    <>
      <h1>Hello World</h1>
      <Link href="/dave">Dave?</Link>
      <p>
        <ClientComponent />
      </p>
      <p>
        <ServerComponent a={5} b={2} />
      </p>
    </>
  )
}
```
</details>
<details>
<summary><code>app/page.test.tsx</code></summary>

```ts
import { render, screen } from '@testing-library/react'
import Page from './page'

it('greets', () => {
  render(<Page />)
  expect(screen.getByRole('link')).toHaveTextContent('Dave?')
  expect(screen.getByRole('heading')).toHaveTextContent('Hello World')
  expect(screen.getByRole('button')).toHaveTextContent('not clicked yet')
  expect(screen.getByRole('comment')).toHaveTextContent('5 + 2 = 7')
})
```
</details>
<details>
<summary><code>app/[blog]/page.tsx</code></summary>

```ts
import { Metadata } from 'next'
import Link from 'next/link'

type Props = {
  params: { blog: string }
}

export async function generateMetadata({
  params: { blog: title },
}: Props): Promise<Metadata> {
  return { title, description: `A blog post about ${title}` }
}

export default function Page({ params }: Props) {
  return (
    <>
      <div>
        <Link href="/">Back</Link>
      </div>
      <h1>All about {params.blog}</h1>
    </>
  )
}
```
</details>
<details>
<summary><code>app/[blog]/page.test.tsx</code></summary>

```ts
import { render, screen } from '@testing-library/react'
import Page from './page'

it('has the appropriate title', () => {
  const title = 'Jane'
  render(<Page params={{ blog: title }} />)
  expect(screen.getByRole('heading')).toHaveTextContent(`All about ${title}`)
  expect(screen.getByRole('link')).toHaveTextContent('Back')
})
```
</details>
<details>
<summary><code>app/layout.tsx</code></summary>

```ts
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
```
</details>
<details>
<summary><code>jest.config.js</code></summary>

```ts
const nextJest = require('next/jest')

const createJestConfig = nextJest({ dir: './' })

module.exports = createJestConfig({
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/test-setup.ts'],
})
```
</details>
<details>
<summary><code>package.json</code></summary>

```ts
{
  "name": "rsc-test",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "latest"
  }
}
```
</details>
<details>
<summary><code>test-setup.ts</code></summary>

```ts
import '@testing-library/jest-dom'
```
</details>
   
The app should run and all test should pass.

###  Notes to reviewers

#### The problem:

1. next/jest configures jest with a transformer ([jest-transformer](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/swc/jest-transformer.ts)) to compile react code with next -swc
2. the transformers configures next -swc for a given environment: Server or Client, based on jest global environment
3. Based on the environment, next -swc checks for invalid usage of `import('server-only')`  `“use client”`, `export const metadata` or `export async function generateMetadata` 
4. Because the global test environment is either jsdom or node, the same test suite can not include both client and server components

#### Possible mitigations

*A. Using jest projects*

When configured with [multiple projects](https://jestjs.io/docs/next/configuration/#projects-arraystring--projectconfig), Jest can launch different runners with different environment. This would allow running server-only code in node and client-only code in jsdom. 

However, it requires user to completely change their jest configuration. It would also require a different setup when scaffolding new app-directory project with create-next.

*B. Using doc blocks*

Jest allows changing the environment per test file [with docBlock](https://jestjs.io/docs/configuration#testenvironment-string). 

However, by the time jest is invoking next -swc on a source file to transform it, this information is gone, and next -swc is still invoked with the (wrong) global environment.

The PR #52393 provides a workaround for files with `import('server-only')`, but does not allow testing pages with metadata.

*C. Always compile for node*

Our jest-transformer could always configure next -swc for server:

- pass Server-specific validations `import('server-only')`  `export const metadata` or `export async function generateMetadata`
- does not complain about `"use client"`

This is what this PR is about!

Fixes #47299

Co-authored-by: Jiachi Liu <4800338+huozhi@users.noreply.github.com>
2023-08-16 07:14:27 +00:00
Zack Tanner
c4f9c6d492
add standalone testcase for ipv6 hostnames (#53999)
This adds a test case for ipv6 hostnames in standalone mode

- Follow up to https://github.com/vercel/next.js/pull/53131
2023-08-14 17:14:07 +00:00
Ngô Đức Anh
a4b430e6f1
Better IPv6 support for next-server (#53131)
### What?
This PR makes it easier to use Next.js with IPv6 hostnames such as `::1` and `::`.

### How?
It does so by removing rewrites from `localhost` to `127.0.0.1` introduced in #52492. It also fixes the issue where Next.js tries to fetch something like `http://::1:3000` when `--hostname` is `::1` as it is not a valid URL (browsers' `URL` class throws an error when constructed with such hosts). It also fixes `NextURL` so that it doesn't accept `http://::1:3000` but refuse `http://[::1]:3000`. It also changes `next/src/server/lib/setup-server-worker.ts` so that it uses the server's `address` method to retrieve the host instead of our provided `opts.hostname`, ensuring that no matter what `opts.hostname` is we will always get the correct one.

### Note
I've verified that `next dev`, `next start` and `node .next/standalone/server.js` work with IPv6 hostnames (such as `::` and `::1`), IPv4 hostnames (such as `127.0.0.1`, `0.0.0.0`) and `localhost` - and with any of these hostnames fetching to `localhost` also works. Server Actions and middleware have no problems as well.

This also removes `.next/standalone/server.js`'s logging as we now use `start-server`'s logging to avoid duplicates. `start-server`'s logging has also been updated to report the actual hostname.
![image](https://github.com/vercel/next.js/assets/75556609/cefa5f23-ff09-4cef-a055-13eea7c11d89)
![image](https://github.com/vercel/next.js/assets/75556609/619e82ce-45d9-47b7-8644-f4ad083429db)
The above pictures also demonstrate using Server Actions with Next.js after this PR.
![image](https://github.com/vercel/next.js/assets/75556609/3d4166e9-f950-4390-bde9-af2547658148)

Fixes #53171
Fixes #49578
Closes NEXT-1510

Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
2023-08-14 07:23:24 +00:00
Zack Tanner
23f623546e
add "expect" to list of forbidden IPC headers (#53947)
`expect` is an unsupported header for undici: c83b084879/lib/core/request.js (L354) -- this filters it out so that the API routes don't throw an internal server error if that header is included. 

Also added a test case for the previously submitted PR that was added for `content-length: 0`

- x-ref: #53843

Fixes #53822 (erroneously closed by a content-length issue being fixed)
2023-08-12 19:38:38 +00:00
Balázs Orbán
b41497d763
fix(next/image): don't call ReactDOM.preload if missing, such as jest (#53443)
### What?

`ReactDOM.preload` is available in `react-dom@experimental` builds. If it's not available, we should fall back to `Head`+`link`

### Why?

Since `ReactDOM.preload` is only available in `react-dom@experimental` builds, certain environments (like Jest or [Storybook](https://github.com/storybookjs/storybook/issues/23661)) might have a version of `react-dom` installed that won't work with `preload()`

### How?

Closes NEXT-1482
Fixes #53272

See also: https://github.com/storybookjs/storybook/issues/23661

Co-authored-by: Steven <229881+styfle@users.noreply.github.com>
2023-08-08 01:04:40 +00:00
Zack Tanner
26c19b1fa2
return a 404 when /next/_data build IDs are mismatched (#53596)
`normalizeNextData` in `next-server` used to exit early with a 404 when there was a build ID mismatch, but a recent refactor accidentally removed this functionality. This PR updates it to behave similarly to [web-server](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/web-server.ts#L180-L187) where we render404 if there's a mismatch.

[slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1691111541353749)
2023-08-05 00:15:42 +00:00
Steven
cdbea3e7da
chore(ci): remove console.log() (#53413)
Follow up to #53408
2023-08-01 01:32:11 +00:00
Steven
8c6da3f72d
chore(test): move build-spinners node-pty test to isolated (#53408)
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2023-08-01 00:30:22 +00:00
JJ Kasper
35e16f75bc
Tweak flakey prefetch test handling (#53391)
Seems this one is still finicky so re-works it some more. 

x-ref: https://github.com/vercel/next.js/actions/runs/5716005333/job/15486690109
2023-07-31 16:20:43 +00:00
JJ Kasper
4a926efb83
Update flakey app-action and prerender-prefetch tests (#53340)
x-ref:
https://github.com/vercel/next.js/actions/runs/5699334417/job/15448149485#step:27:600
x-ref:
https://github.com/vercel/next.js/actions/runs/5702064037/job/15453403529?pr=53340
2023-07-30 12:51:24 -07:00
JJ Kasper
1398de9977
Revert "Revert "Separate routing code from render servers (#52492)"" (#53029)
Reverts vercel/next.js#53016
2023-07-21 14:02:52 -07:00
JJ Kasper
ac62406ca0
Revert "Separate routing code from render servers (#52492)" (#53016)
Temporarily reverts these changes to allow patch release first. 

Reverts: https://github.com/vercel/next.js/pull/52149
Reverts: https://github.com/vercel/next.js/pull/52492
2023-07-21 10:52:19 -07:00
JJ Kasper
f57eecde5e
Separate routing code from render servers (#52492)
This breaks out routing handling from `next-server`, `next-dev-server`,
and `base-server` so that these are only handling the "render" work and
eventually these will be deleted completely in favor of the bundling
work being done.

The `router` process and separate `render` processes are still
maintained here although will be investigated further in follow-up to
see if we can reduce the need for these.

We are also changing the `require-cache` IPC to a single call instead of
call per entry to reduce overhead and also de-dupes handling for
starting the server between the standalone server and normal server.

To maintain support for existing turbopack route resolving this
implements the new route resolving in place of the existing
`route-resolver` until the new nextturbo API is fully landed.

After these initial changes we should continue to eliminate non-render
related code from `next-server`, `base-server`, and `next-dev-server`.
2023-07-20 22:13:42 -07:00
Facundo Giuliani
a26bac9604
Update default moduleResolution in tsconfig.json from node to bundler (#51957)
This updates our `moduleResolution` to `bundler` as this matches our heuristics much more closely so is more accurate. This shouldn't be a breaking change is it should be compatible with our previous default. 

Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2023-07-18 15:11:09 +00:00
Damien Simonin Feugas
4a14671fa6
fix(next/jest): jest can not load server-only code (#52393)
### 🧐 What's in there?

At the moment, it is not possible to test code with `import 'server-only'` in app directory.
When trying to load such file in jest (even with `testEnvironment: node`), the error will be:
```
      ● Test suite failed to run··
          x NEXT_RSC_ERR_CLIENT_IMPORT: server-only
           ,-[lib/util.js:1:1]
         1 | /** @jest-environment node */·
         2 |         import 'server-only'
           :         ^^^^^^^^^^^^^^^^^^^^
         3 |         export const PI = 3.14;
           `----·
          at Object.transformSync (node_modules/next/src/build/swc/index.ts:443:25)
          at transformSync (node_modules/next/src/build/swc/index.ts:629:19)
          at Object.process (node_modules/next/src/build/swc/jest-transformer.ts:117:25)
          at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:619:31)
          at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:765:40)
          at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:822:19)·
```

In a nutshell:
- next/swc is looking for ‘server-only’ [text in the source](https://github.com/vercel/next.js/blob/canary/packages/next-swc/crates/core/src/react_server_components.rs#L576), and throw if not configured for server
- next's jest-transformer will only configure next/swc for server [if the environment is node](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/swc/jest-transformer.ts#L88)
- when testing Next.js apps, your jest testEnvironment is most likely jsdom. But you can configure it [per file with docBlock](https://jestjs.io/docs/configuration#testenvironment-string), which jest-transformer ignores because it only reads the top-level configuration.

This PR fixes this, by 
1. reading the docblock to configure next/swc accordingly and bypass its hardcoded guard
2. mocking `server-only` so [it does not throw](https://github.com/vercel/next.js/blob/canary/packages/next/src/compiled/server-only/index.js) when loaded (jest does not read `react-server` export from package.json)

Users would still have to annotate their `server-only` files with `/** @jest-environment node */` in order to test them.

### 🧪 How to test?

There's a full test available: `pnpm testheadless --testPathPattern jest/server-only`

Here is also a minimal reproduction:

<details>
    <summary>app/layout.tsx</summary>

```typescript
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (<html lang="en"><body>{children}</body></html>)
}
```
</details>

<details>
    <summary>app/page.tsx</summary>

```typescript
import { PI } from '@/lib/utils'

export default function Home() {
    return <h1>{PI}</h1>
}
```
</details>

<details>
    <summary>lib/utils.ts</summary>

```typescript
import 'server-only'

export const PI = 3.14
```
</details>

<details>
    <summary>lib/utils.test.ts</summary>

```typescript
import { PI } from './utils'

it('works', () => expect(PI).toEqual(3.14))
```
</details>

<details>
    <summary>jest.config.js</summary>

```typescript
const nextJest = require('next/jest')

module.exports = nextJest({ dir: './' })({ testEnvironment: 'jsdom' })
```
</details>

###  Notes to reviewers

[jest-docblock](https://packagephobia.com/result?p=jest-docblock) with dependencies is only 12.5 kB.


Fixes #47448
2023-07-12 08:51:29 +00:00
JJ Kasper
0600293b03
Fix ISR case with bot requests (#52581)
This ensures we don't bail from static generation unexpectedly due to a
bot request as this shouldn't affect ISR handling.

Test deployment with patch can be seen here
https://test-app-isr-fallback-dwn2neok6-vtest314-ijjk-testing.vercel.app/new

Fixes: https://github.com/vercel/next.js/issues/47805
2023-07-11 23:39:50 -07:00
JJ Kasper
fab164dcc8
Update id handling for fonts (#52559)
We don't need to apply the ID here as these assets should always be available across deploys. 

x-ref: [slack thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1689035592272659)
2023-07-11 17:14:25 +00:00
Ngô Đức Anh
98cc99df46
fix(standalone): fixed output: "standalone" crashing build when there is no app/ page (#51993)
### What?
This PR fixes build crashing when `output: 'standalone'` and `experimental.appDir` is enabled but there is no app pages.

### How?
It does that by checking whether `.next/server/app` exists before copying the folder to `.next/standalone/...`

Closes #51828
Fixes #44442
Fixes #44120
2023-07-10 08:40:02 +00:00
Steven
525ffb4334
chore: remove experimental appDir: true from tests (#52291)
The experimental flag is no longer needed.

https://nextjs.org/blog/next-13-4
2023-07-05 19:17:29 -07:00
JJ Kasper
8dc0b1be61
Fix app cache enabling case (#52278)
Ensures we don't attempt using the wrong cache handler during build. 

x-ref: [slack
thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1688549526316949)
2023-07-05 12:52:16 -07:00
Shu Ding
cd66e765e0
Skip build-time dynamic code checks for specific polyfills in the Edge runtime (#52009)
As discussed in https://vercel.slack.com/archives/C03ENM5HB4K/p1687999628589119 and #51910, it makes sense to have a known list for packages (mostly polyfills) that we know are having dynamic code (`eval`, `new Function`) but are safe to run in the Edge Runtime because that dynamic code will never be executed.
2023-07-04 14:18:02 +00:00
Leah
5d54eaaf18
type check tests (and convert next-test-utils.js to ts) (#51071)
Enables type checking for tests in CI and fixes a bunch of things related to that
2023-06-23 17:42:50 +00:00
Jiachi Liu
16eb80b0b0
Fix standalone rendering for unmatched _next routes (#51611)
Request data flow in the server

```
request ---> router worker (1) ---> ipc ---> render worker app (2)
                                                              |-----> render worker pages (3)
```

When it's hitting `_next/*` unmatched routes in standalone server, it will render 404, but when you hit `_next/*` it will render app not-found as the app router is always enabled, but router worker isn't set up with require-hook for proper built-in react version, then the app-render will fail with `./server.edge` exports not found error.

We detect if it's in the render worker, then do the app paths rendering instead of directly looking up for app paths in route worker. This could avoid unexpected accesses to the app-render

Fixes #51482 
Fixes #50232
Closes #51506
Reverts changes in #51172
fix NEXT-1260
2023-06-22 22:58:04 +00:00
Wyatt Johnson
77ef61ea35
Route Module Updates (#51433)
Small QOL improvements to `RenderResult` and `RouteModule` setup. This
also adds a test to verify that headers aren't sent on responses that
have already been sent.

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-06-21 15:30:24 -07:00
Shu Ding
a0cc4aa65e
Revert "Fix standalone not found" (#51506)
Reverts vercel/next.js#51172

Fixes #51482.
2023-06-21 13:15:05 -07:00
JJ Kasper
f6998e30a8
Update id env prefix (#51588)
Removes `__` prefix and ensures it's available on client/server as
expected.

x-ref: [slack
thread](https://vercel.slack.com/archives/C04TNLL0LSK/p1687197571572119)
2023-06-20 16:41:28 -07:00
JJ Kasper
bdcca0ccff
Fix CSS deploy id case (#51325)
x-ref: [slack
thread](https://vercel.slack.com/archives/C04MEB9L9RQ/p1686787663510239?thread_ts=1686770561.895939&cid=C04MEB9L9RQ)
2023-06-14 20:28:18 -07:00
Jiachi Liu
9d0129c635
Fix standalone not found (#51172)
Fixes #50232

Passing down the private env into `'render-server'` module to pick up the proper react with require-hook in standalone server
fix NEXT-1260
2023-06-12 21:14:32 +00:00
JJ Kasper
32a9c3553f
Fix another case with app router revalidation (#51076)
This ensures we don't attempt streaming a response during revalidation
in deployed environments.

x-ref: https://github.com/vercel/next.js/pull/51062
x-ref: [slack
thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1686216024812579)
2023-06-09 16:40:41 -07:00
JJ Kasper
90ee9589d6
Update response cache test (#51072)
x-ref: https://github.com/vercel/next.js/pull/51062
2023-06-09 14:14:30 -07:00
JJ Kasper
804552590e
Update app router revalidate handling on deploy (#51062)
This ensures we clear the RSC headers during revalidate when deployed so
that the HTML revalidation isn't treated as the RSC revalidation.
2023-06-09 13:23:44 -07:00
JJ Kasper
4080f63505
Ensure id handling applies for dynamic import in pages (#51049)
Noticed this case wasn't handled in pages so added additional test
coverage and patched the case.
2023-06-09 09:51:51 -07:00
JJ Kasper
1e0566b9ac
Update id config handling (#50847)
Adds a separate flag for leveraging the env variable.
2023-06-06 07:54:06 -07:00
JJ Kasper
8253fa0938
Add experimental id handling (#50470)
x-ref: [slack
thread](https://vercel.slack.com/archives/C04TNLL0LSK/p1684879925060159)
2023-05-31 18:09:10 -07:00
JJ Kasper
a3ab542630
Add new build and test workflow (#50436)
This adds new `build and test` and `build and deploy` workflows in favor
of the existing massive `build, test, and deploy` workflow. Since the
new workflows will use `pull_request_target` this waits to remove the
existing workflow until the new one is tested.

While testing this new workflow flakey behavior in tests have also been
addressed. Along with the new workflow we will also be leveraging new
runners which allow us to run tests against the production binary of
`next-swc` so this avoids slight differences in tests we've seen due to
running against the dev binary.

Furthermore we will have a new flow for allowing workflow runs on PRs
from external forks which will either require a comment be checking a
box approving the run after each change or a label added by the team.

The new flow also no longer relies on `actions/cache` or similar which
have proven to be pretty unreliable.

Tests runs with the new workflow can be seen here
https://github.com/vercel/next.js/actions/runs/5100673508/jobs/9169416949
2023-05-27 21:02:31 -07:00
Javi Velasco
aa91de56ce
Remove static analysis of process.env (#50260)
Since there is no longer a limitation that requires us to static analyze
`process.env`, this PR removes it from the build process and updates the
corresponding documentation.
2023-05-24 08:19:02 -07:00
Shu Ding
c7e5d76717
Fix custom server React resolution with app dir and pages both presented (#49805)
If running Next.js in the custom server with both app and pages directories presented, a standalone server needs to serve all traffic and the server running in main thread should be a no-op. (cc @ijjk).

Fixes the problem described here: https://github.com/vercel/next.js/issues/49355#issuecomment-1537536063.
2023-05-18 01:31:43 +00:00
Tim Neutkens
25a9547cad
Remove experimental config from create-next-app (#49241)
## What?

Removes `experimental.appDir` this was leftover from when I flipped the
switch.

Kept the config file as in the future we might add future flags and
such. It also helps that it has the types comment included so you always
get types.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation or adding/fixing Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md



## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2023-05-05 00:22:28 -07:00