Commit graph

96 commits

Author SHA1 Message Date
Wyatt Johnson
33a6dca747
Mask Flight Parameters from Middleware (#39939)
This masks flight parameters from middleware so it doesn't interfere with RSC or routing.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)


Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
2022-09-15 14:53:51 +00:00
Damien Simonin Feugas
97ac344468
feat(edge): allows configuring Dynamic code execution guard (#39539)
### 📖  What's in there?

Dynamic code evaluation (`eval()`, `new Function()`, ...) is not
supported on the edge runtime, hence why we fail the build when
detecting such statement in the middleware or `experimental-edge` routes
at build time.

However, there could be false positives, which static analysis and
tree-shaking can not exclude:
- `qs` through these dependencies (get-intrinsic:
[source](https://github.com/ljharb/get-intrinsic/blob/main/index.js#L12))
- `function-bind`
([source](https://github.com/Raynos/function-bind/blob/master/implementation.js#L42))
- `has`
([source](https://github.com/tarruda/has/blob/master/src/index.js#L5))

This PR leverages the existing `config` export to let user allow some of
their files.
it’s meant for allowing users to import 3rd party modules who embed
dynamic code evaluation, but do not use it (because or code paths), and
can't be tree-shaked.

By default, it’s keeping the existing behavior: warn in dev, fails to
build.
If users allow dynamic code, and that code is reached at runtime, their
app stills breaks.

### 🧪 How to test?

- (existing) integration tests for disallowing dynamic code evaluation:
`pnpm testheadless --testPathPattern=runtime-dynamic`
- (new) integration tests for allowing dynamic code evaluation: `pnpm
testheadless --testPathPattern=runtime-configurable`
- (amended) production tests for validating the new configuration keys:
`pnpm testheadless --testPathPattern=config-validations`

To try it live, you could have an application such as:
```js
// lib/index.js
/* eslint-disable no-eval */
export function hasUnusedDynamic() {
  if ((() => false)()) {
    eval('100')
  }
}

export function hasDynamic() {
  eval('100')
}

// pages/index.jsx
export default function Page({ edgeRoute }) {
  return <p>{edgeRoute}</p>
}

export const getServerSideProps = async (req) => {
  const res = await fetch(`http://localhost:3000/api/route`)
  const data = await res.json()
  return { props: { edgeRoute: data.ok ? `Hi from the edge route` : '' } }
}

// pages/api/route.js
import { hasDynamic } from '../../lib'

export default async function handle() {
  hasDynamic()
  return Response.json({ ok: true })
}

export const config = { 
  runtime: 'experimental-edge' ,
  allowDynamic: '/lib/**'
}
```

Playing with `config.allowDynamic`, you should be able to:
- build the app even if it uses `eval()` (it will obviously fail at
runtime)
- build the app that _imports but does not use_ `eval()`
- run the app in dev, even if it uses `eval()` with no warning

### 🆙 Notes to reviewers

Before adding documentation and telemetry, I'd like to collect comments
on a couple of points:
- the overall design for this feature: is a list of globs useful and
easy enough?
- should the globs be relative to the application root (current
implementation) to to the edge route/middleware file?
- (especially to @sokra) is the implementation idiomatic enough? I've
leverage loaders to read the _entry point_ configuration once, then the
ModuleGraph to get it back during the parsing phase. I couldn't re-use
the existing `getExtractMetadata()` facility since it's happening late
after the parsing.
- there's a glitch with `import { ServerRuntime } from '../../types'` in
`get-page-static-info.ts`
([here](https://github.com/vercel/next.js/pull/39539/files#diff-cb7ac6392c3dd707c5edab159c3144ec114eafea92dad5d98f4eedfc612174d2L12)).
I had to use `next/types` because it was failing during lint. Any clue
why?

### ☑️ Checklist

- [ ] 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`
- [x] Integration tests added
- [x] Documentation added
- [x] Telemetry added. In case of a feature if it's used or not.
- [x] Errors have helpful link attached, see `contributing.md`
2022-09-12 15:01:00 -07:00
JJ Kasper
3bf8b2b4fe
Update to detect GSSP with edge runtime during build (#40076)
This updates to handle detecting `getStaticProps`/`getServerSideProps` correctly during build when `experimental-edge` is being used. This also fixes not parsing dynamic route params correctly with the edge runtime and sets up the handling needed for the static generation for app opened in the below mentioned PR.

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

Fixes: [slack thread](https://vercel.slack.com/archives/C0289CGVAR2/p1661554455121189)
x-ref: https://github.com/vercel/next.js/pull/39884
2022-08-30 18:18:02 +00:00
Gal Schlezinger
41d4aa04c4
allow Edge Functions to stream a compressed fetch response (#39608)
When a user tried to have the following Edge Function:

```ts
export default () => fetch("https://example.vercel.sh");
```

The Edge Function were failing.

Why is that?

When `fetch` was called, an implicit `Accept-Encoding` header was added
to allow the origin to return a compressed response. Then, the origin
will set the `Content-Encoding` header in the response, to let the
client know that the body needs to be decompressed in order to be read.

That creates an issue though: `response.body` will be a
`ReadableStream<Uint8Array>`, or, a stream that contains binary data
that decodes into _the uncompressed data_ (or, plain text!).

What it means, is that `response.body` is uncompressed data, while
`response.headers.get('content-encoding')` is marking the response body
as compressed payload. This confuses the HTTP clients and makes them fail.

This commit removes the `content-encoding`, `transfer-encoding` and
`content-length` headers from the response, as the Next.js server _always_
streams Edge Function responses.

## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
2022-08-21 10:43:02 +00:00
Tim Neutkens
4cd8b23032
Enable @typescript-eslint/no-use-before-define for functions (#39602)
Follow-up to the earlier enabling of classes/variables etc.

Bug

 Related issues linked using fixes #number
 Integration tests added
 Errors have helpful link attached, see 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
 Integration tests added
 Documentation added
 Telemetry added. In case of a feature if it's used or not.
 Errors have helpful link attached, see contributing.md

Documentation / Examples

 Make sure the linting passes by running pnpm lint
 The examples guidelines are followed from our contributing doc

Co-authored-by: Steven <steven@ceriously.com>
2022-08-15 10:29:51 -04:00
Tim Neutkens
b5aa571c71
Refactor client entry plugin to separate methods. (#39162)
WIP.


## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)


Co-authored-by: Shu Ding <3676859+shuding@users.noreply.github.com>
2022-08-12 13:01:19 +00:00
Tim Neutkens
db9040b0b8
Enable @typescript-eslint/no-use-before-define variables,enums,typedefs for core files (#39511)
* Enable @typescript-eslint/no-use-before-define typedefs and enums

* Enable variables

* Move in client/index

* Revert "Move in client/index"

This reverts commit 592d70cf3d9cd39e741905faf9229f664c9b4ebd.

* Move wrapApp

* Revert "Revert "Move in client/index""

This reverts commit 14b6105eb45ab87b3b4a1d6f2907d8b9e9657888.

* Fix classes cases
2022-08-11 16:32:52 -05:00
Balázs Orbán
b292bdc293
fix(ts): Middleware type tweaks (#38625)
* fix internal type

* allow `void` to be returned from Middleware

* mark deprecated APIs in JSDoc

* fix typo

* add missing error page

* remove unused import
2022-08-08 09:40:44 -05:00
Kiko Beats
0ebd53fdb5
fix: print Request & Response properties (#38903)
* Add inspect symbol for request

WIP

* Add inspect symbol for response

* build: upgrade edge-runtime
2022-07-27 09:16:16 -05:00
Shu Ding
0831dd59c9
chore: Clean up imports and unused code (#39044)
A small refactor PR to convert some imports to type imports, as well as removing a couple of unused exports.

The Edge SSR loader is also missing the global process injection (`enhanceGlobals`).

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
2022-07-26 21:41:59 +00:00
Javi Velasco
14463ddd10
Update Edge Runtime (#38862)
This PR updates the Edge Runtime to use a new version that loads dependencies differently. This addresses https://github.com/vercel/next.js/pull/38766 so `instanceof` works as expected.

It involved a few code changes, mostly regarding to types. The most important change is that the `Runner` function in the sandbox doesn't take a `ReadableStream` as `body` anymore since this implies creating the instance on "node land" and makes the runtime `fetch` function not to be able to compare with `ReadableStream` using `instanceof`.  Instead we introduce a "clonable body" abstraction that allows to create the `ReadableStream` from `Readable` by using the edge runtime primitive which would hold the correct prototype.

Also, this PR changes the way we pre-compile the Edge Runtime to adapt it to the new version.
2022-07-21 18:29:19 +00:00
Damien Simonin Feugas
90bbac44db
fix(edge): error handling for edge route and middleware is inconsistent (#38401)
## What’s in there?

This PR brings more consistency in how errors and warnings are reported when running code in the Edge Runtime:

- Dynamic code evaluation (`eval()`, `new Function()`, `WebAssembly.instantiate()`, `WebAssembly.compile()`…)
- Usage of Node.js global APIs (`BroadcastChannel`, `Buffer`, `TextDecoderStream`, `setImmediate()`...)
- Usage of Node.js modules (`fs`, `path`, `child_process`…)

The new error messages should mention *Edge Runtime* instead of *Middleware*, so they are valid in both cases.

It also fixes a bug where the process polyfill would issue a warning for  `process.cwd` (which is `undefined` but legit). Now, one has to invoke the function `process.cwd()` to trigger the error.

It finally fixes the react-dev-overlay, where links from middleware and Edge API route files could not be opened because of the `(middleware)/` prefix in their name.

About the later, please note that we can’t easily remove the prefix or change it for Edge API routes. It comes from the Webpack layer, which is the same for both. We may consider renaming it to *edge* instead in the future.

## How to test?

These changes are almost fully covered with tests:

```bash
pnpm testheadless --testPathPattern runtime-dynamic
pnpm testheadless --testPathPattern runtime-with-node
pnpm testheadless --testPathPattern runtime-module
pnpm testheadless --testPathPattern middleware-dev-errors
```

To try them out manually, you can write a middleware and Edge route files like these:

```jsx
// middleware.js
import { NextResponse } from 'next/server'
import { basename } from 'path'

export default async function middleware() {
  eval('2+2')
  setImmediate(() => {})
  basename()
  return NextResponse.next()
}

export const config = { matcher: '/' }
```

```jsx
// pages/api/route.js
import { basename } from 'path'

export default async function handle() {
  eval('2+2')
  setImmediate(() => {})
  basename()
  return Response.json({ ok: true })
}

export const config = { runtime: 'experimental-edge' }
```

The expected behaviours are:

- [x] dev, middleware/edge route is using a node.js module: error at runtime (logs + read-dev-overlay):

```bash
error - (middleware)/pages/api/route.js (1:0) @ Object.handle [as handler]
error - The edge runtime does not support Node.js 'path' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
> 1 | import { basename } from "path";
  2 | export default async function handle() {
```

- [x] build, middleware/edge route is using a node.js module: warning but succeeds

```bash
warn  - Compiled with warnings

./middleware.js
A Node.js module is loaded ('path' at line 4) which is not supported in the Edge Runtime.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

./pages/api/route.js
A Node.js module is loaded ('path' at line 1) which is not supported in the Edge Runtime.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
```

- [x] production, middleware/edge route is using a node.js module: error at runtime (logs + 500 error)

```bash
Error: The edge runtime does not support Node.js 'path' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
    at <unknown> (file:///Users/damien/dev/next.js/packages/next/server/web/sandbox/context.ts:149)
```

- [x] dev, middleware/edge route is using a node.js global API: error at runtime (logs + read-dev-overlay):

```bash
error - (middleware)/pages/api/route.js (4:2) @ Object.handle [as handler]
error - A Node.js API is used (setImmediate) which is not supported in the Edge Runtime.
Learn more: https://nextjs.org/docs/api-reference/edge-runtime
  2 |
  3 | export default async function handle() {
> 4 |   setImmediate(() => {})
    |  ^
```

- [x] build, middleware/edge route is using a node.js global API: warning but succeeds

```bash
warn  - Compiled with warnings

./middleware.js
A Node.js API is used (setImmediate at line: 6) which is not supported in the Edge Runtime.
Learn more: https://nextjs.org/docs/api-reference/edge-runtime

./pages/api/route.js
A Node.js API is used (setImmediate at line: 3) which is not supported in the Edge Runtime.
Learn more: https://nextjs.org/docs/api-reference/edge-runtime
```

- [x] production, middleware/edge route is using a node.js module: error at runtime (logs + 500 error)

```bash
Error: A Node.js API is used (setImmediate) which is not supported in the Edge Runtime.
Learn more: https://nextjs.org/docs/api-reference/edge-runtime
    at <unknown> (file:///Users/damien/dev/next.js/packages/next/server/web/sandbox/context.ts:330)
```

- [x] dev, middleware/edge route is loading dynamic code: warning at runtime (logs + read-dev-overlay) and request succeeds (we allow dynamic code in dev only):

```bash
warn  - (middleware)/middleware.js (7:2) @ Object.middleware [as handler]
warn  - Dynamic Code Evaluation (e. g. 'eval', 'new Function') not allowed in Edge Runtime
   5 |
   6 | export default async function middleware() {
>  7 |   eval('2+2')
```

- [x] build, middleware/edge route is loading dynamic code: build fails with error:

```bash
Failed to compile.

./middleware.js
Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime
Used by default

./pages/api/route.js
Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in Edge Runtime
Used by default
```

## Notes to reviewers

Edge-related errors are either issued from `next/server/web/sandbox/context.ts` file (runtime errors) or from `next/build/webpack/plugins/middleware-plugin.ts` (webpack compilation).

The previous implementation (I’m pleading guilty here) was way too verbose: some errors (Node.js global APIs like using `process.cwd()`) could be reported several times, and the previous mechanism to dedupe them (in middleware-plugin) wasn’t really effective.

Changes in tests are due to renaming existing tests such as `test/integration/middleware-with-node.js-apis` into `test/integration/edge-runtime-with-node.js-apis`. I extended them to cover Edge API route.

@hanneslund I’ve pushed the improvement you did in https://github.com/vercel/next.js/pull/38289/ one step further to avoid duplication.
2022-07-21 14:53:23 +00:00
Damien Simonin Feugas
851e9aeba9
fix(edge-runtime): undefined global in edge runtime. (#38769)
## How to reproduce

1. create a next.js app with a middleware (or an edge route) that imports a node.js module:
   ```js
   // middleware.js
   import { NextResponse } from 'next/server'
   import { basename } from 'path'
   
   export default async function middleware() {
     basename()
     return NextResponse.next()
   }
   ```
2. deploy it to vercel with `vc`
3. go to the your function logs in Vercel Front (https://vercel.com/$user/$project/$deployment/functions)
4. in another tab, query your application
   > it results in a 500 page:
   <img width="517" alt="image" src="https://user-images.githubusercontent.com/186268/179557102-72568ca9-bcfd-49e2-9b9c-c51c3064f2d7.png">

    >  in the logs you should see:
   <img width="1220" alt="image" src="https://user-images.githubusercontent.com/186268/179557266-498f3290-b7df-46ac-8816-7bb396821245.png">

## Expected behavior

The route should fail indeed in a 500, because Edge runtime **does not support node.js modules**. However the error in logs should be completely different:
```shell
error - Error: The edge runtime does not support Node.js 'path' module.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime
```

## Notes to reviewers

I introduced this issue in #38234.
Prior to the PR above, the app would not even build, as we were checking imported node.js module during the build with AST analysis.
Since #38234, the app would build and should fail at runtime, with an appropriate error.

The mistake was to declare `__import_unsupported` function in the sandbox's context, that is only used in `next dev` and `next start`, but not shipped to Vercel platform.

By loading it inside webpack loaders (both middleware and edge route), we ensure it will be defined on Vercel as well. 

The existing test suite (`pnpm testheadless --testPathPattern=runtime-module-error`) covers them.
2022-07-20 14:53:27 +00:00
Gal Schlezinger
20486c159d
[edge] allow importing blob assets (#38492)
* [edge] allow importing blob assets

* Fix test

* extract to a new file, to make it easier to read and review

* Use webpack asset discovery and transform with a loader

* fix tests

* don't prefix assets

* use emitFile

* rename assets to blobs to be more specific

* rename blobs to assets and use webpack's hashing algo

* Dedupe correctly

* Add a Node.js dep test

* Update packages/next/server/next-server.ts

Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>

* [code review] test remote URL fetches

* [code review] use `import type` for type-only imports

* Update packages/next/server/next-server.ts

Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>

* Apply suggestions from code review

Co-authored-by: JJ Kasper <jj@jjsweb.site>

Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-07-19 12:27:15 -05:00
Damien Simonin Feugas
6e2c3821cf
feat: build edge functions with node.js modules and fail at runtime (#38234)
## What's in there?

The Edge runtime [does not support Node.js modules](https://edge-runtime.vercel.app/features/available-apis#unsupported-apis).
When building Next.js application, we currently fail the build when detecting node.js module imported from middleware.

This is an blocker for using code that is conditionally loading node.js modules (based on platform/env detection), as @cramforce reported.

This PR implements a new strategy where:
- we can build such middleware/Edge API route code **with a warning**
- we fail at run time, with graceful errors in dev (console & react-dev-overlay error)
- we fail at run time, with console errors in production

## How to test?

All cases are covered with integration tests.
To try them live, create a simple app with a page, a `middleware.js` file and a `pages/api/route.js`file.
Here are iconic examples:

### node.js modules
```js
// middleware.js
import { NextResponse } from 'next/server'
// static
import { basename } from 'path'

export default async function middleware() {
  // dynamic
  const { basename } = await import('path')
  basename()
  return NextResponse.next()
}

export const config = { matcher: '/' }
```
```js
// pags/api/route.js
// static
import { isAbsolute } from 'path'

export default async function handle() {
  // dynamic
  const { isAbsolute } = await import('path')
  return Response.json({ useNodeModule: isAbsolute('/test') })
}

export const config = { runtime: 'experimental-edge' }
```

Desired error (+ source code highlight in dev):

> The edge runtime does not support Node.js 'path' module
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

Desired warning at build time:

> A Node.js module is loaded ('path' at line 2) which is not supported in the Edge Runtime.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

- [x]  in dev middleware, static, shows desired error on stderr
- [x]  in dev route, static, shows desired error on stderr
- [x]  in dev middleware, dynamic, shows desired error on stderr
- [x]  in dev route, dynamic, shows desired error on stderr
- [x]  in dev middleware, static, shows desired error on react error overlay
- [x]  in dev route, static, shows desired error on react error overlay
- [x]  in dev middleware, dynamic, shows desired error on react error overlay
- [x]  in dev route, dynamic, shows desired error on react error overlay
- [x]  builds middleware successfully, shows build warning, shows desired error on stderr on call
- [x]  builds route successfully, shows build warning, shows desired error on stderr on call

### 3rd party modules not found

```js
// middleware.js
import { NextResponse } from 'next/server'
// static
import Unknown from 'unknown'

export default async function middleware() {
  // dynamic
  const Unknown = await import('unknown')
  new Unknown()
  return NextResponse.next()
}
```
export const config = { matcher: '/' }
```
```js
// pags/api/route.js
// static
import Unknown from 'unknown'

export default async function handle() {
  // dynamic
  const Unknown = await import('unknown')
  return Response.json({ use3rdPartyModule: Unknown() })
}

export const config = { runtime: 'experimental-edge' }
```

Desired error (+ source code highlight in dev):

> Module not found: Can't resolve 'does-not-exist'
Learn More: https://nextjs.org/docs/messages/module-not-found

- [x]  in dev middleware, static, shows desired error on stderr
- [x]  in dev route, static, shows desired error on stderr
- [x]  in dev middleware, dynamic, shows desired error on stderr
- [x]  in dev route, dynamic, shows desired error on stderr
- [x]  in dev middleware, static, shows desired error on react error overlay
- [x]  in dev route, static, shows desired error on react error overlay
- [x]  in dev middleware, dynamic, shows desired error on react error overlay
- [x]  in dev route, dynamic, shows desired error on react error overlay
- [x]  fails to build middleware, with desired error on stderr
- [x]  fails to build route, with desired error on stderr

### unused node.js modules
```js
// middleware.js
import { NextResponse } from 'next/server'

export default async function middleware() {
  if (process.exit) {
    const { basename } = await import('path')
    basename()
  }
  return NextResponse.next()
}
```
```js
// pags/api/route.js
export default async function handle() {
  if (process.exit) {
    const { basename } = await import('path')
    basename()
  }
  return Response.json({ useNodeModule: false })
}

export const config = { runtime: 'experimental-edge' }
```

Desired warning at build time:

> A Node.js module is loaded ('path' at line 2) which is not supported in the Edge Runtime.
Learn More: https://nextjs.org/docs/messages/node-module-in-edge-runtime

- [x]  invoke middleware in dev with no error
- [x]  invoke route in dev with no error
- [x]  builds successfully, shows build warning, invoke middleware with no error
- [x]  builds successfully, shows build warning, invoke api-route with no error

## Notes to reviewers

The strategy to implement this feature is to leverages webpack [externals](https://webpack.js.org/configuration/externals/#externals) and run a global `__unsupported_module()` function when using a node.js module from edge function's code.
For the record, I tried using [webpack resolve.fallback](https://webpack.js.org/configuration/resolve/#resolvefallback) and [Webpack.IgnorePlugin](https://webpack.js.org/plugins/ignore-plugin/) but they do not allow throwing proper errors at runtime that would contain the loaded module name for reporting.

`__unsupported_module()` is defined in `EdgeRuntime`, and returns a proxy that's throw on use (whether it's property access, function call, new operator... synchronous & promise-based styles).

However there's an issue with error reporting: webpack does not includes the import lines in the generated sourcemaps, preventing from displaying useful errors.
I extended our middleware-plugin to supplement the sourcemaps (when analyzing edge function code, it saves which module is imported from which file, together with line/column/source)

The react-dev-overlay was adapted to look for this additional information when the caught error relates to modules, instead of looking at sourcemaps.

I removed the previous mechanism (built by @nkzawa ) which caught webpack errors at built time to change the displayed error message (files `next/build/index.js`, `next/build/utils.ts` and `wellknown-errors-plugin`)
2022-07-06 20:54:44 +00:00
Hannes Bornö
469c5030ba
Display stack trace when error occurs in API route (#38289)
## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
2022-07-05 21:33:58 +00:00
Javi Velasco
ca621ced66
Add init to some NextResponse methods (#38071)
* Add `init` to some `NextResponse` methods

* Add NextResponse.redirect test and fix headers

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-06-27 18:39:00 -05:00
Gal Schlezinger
92915e47f7
Remove NextResponse.json as we already have it defined from inheriting Response (#37887)
Lately, `Response.json` was introduced as a standard static method.
That means we can remove our implementation of `NextResponse.json` piggyback on `Response.json`


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-06-22 16:03:31 +00:00
JJ Kasper
122899bd37
Add hard navigation guard and fix middleware rewrite cases (#37815)
This adds a guard for whenever we do a hard navigation over a client-navigation to ensure we aren't redirecting to the same URL that we are currently on as this can cause infinite redirecting. This also fixes some cases with middleware rewrites without i18n enabled and expands our middleware suite to test both with i18n and without. 

This also fixes a race condition with the query updating where a user could attempt a route transition and it then gets overridden by the query updating and prevents firing router events during the query updating as these can be false signals of a transition.

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

Fixes: https://github.com/vercel/next.js/issues/37804
2022-06-20 11:31:19 +00:00
Damien Simonin Feugas
c2b8006485
refactor(middleware): leverages edge-runtime builtins to decorate errors in dev (#37718)
### What's in there?

This is a followup of https://github.com/vercel/next.js/pull/37695.
For the dev server to clean stacktraces, we're decorating errors caught during code evaluation (`getServerSideProps` or middleware).
However, when these errors are asynchronously raised, we can't decorate them before processing them, leading to this fallback logic:

bf7bf8217f/packages/next/server/dev/next-dev-server.ts (L775-L779)

Thanks to latest improvement of the edge-runtime in 1.1.0-beta.4, we can now catch unhandled rejection and uncaught exception, and decorate them.

### How to test?

Please reuse the existing tests who already covered these cases:
`pnpm testheadless --testPathPattern middleware-dev-errors`


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-06-17 15:06:30 +00:00
Javi Velasco
2d5d43fb75
Refactor server routing (#37725)
This PR fixes an issue where we have a middleware that rewrites every single request to the same origin while having `i18n` configured. It would be something like: 

```typescript
import { NextResponse } from 'next/server'

export function middleware(req) {
  return NextResponse.rewrite(req.nextUrl)
}
```

In this case we are going to be adding always the `locale` at the beginning of the destination since it is a rewrite. This causes static assets to not match and the whole application to break. I believe this is a potential footgun so in this PR we are addressing the issue by removing the locale from pathname for those cases where we check against the filesystem (e.g. public folder).

To achieve this change, this PR introduces some preparation changes and then a refactor of the logic in the server router. After this refactor we are going to be relying on properties that can be defined in the `Route` to decide wether or not we should remove the `basePath`, `locale`, etc instead of checking which _type_ of route it is that we are matching.

Overall this simplifies quite a lot the server router. The way we are testing the mentioned issue is by adding a default rewrite in the rewrite tests middleware.
2022-06-16 21:43:01 +00:00
Seiya Nuta
0bf9233e14
[middleware] Warn dynamic WASM compilation (#37681)
In Middlewares, dynamic code execution is not allowed. Currently, we warn if eval / new Function are invoked in dev but don't warn another dynamic code execution in WebAssembly.

This PR adds warnings for `WebAssembly.compile` and `WebAssembly.instantiate` with a buffer parameter (note that `WebAssembly.instantiate` with a **module** parameter is legit) invocations. Note that other methods that compile WASM dynamically such as `WebAssembly.compileStreaming` are not exposed to users so we don't need to cover them.



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [x] Integration tests added
- [x] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [x] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-06-16 14:59:30 +00:00
JJ Kasper
bf7bf8217f
Ensure navigating with middleware parses route params correctly (#37704) 2022-06-15 09:09:51 -05:00
Javi Velasco
de7b316446
Improve Middleware errors (#37695)
* Improve stack traces in dev mode

* Refactor `react-dev-overlay` to support the Edge Compiler

* Serialize errors including the compiler `source`

* Adopt the new `react-dev-overlay` displaying it for middleware errors

* Improve tests

* fix rsc cases

* update test

* use check for dev test

* handle different error from node version

Co-authored-by: feugy <damien@vercel.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-06-14 19:58:13 -05:00
JJ Kasper
607ff2b322
Update to process redirects/rewrites for _next/data with middleware (#37574)
* Update to process redirects/rewrites for _next/data

* correct matched-path resolving with middleware

* Add next-data header

* migrate middleware tests

* lint-fix

* update error case

* update test case

* Handle additional resolving cases and add more tests

* update test from merge

* fix test

* rm .only

* apply changes from review

* ensure _next/data resolving does not apply without middleware
2022-06-10 12:35:12 -05:00
Kiko Beats
76083210ed
Middleware: remove req.ua (#37512)
This PR moves the internal logic associated with `req.ua` into an explicit method the user should to call to have the same behavior.

**before**

```typescript
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
export function middleware(request: NextRequest) {
  const url = request.nextUrl
  const viewport = request.ua.device.type === 'mobile' ? 'mobile' : 'desktop'
  url.searchParams.set('viewport', viewport)
  return NextResponse.rewrites(url)
}
```

**after**

```typescript
// middleware.ts
import { NextRequest, NextResponse, userAgent } from 'next/server'
export function middleware(request: NextRequest) {
  const url = request.nextUrl
  const { device } = userAgent(request)
  const viewport = device.type === 'mobile' ? 'mobile' : 'desktop'
  url.searchParams.set('viewport', viewport)
  return NextResponse.rewrites(url)
}
```

This potentially will save the extra 17 kB related to the size of `ua-parser-js`
2022-06-09 11:10:21 +00:00
Javi Velasco
7584b02b34
Remove Middleware Preflight (#37490)
* Refactor data fetching to support getting headers

* Relax `getNextPathnameInfo` type

* Add test for middleware internal redirects

* Export `ParsedRelativeUrl` type

* Refactor `getMiddlewareEffects`

* Move rewrite i18n test to middleware rewrite tests

* Fix bug parsing pathname info

* Normalize data requests to page requests for middleware

* Ensure there is a header `x-nextjs-matched-path` for middleware rewrites on data requests

* Extract `getDataHref` to a function

* Stop using `getDataHref` for flight

* Always set the query in `dataHref` independently of if it is SSG

* Add test for recursive rewrites

* Refactor dynamicPath validation to `matchHrefAndAsPath`

* Add `dataHref` to `FetchDataOutput`

* Extract `matchesMiddleware` function

* Add `hasMiddleware` option to `fetchNextData`

* Move preflight test

* Remove preflight test

* Add middleware prefetch tests

* Remove preflight

* Attempt to reduce bundle size

Include `withMiddlewareEffects` and `matchHrefAndAsPath` into `router`

Bring `getDataHref` back to `page-loader`

Bring `resolveDynamicRoute` back to `router`

* Reduce arg duplication for `withMiddlewareEffects`

* Remove some async/await and spreads to reduce bundle size

* Upgrade `edge-runtime` & clone `Request` on redirects to mutate headers

* Add some rewrite tests

Co-authored-by: Kiko Beats <josefrancisco.verdu@gmail.com>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-06-08 10:41:28 -05:00
Gal Schlezinger
88d0440ad4
[middleware] Support any method when fetching a Request instance (#37540)
There was a bug that ignored `Request` options when one was given to the `fetch` function:

```ts
const request = new Request("https://example.vercel.sh", { method: "POST" });
await fetch(request);
```

The code above was expected to make a `POST` request, but instead it
made a `GET` request.

This commit fixes it and adds some tests to verify that fetching with a
`Request` object works as expected, and therefore resolves #37123.

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
2022-06-08 11:00:49 +00:00
Kiko Beats
129052dc98
Edge Functions: deprecate access to request.page (#37349)
It uses `URLSearchParams` to have the same behavior.

closes https://github.com/vercel/next.js/issues/34521
2022-06-01 20:06:37 +00:00
Kiko Beats
fafbea8b74
Use Edge Runtime for running Edge Functions locally (#37024)
This PR introduces [Edge Runtime](https://edge-runtime.vercel.app/) for emulating [Edge Functions](https://vercel.com/features/edge-functions) locally.

Every time you run a [middleware](https://nextjs.org/docs/advanced-features/middleware) locally via `next dev`, an isolated edge runtime context will be created.

These contexts have the same constraints as production servers, plus they don't pollute the global scope; Instead, all the code run in a vm on top of a Node.js process.

Additionally, `@edge-runtime/jest-environment` has been added to make easier testing Edge Functions in a programmatic way.

It dropped the following polyfills from Next.js codebase, since they are now part of Edge Runtime:

- abort-controller
- formdata
- uuid
- web-crypto
- web-streams

Co-authored-by: Gal Schlezinger <2054772+Schniz@users.noreply.github.com>
2022-05-30 12:01:36 +00:00
Javi Velasco
523704b83f
Execute middleware on Next.js internal requests (#37121)
* Do not exclude internal _next request in middleware

* Allow for `NextURL` to parse prefetch requests

* Add test for middleware data prefetch

* Refactor `hasBasePath` and `replaceBasePath`

* Refactor `removeTrailingSlash`

* Refactor parsed next url to use `getNextPathnameInfo`

* Allow to configure `NextURL`

* Ensure middleware rewrites with always with a locale

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-05-27 13:29:04 -05:00
Damien Simonin Feugas
4e6b6a5b86
feat(middleware): issues warnings when using node.js global APIs in middleware (#36980) 2022-05-23 11:07:26 +02:00
Gáspár Körtesi
863db9b0e2
keep method when cloning Request, fixes #36522 (#36539)
keep method when cloning Request

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-05-22 12:58:17 -05:00
Damien Simonin Feugas
bf089562c7
feat(middleware)!: forbids middleware response body (#36835)
_Hello Next.js team! First PR here, I hope I've followed the right practices._

### What's in there?

It has been decided to only support the following uses cases in Next.js' middleware:
- rewrite the URL (`x-middleware-rewrite` response header)
- redirect to another URL (`Location` response header)
- pass on to the next piece in the request pipeline (`x-middleware-next` response header)

1. during development, a warning on console tells developers when they are returning a response (either with `Response` or `NextResponse`).
2. at build time, this warning becomes an error.
3. at run time, returning a response body will trigger a 500 HTTP error with a JSON payload containing the detailed error.

All returned/thrown errors contain a link to the documentation.

This is a breaking feature compared to the _beta_ middleware implementation, and also removes `NextResponse.json()` which makes no sense any more.

### How to try it?
- runtime behavior: `HEADLESS=true yarn jest test/integration/middleware/core`
- build behavior : `yarn jest test/integration/middleware/build-errors`
- development behavior: `HEADLESS=true yarn jest test/development/middleware-warnings`

### Notes to reviewers

The limitation happens in next's web adapter. ~The initial implementation was to check `response.body` existence, but it turns out [`Response.redirect()`](https://github.com/vercel/next.js/blob/canary/packages/next/server/web/spec-compliant/response.ts#L42-L53) may set the response body (https://github.com/vercel/next.js/pull/31886). Hence why the proposed implementation specifically looks at response headers.~
`Response.redirect()` and `NextResponse.redirect()` do not need to include the final location in their body: it is handled by next server https://github.com/vercel/next.js/blob/canary/packages/next/server/next-server.ts#L1142

Because this is a breaking change, I had to adjust several tests cases, previously returning JSON/stream/text bodies. When relevant, these middlewares are returning data using response headers.

About DevEx: relying on AST analysis to detect forbidden use cases is not as good as running the code.
Such cases are easy to detect:
```js
new Response('a text value')
new Response(JSON.stringify({ /* whatever */ })
```
But these are false-positive cases:
```js
function returnNull() { return null }
new Response(returnNull())

function doesNothing() {}
new Response(doesNothing())
```
However, I see no good reasons to let users ship middleware such as the one above, hence why the build will fail, even if _technically speaking_, they are not setting the response body. 



## Feature

- [x] 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`
- [x] Integration tests added
- [x] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [x] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [x] Make sure the linting passes by running `yarn lint`
2022-05-19 22:02:20 +00:00
Kiko Beats
cc8ab99a92
Edge Cookies: Add .getWithOptions method (#36943)
Hello,

This is an iteration after first work at https://github.com/vercel/next.js/pull/36478.

What that PR missed is a way to just get a cookie value. Well, this PR adds two new things:

`cookies.get` returns the cookie value that could be `string | undefined`:

```js
const response = new NextResponse()
response.cookies.set('foo', 'bar', { path: '/test' })

const value = response.cookies.get('foo')
console.log(value) // => 'bar'
```

Additionally, if you want to know all the cookie details, you can use `cookies.getWithOptions`:

```js
const response = new NextResponse()

response.cookies.set('foo', 'bar', { path: '/test' })
const { value, options } response.cookies.getWithOptions('foo')

console.log(value) // => 'bar'
console.log(options) // => { Path: '/test' }
```
2022-05-19 13:04:58 +00:00
Steven
d67baa0d1f
Fix return type of middleware req.cookies.get() (#36872)
Follow up to #36478 

Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-05-12 21:44:06 +00:00
Kiko Beats
b78c28f7a0
feat: better cookies API for Edge Functions (#36478)
This PR introduces a more predictable API to manipulate cookies in an Edge Function context.

```js
const response = new NextResponse()

// set a cookie
response.cookies.set('foo, 'bar') // => set-cookie: 'foo=bar; Path=/'`

// set another cookie
response.cookies.set('fooz, 'barz') // => set-cookie: 'foo=bar; Path=/, fooz=barz; Path=/'`

// delete a cookie means mark it as expired
response.cookies.delete('foo') // => set-cookie: 'foo=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT, fooz=barz; Path=/'`

// clear all cookies means mark all of them as expired
response.cookies.clear() // => set-cookie: 'fooz=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT, foo=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT'`
``` 

This new cookies API uses [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) interface, and it's available for `NextRequest` and `NextResponse`.

Additionally, you can pass a specific cookies option as a third argument in `set` method:

```js
response.cookies.set('foo', 'bar', {
  path: '/',
  maxAge: 60 * 60 * 24 * 7,
  httpOnly: true,
  sameSite: 'strict',
  domain: 'example.com'
}
```

**Note**: `maxAge` it's in seconds rather than milliseconds.

Any cookie manipulation will be reflected over the `set-cookie` header, transparently.

closes #31719
2022-05-09 09:50:32 +00:00
Javi Velasco
0de109baab
Refactor Page Paths utils and Middleware Plugin (#36576)
This PR brings some significant refactoring in preparation for upcoming middleware changes. Each commit can be reviewed independently, here is a summary of what each one does and the reasoning behind it:
- [Move pagesDir to next-dev-server](f2fe154c00) simply moves the `pagesDir` property to the dev server which is the only place where it is needed. Having it for every server is misleading.
- [Move (de)normalize page path utils to a file page-path-utils.ts](27cedf0871) Moves the functions to normalize and denormalize page paths to a single file that is intended to hold every utility function that transforms page paths. Since those are complementary it makes sense to have them together. I also added explanatory comments on why they are not idempotent and examples for input -> output that I find very useful.
- [Extract removePagePathTail](6b121332aa) This extracts a function to remove the tail on a page path (absolute or relative). I'm sure there will be other contexts where we can use it.
- [Extract getPagePaths and refactor findPageFile](cf2c7b842e) This extracts a function `getPagePaths` that is used to generate an array of paths to inspect when looking for a page file from `findPageFile`. Then it refactors such function to use it parallelizing lookups. This will allow us to print every path we look at when looking for a file which can be useful for debugging. It also adds a `flatten` helper. 
- [Refactor onDemandEntryHandler](4be685c37e) I've found this one quite difficult to understand so it is refactored to use some of the previously mentioned functions and make it easier to read.
- [Extract absolutePagePath util](3bc0783474) Extracts yet another util from the `next-dev-server` that transforms an absolute path into a page name. Of course it adds comments, parameters and examples.
- [Refactor MiddlewarePlugin](c595a2cc62) This is the most significant change. The logic here was very hard to understand so it is totally redistributed with comments. This also removes a global variable `ssrEntries` that was deprecated in favour of module metadata added to Webpack from loaders keeping less dependencies. It also adds types and makes a clear distinction between phases where we statically analyze the code, find metadata and generate the manifest file cc @shuding @huozhi 

EDIT: 
- [Split page path utils](158fb002d0) After seeing one of the utils was being used by the client while it was defined originally in the server, with this PR we are splitting the util into multiple files and moving it to `shared/lib` in order to make explicit that those can be also imported from client.
2022-04-30 11:19:27 +00:00
Jiachi Liu
d5e767b20d
Add process env NEXT_RUNTIME (#36383)
* To help determine the current running environment is in server nodejs / edge runtime
* Remove usage of `process.browser`
2022-04-26 17:54:28 +00:00
Naoyuki Kanezawa
a6282566f9
Do not polyfill node built-in modules on edge functions (#36190)
As the title. This is intended to be applied on both middleware and edge functions.

## Bug

- [ ] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`


Co-authored-by: Jiachi Liu <4800338+huozhi@users.noreply.github.com>
2022-04-25 09:25:27 +00:00
Kiko Beats
8f8e497e1b
fix(NextResponse.json): pass options (#35367) 2022-04-15 22:23:42 -05:00
Steven
4c15f89b53
Add support for tsconfig moduleResolution node | node12 | nodenext (#36189)
- Fixes #35572 

Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-04-15 17:09:12 +00:00
Preston Richey
a5103d2e34
Add support for catch-all route params in NextRequest page type declaration (#36137)
fixes https://github.com/vercel/next.js/issues/36136

## Bug

- [X] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
2022-04-13 23:08:53 +00:00
Naoyuki Kanezawa
1d8165bd79
fix: do not add locale prefix to api route on NextURL (#36118)
Fixes https://github.com/vercel/next.js/issues/35694

## Bug

- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
2022-04-13 15:30:03 +00:00
Kiko Beats
46d3f0e216
fix(next-url): print properly using logger symbol (#36097)
Hello,

This PR adds a method to have a custom inspect for `NextURL`

closes #35519
2022-04-12 15:31:29 +00:00
Shu Ding
049bb22c1c
Update polyfill of web streams (#35571)
* attach pipeTo and pipeThrough polyfills to instance

* remove transformer polyfill

* remove polyfill

* fix missing polyfill in sandbox

* always polyfill the runtime

* always polyfill web streams in renderer

* fix missing AbortController and AbortSignal

* type fix

* fix type generation

* use global

Co-authored-by: Shu Ding <shu@shus-mac-studio.localdomain>
2022-04-07 16:26:30 +02:00
Seth Falco
ad7cb3b207
fix: don't override user-agent in fetch if specified (#35547)
* fix: don't override user-agent in fetch if specified

* Add test for fetch user-agent in middleware

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-03-28 18:04:21 -05:00
Luis Alvarez D
5d1f33f5c4
Add deprecated JSDoc comments for the previous middleware signature (#35448)
Something I noticed while using Middleware is that the older and no longer working methods are still accessible for the `event` with autocompletion because of their types, and the way of knowing they're deprecated is by running the app and seeing the error message, this should improve that when coding in tools like VS Code.

## 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`
- [ ] Integration tests added
- [x] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`


Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>
2022-03-28 21:15:08 +00:00
Malte Ubl
6da769129e
Reduce hello-world middleware bundle size from 128k to 88k (#35512)
Moves two utility functions from `server/router.ts` into their own file. This avoids the middleware pulling in the full Next.js router into its bundle.

There are probably more opportunities like this, but this is a good start. Middleware should likely be bundled by a non-chunking optimizing compiler.
2022-03-22 14:54:05 +00:00
Shu Ding
757a0c7082
Abstract out stream related utils from render and web/utils (#35372)
The `readableStreamTee` util is only used by server/render.tsx, but ended up in the middleware runtime bundle. So it's better to add all the utils in one place, and we can remove them once upstream implementation of ReadableStream is ready.

## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `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`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
2022-03-17 23:21:16 +00:00