Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Remove deprecated features and enable future flag (vercel#26066)
Browse files Browse the repository at this point in the history
- Enables excludeDefaultMomentLocales by default
- Adds distDir cleaning (See RFC vercel#6009)
- Adds support for `PORT`
- Removes `router.events` from the server-side router as it should not be used server-side (long-standing todo that is potentially breaking). Note that it's still available as `Router.events` (import Router from 'next/router') and with `useRouter` in `useEffect`. Using it with `useEffect` is the correct way and I've updated the upgrading guide to reflect that
- Added webpack 5 to the upgrading guide
- Removed `Head.rewind` as it's been a no-op since Next.js 9.5 and can now be safely removed from user code

Fixes vercel#11408 
Fixes vercel#10338
Fixes vercel#5554



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added

## Feature

- [x] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [x] 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.

## Documentation / Examples

- [ ] Make sure the linting passes
  • Loading branch information
timneutkens authored Jun 14, 2021
1 parent ef59147 commit f47ee59
Show file tree
Hide file tree
Showing 21 changed files with 252 additions and 25 deletions.
18 changes: 17 additions & 1 deletion docs/api-reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,15 @@ The application will start at `http://localhost:3000` by default. The default po
npx next dev -p 4000
```

Similarly, you can also set the hostname to be different from the default of `0.0.0.0`, this can be useful for making the application available for other devices on the network. The default hostname can be changed with `-H`, like so:
Or using the `PORT` environment variable:

```bash
PORT=4000 npx next dev
```

> Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized.
You can also set the hostname to be different from the default of `0.0.0.0`, this can be useful for making the application available for other devices on the network. The default hostname can be changed with `-H`, like so:

```bash
npx next dev -H 192.168.1.2
Expand All @@ -90,6 +98,14 @@ The application will start at `http://localhost:3000` by default. The default po
npx next start -p 4000
```

Or using the `PORT` environment variable:

```bash
PORT=4000 npx next start
```

> Note: `PORT` can not be set in `.env` as booting up the HTTP server happens before any other code is initialized.
## Lint

`next lint` runs ESLint for all files in the `pages`, `components`, and `lib` directories. It also
Expand Down
65 changes: 65 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ Or using `yarn`:
yarn add react@latest react-dom@latest
```

### Webpack 5

Webpack 5 is now the default for all Next.js applications. If you did not have custom webpack configuration your application is already using webpack 5. If you do have custom webpack configuration you can refer to the [Next.js webpack 5 documentation](https://nextjs.org/docs/messages/webpack5) for upgrading guidance.

### Cleaning the `distDir` is now a default

The build output directory (defaults to `.next`) is now cleared by default except for the Next.js caches. You can refer to [the cleaning `distDir` RFC](https://github.com/vercel/next.js/discussions/6009) for more information.

If your application was relying on this behavior previously you can disable the new default behavior by adding the `cleanDistDir: false` flag in `next.config.js`.

### `PORT` is now supported for `next dev` and `next start`

Next.js 11 supports the `PORT` environment variable to set the port the application has to run on. Using `-p`/`--port` is still recommended but if you were prohibited from using `-p` in any way you can now use `PORT` as an alternative:

Example:

```
PORT=4000 next start
```

### Remove `super.componentDidCatch()` from `pages/_app.js`

The `next/app` component's `componentDidCatch` has been deprecated since Next.js 9 as it's no longer needed and has since been a no-op, in Next.js 11 it has been removed.
Expand Down Expand Up @@ -52,6 +72,51 @@ This option hasn't been mentioned in the documentation since Next.js 8 so it's l

If you application does use `modules` and `render` you can refer to [the documentation](https://nextjs.org/docs/messages/next-dynamic-modules).

### Remove `Head.rewind`

`Head.rewind` has been a no-op since Next.js 9.5, in Next.js 11 it was removed. You can safely remove your usage of `Head.rewind`.

### Moment.js locales excluded by default

Moment.js includes translations for a lot of locales by default. Next.js now automatically excludes these locales by default to optimize bundle size for applications using Moment.js.

To load a specific locale use this snippet:

```js
import moment from 'moment'
import 'moment/locale/ja'

moment.locale('ja')
```

You can opt-out of this new default by adding `excludeDefaultMomentLocales: false` to `next.config.js` if you do not want the new behavior, do note it's highly recommended to not disable this new optimization as it significantly reduces the size of Moment.js.

### Update usage of `router.events`

In case you're accessing `router.events` during rendering, in Next.js 11 `router.events` is no longer provided during pre-rendering. Ensure you're accessing `router.events` in `useEffect`:

```js
useEffect(() => {
const handleRouteChange = (url, { shallow }) => {
console.log(
`App is changing to ${url} ${
shallow ? 'with' : 'without'
} shallow routing`
)
}

router.events.on('routeChangeStart', handleRouteChange)

// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleRouteChange)
}
}, [router])
```

If your application uses `router.router.events` which was an internal property that was not public please make sure to use `router.events` as well.

## React 16 to 17

React 17 introduced a new [JSX Transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) that brings a long-time Next.js feature to the wider React ecosystem: Not having to `import React from 'react'` when using JSX. When using React 17 Next.js will automatically use the new transform. This transform does not make the `React` variable global, which was an unintended side-effect of the previous Next.js implementation. A [codemod is available](/docs/advanced-features/codemods.md#add-missing-react-import) to automatically fix cases where you accidentally used `React` without importing it.
Expand Down
4 changes: 4 additions & 0 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,10 @@ export default async function build(
)
}

if (config.cleanDistDir) {
await recursiveDelete(distDir, /^cache/)
}

// We need to write the manifest with rewrites before build
// so serverless can import the manifest
await nextBuildSpan
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,7 @@ export default async function getBaseWebpackConfig(
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
config.future.excludeDefaultMomentLocales &&
config.excludeDefaultMomentLocales &&
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
Expand Down Expand Up @@ -1333,7 +1333,7 @@ export default async function getBaseWebpackConfig(
scrollRestoration: config.experimental.scrollRestoration,
basePath: config.basePath,
pageEnv: config.experimental.pageEnv,
excludeDefaultMomentLocales: config.future.excludeDefaultMomentLocales,
excludeDefaultMomentLocales: config.excludeDefaultMomentLocales,
assetPrefix: config.assetPrefix,
disableOptimizedLoading: config.experimental.disableOptimizedLoading,
target,
Expand Down
3 changes: 2 additions & 1 deletion packages/next/cli/next-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ const nextDev: cliCommand = (argv) => {
}
}

const port = args['--port'] || 3000
const port =
args['--port'] || (process.env.PORT && parseInt(process.env.PORT)) || 3000
const host = args['--hostname'] || '0.0.0.0'
const appUrl = `http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`

Expand Down
3 changes: 2 additions & 1 deletion packages/next/cli/next-start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ const nextStart: cliCommand = (argv) => {
}

const dir = resolve(args._[0] || '.')
const port = args['--port'] || 3000
const port =
args['--port'] || (process.env.PORT && parseInt(process.env.PORT)) || 3000
const host = args['--hostname'] || '0.0.0.0'
const appUrl = `http://${host === '0.0.0.0' ? 'localhost' : host}:${port}`
startServer({ dir }, port, host)
Expand Down
3 changes: 0 additions & 3 deletions packages/next/next-server/lib/head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,4 @@ function Head({ children }: { children: React.ReactNode }) {
)
}

// TODO: Remove in the next major release
Head.rewind = () => {}

export default Head
6 changes: 4 additions & 2 deletions packages/next/next-server/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type DomainLocales = Array<{
}>

export type NextConfig = { [key: string]: any } & {
cleanDistDir?: boolean
i18n?: {
locales: string[]
defaultLocale: string
Expand All @@ -29,14 +30,14 @@ export type NextConfig = { [key: string]: any } & {
redirects?: () => Promise<Redirect[]>
trailingSlash?: boolean
webpack5?: false
excludeDefaultMomentLocales?: boolean

future: {
/**
* @deprecated this options was moved to the top level
*/
webpack5?: false
strictPostcssConfiguration?: boolean
excludeDefaultMomentLocales?: boolean
}
experimental: {
cpus?: number
Expand Down Expand Up @@ -69,6 +70,7 @@ export const defaultConfig: NextConfig = {
webpack: null,
webpackDevMiddleware: null,
distDir: '.next',
cleanDistDir: true,
assetPrefix: '',
configOrigin: 'default',
useFileSystemPublicRoutes: true,
Expand Down Expand Up @@ -119,9 +121,9 @@ export const defaultConfig: NextConfig = {
},
webpack5:
Number(process.env.NEXT_PRIVATE_TEST_WEBPACK4_MODE) > 0 ? false : undefined,
excludeDefaultMomentLocales: true,
future: {
strictPostcssConfiguration: false,
excludeDefaultMomentLocales: false,
},
serverRuntimeConfig: {},
publicRuntimeConfig: {},
Expand Down
3 changes: 0 additions & 3 deletions packages/next/next-server/server/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { defaultHead } from '../lib/head'
import { HeadManagerContext } from '../lib/head-manager-context'
import Loadable from '../lib/loadable'
import { LoadableContext } from '../lib/loadable-context'
import mitt, { MittEmitter } from '../lib/mitt'
import postProcess from '../lib/post-process'
import { RouterContext } from '../lib/router-context'
import { NextRouter } from '../lib/router/router'
Expand Down Expand Up @@ -83,8 +82,6 @@ class ServerRouter implements NextRouter {
domainLocales?: DomainLocales
isPreview: boolean
isLocaleDomain: boolean
// TODO: Remove in the next major version, as this would mean the user is adding event listeners in server-side `render` method
static events: MittEmitter = mitt()

constructor(
pathname: string,
Expand Down
1 change: 1 addition & 0 deletions test/integration/clean-distdir/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {}
1 change: 1 addition & 0 deletions test/integration/clean-distdir/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'hello from index'
75 changes: 75 additions & 0 deletions test/integration/clean-distdir/test/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* eslint-env jest */

import fs from 'fs-extra'
import { join } from 'path'
import { nextBuild } from 'next-test-utils'

jest.setTimeout(1000 * 60 * 2)

const appDir = join(__dirname, '../')
const customFile = join(appDir, '.next/extra-file.txt')
const cacheDir = join(appDir, '.next/cache')
const nextConfig = join(appDir, 'next.config.js')

let nextConfigContent

async function checkFileWrite(existsAfterBuild) {
await nextBuild(appDir)
fs.writeFileSync(customFile, 'this is a testing file')
await nextBuild(appDir)
expect(fs.existsSync(customFile)).toBe(existsAfterBuild)
// `.next/cache` should be preserved in all cases
expect(fs.existsSync(cacheDir)).toBe(true)
}

const runTests = () => {
it('should clean up .next before build start', async () => {
await checkFileWrite(false)
})
}

describe('Cleaning distDir', () => {
describe('server mode', () => {
runTests()
})

describe('serverless mode', () => {
beforeAll(async () => {
nextConfigContent = await fs.readFile(nextConfig, 'utf8')
await fs.writeFile(
nextConfig,
`
module.exports = {
target: 'serverless'
}
`
)
})
afterAll(async () => {
await fs.writeFile(nextConfig, nextConfigContent)
})

runTests()
})

describe('disabled write', () => {
beforeAll(async () => {
nextConfigContent = await fs.readFile(nextConfig, 'utf8')
await fs.writeFile(
nextConfig,
`
module.exports = {
cleanDistDir: false
}
`
)
})
afterAll(async () => {
await fs.writeFile(nextConfig, nextConfigContent)
})

it('should not clean up .next before build start', async () => {
await checkFileWrite(true)
})
})
})
1 change: 1 addition & 0 deletions test/integration/env-config/app/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
cleanDistDir: false,
// update me
env: {
nextConfigEnv: process.env.ENV_KEY_IN_NEXT_CONFIG,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module.exports = {}
module.exports = {
cleanDistDir: false,
}
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module.exports = {}
module.exports = {
cleanDistDir: false,
}
16 changes: 12 additions & 4 deletions test/integration/font-optimization/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,11 @@ describe('Font Optimization', () => {

describe('Font optimization for SSR apps', () => {
beforeAll(async () => {
await fs.writeFile(nextConfig, `module.exports = { }`, 'utf8')
await fs.writeFile(
nextConfig,
`module.exports = { cleanDistDir: false }`,
'utf8'
)

if (fs.pathExistsSync(join(appDir, '.next'))) {
await fs.remove(join(appDir, '.next'))
Expand All @@ -255,7 +259,7 @@ describe('Font Optimization', () => {
beforeAll(async () => {
await fs.writeFile(
nextConfig,
`module.exports = { target: 'serverless' }`,
`module.exports = { target: 'serverless', cleanDistDir: false }`,
'utf8'
)
await nextBuild(appDir)
Expand All @@ -272,7 +276,7 @@ describe('Font Optimization', () => {
beforeAll(async () => {
await fs.writeFile(
nextConfig,
`module.exports = { target: 'experimental-serverless-trace' }`,
`module.exports = { target: 'experimental-serverless-trace', cleanDistDir: false }`,
'utf8'
)
await nextBuild(appDir)
Expand All @@ -290,7 +294,11 @@ describe('Font Optimization', () => {

describe('Font optimization for unreachable font definitions.', () => {
beforeAll(async () => {
await fs.writeFile(nextConfig, `module.exports = { }`, 'utf8')
await fs.writeFile(
nextConfig,
`module.exports = { cleanDistDir: false }`,
'utf8'
)
await nextBuild(appDir)
await fs.writeFile(
join(appDir, '.next', 'server', 'font-manifest.json'),
Expand Down
6 changes: 1 addition & 5 deletions test/integration/future/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
module.exports = {
future: {
excludeDefaultMomentLocales: true,
},
}
module.exports = {}
2 changes: 1 addition & 1 deletion test/integration/future/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let appDir = join(__dirname, '../')
let server
let appPort

describe('future.excludeDefaultMomentLocales', () => {
describe('excludeDefaultMomentLocales', () => {
beforeAll(async () => {
await nextBuild(appDir)
const app = nextServer({
Expand Down
1 change: 1 addition & 0 deletions test/integration/port-env-var/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = {}
1 change: 1 addition & 0 deletions test/integration/port-env-var/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default () => 'hello from index'
Loading

0 comments on commit f47ee59

Please sign in to comment.