This adds the initial changes outlined in the [i18n routing RFC](https://github.com/vercel/next.js/discussions/17078). This currently treats the locale prefix on routes similar to how the basePath is treated in that the config doesn't require any changes to your pages directory and is automatically stripped/added based on the detected locale that should be used.
Currently redirecting occurs on the `/` route if a locale is detected regardless of if an optional catch-all route would match the `/` route or not we may want to investigate whether we want to disable this redirection automatically if an `/index.js` file isn't present at root of the pages directory.
TODO:
- [x] ensure locale detection/populating works in serverless mode correctly
- [x] add tests for locale handling in different modes, fallback/getStaticProps/getServerSideProps
To be continued in fall-up PRs
- [ ] add tests for revalidate, auto-export, basePath + i18n
- [ ] add mapping of domains with locales
- [ ] investigate detecting locale against non-index routes and populating the locale in a cookie
x-ref: https://github.com/vercel/next.js/issues/17110
On the latest beta of webpack 5 resolving fails with the below error and according to https://github.com/webpack/webpack/issues/11467 is due to the imports in this module not being fully specified. This adds the config mentioned in the thread to correct the resolving for this module.
```sh
Failed to compile.
--
16:33:50.046 | ModuleNotFoundError: Module not found: Error: Can't resolve './assertThisInitialized' in '/vercel/f03cc85/node_modules/@babel/runtime/helpers/esm'
16:33:50.046 | > Build error occurred
16:33:50.047 | Error: > Build failed because of webpack errors
16:33:50.047 | at build (/vercel/f03cc85/node_modules/next/dist/build/index.js:15:918)
16:33:50.099 | error Command failed with exit code 1.
```
Earlier today #17038 was merged which I opened to fix a problem when using `webpack@5.0.0-beta.30` with Next.js using the new Webpack 5 support. In that PR, the only change was the renaming of a configuration key. I later discovered that the change on the Webpack side was different than I initially thought, and this meant that the fix I submittted to Next.js didn't work.
This PR intends to fix the remaining problems. Webpack 5 now accepts a `environment` key that can be used to configure the target output. Previously, this was known as `ecmaVersion` and accepted a number. Now, `environment` accepts a configuration object with individual options. I've configured this in such a way where it resembles an ES5 environment:
```js
environment: {
arrowFunction: false,
bigIntLiteral: false,
const: false,
destructuring: false,
dynamicImport: false,
forOf: false,
module: false,
}
```
This PR fixes#17035. As described in the issue, there was a breaking change in `webpack@5.0.0-beta.30`: `output.ecmaVersion` was replaced by `output.environment`. This meant Next.js apps using this `webpack` version would break. This PR updates the relevant Webpack config.
I think this will break any apps that are still using `webpack@5.0.0-beta.29`, but I don't know whether that is a problem as this is a beta feature. If it is, I'd love it if someone could let me know how to detect beta versions in the code so I can make it backwards-compatible.
Handles:
- Next.js version
- next.config.js `env` key
- `NEXT_PUBLIC_` prefixed environment variables
- next.config.js keys that affect performance
Ideally we don't invalidate the whole cache when `NEXT_PUBLIC_` / `env` key variables change, but this is just to initially make the caching reliable, this behavior is similar to the current webpack 4 behavior, so it can only be improved 👍
Don't use this yet as it's still being developed. This is a first iteration that enables the webpack cache. There's still more to do here, for example if css modules are used there's currently a bug where webpack does not save the cache for browser compilation (impacting build performance). @sokra is going to look into that issue.
This adds the following Node.js core polyfills only when the import is used:
- `path`
- `stream`
- `vm`
- `crypto`
- `buffer`
Fixes#15948
We'll have a separate issue about adding warnings for the usage of these modules in the browser, some polyfills like crypto are quite heavy and generally not needed for most applications (included accidentally through node_modules).
This PR adds a second experimental post-processing step for the framework introduced by @prateekbh in #14746. The image post-processing step scans the rendered document for the first few images and uses a simple heuristic to determine if the images should be automatically preloaded.
Analysis of quite a few production Next apps has shown that a lot of sites are taking a substantial hit to their [LCP](https://web.dev/lcp/) score because an image that's part of the "hero" element on the page is not preloaded and is getting downloaded with lower priority than the JavaScript bundles. This post-processor should automatically fix that for a lot of sites, without causing any real performance effects in cases where it fails to identify the hero image.
This feature is behind an experimental flag, and will be subject to quite a bit of experimentation and tweaking before it's ready to be made a default setting.
Next.js plugins like `@next/mdx` inject additional webpack loaders to compile files, but they omit the necessary loader for Fast Refresh to work.
Instead of making these files deopt out of Fast Refresh, we can automatically detect and inject the loader in these cases.
Fixes#13574
In terms of url rewriting, `trailingSlash` supports everything `exportTrailingSlash` does. We can just share all other code paths and deprecate `exportTrailingSlash`.
This PR shows a deprecation warning when `exportTrailingSlash` is used.
Also fixes https://github.com/vercel/next.js/issues/15774
We can update the tests now or later. (I kept them the same to prove it's non-breaking)
To do:
- [x] Do we want to keep this? => nope 841d4efc51/packages/next/next-server/lib/router/router.ts (L329)
- [x] I kept `exportTrailingSlash` here. Do we want to rename that as well? => nope 2d9d649d49/packages/next/build/index.ts (L959)
- Use latest terser version (still 1 warning in the stable version which is an open PR)
- Add emitOnErrors instead of noEmitOnErrors
- Added trace-deprecations for Next.js core development
- Using `namedChunks` where possible, this will also allow for faster access to the chunks as we no longer have to look them up like we did before using `find`
- Using the new asset hooks introduced in the latest webpack beta
- Using the new externals function signature
I think this is necessary for IE11.
via [Webpack docs](https://webpack.js.org/migrate/5/#turn-off-es2015-syntax-in-runtime-code-if-necessary)
> By default, webpack's runtime code uses ES2015 syntax to build smaller bundles. If your build targets environments that don't support this syntax (like IE11), you'll need to set output.ecmaVersion: 5 to revert to ES5 syntax.
Thank you
Found while working on figuring out this bug: https://twitter.com/timneutkens/status/1282129714627448832
I noticed that the node_modules got passed by the ignore still because when chokidar identifies a ignore pattern is a glob it treats the glob as-is instead of appending `/**` to the glob
Removed Option to enable `ReactProductionProfiling` from configuration and added a CLI switch for the same.
Users can now do `next build --profile` to enable react production profiling.
Also added a warning to notify users about the performance impact
Fixes: #14688
This updates the scroll position saving to occur as the scroll position changes instead of trying to do it when the navigation is changing since the `popState` event doesn't allow us to update the leaving history state once the `popState` has occurred.
The order of events that was previously attempted to save scroll position on a `popState` event (back/forward navigation)
1. history.state is already updated with state from `popState`
2. we replace state with the currently rendered page adding scroll info
3. we replace state again with the `popState` event state overriding scroll info
Using this approach the above event order is no longer in conflict since we don't attempt to populate the state with scroll position while it's leaving the state and instead do it while it is still the active state in history
This approach resembles existing solutions:
https://www.npmjs.com/package/scroll-behaviorhttps://twitter.com/ryanflorence/status/1029121580855488512
Fixes: https://github.com/vercel/next.js/issues/13990Fixes: #12530
x-ref: https://github.com/vercel/next.js/pull/14075
Closes [13709](https://github.com/vercel/next.js/issues/13709).
The solution works, **(tested and confirmed with true and false flags with the latest next version)** though I am quite sure this is not the most elegant and proper way to implement it. I have spent the good part of yesterday and today's morning in order to make it more generic but since it's my first time working with anything related to webpack I have struggled miserably. Last, but not least I'm unsure if this is the most proper naming for the flag.
Please, let me know what you want me to change and I'll get it done asap.
Warn users and revert their `devtool` when they manually change the `devtool` in development mode. For this addition, I check to ensure the `devtool` is custom (i.e. different than what is set by Next) and has a value (`false` is fine as a custom `devtool`!).
As described in [this issue (13963)](https://github.com/vercel/next.js/issues/13963), changing the `devtool` in development mode can cause issues with performance.
Fixes#13963
Not sure if it's still there for a reason, but from the types for `NoEmitOnErrorsPlugin`
```js
/* @deprecated use config.optimization.noEmitOnErrors */
```
Initial PR to make `next build` work with webpack 5, still needs more work to make sure runtimeChunk and such are shared between pages.
- No longer needs the custom ChunkNamesPlugin as the default behavior was changed
- Dropping AMP First client page bundles is now compatible
Updates the way filenames are generated for browser compilation.
Notably:
- All entry bundles now have hashes in production, this includes pages (previously pages used a buildId in the path)
- The AmpFiles no longer depends on hardcoded bundle names, it uses the buildManifest instead (internals)
- All cases where we match the page name from the chunk/entrypoint name now use the same function `getRouteFromEntrypoint` (internals)
- In development we no longer include the "faked" `buildId` set to `development` for page files, instead we just use the `/_next/static/pages` path (was `/_next/static/development/pages`). This was changed as it caused unneeded complexity and makes generating the bundles easier (internals)
- Updated tons of tests to be more resilient to these changes by relying on the buildManifest instead of hardcoded paths (internals)
Follow up of these PRs:
https://github.com/vercel/next.js/pull/13759https://github.com/vercel/next.js/pull/13870https://github.com/vercel/next.js/pull/13937https://github.com/vercel/next.js/pull/14130https://github.com/vercel/next.js/pull/14176https://github.com/vercel/next.js/pull/14268Fixes#6303Fixes#12087Fixes#1948Fixes#4368Fixes#4255Fixes#2548
This removes remaining references to `granularChunks` in configs, error messages, and comments.
Also removed the `process.env.__NEXT_GRANULAR_CHUNKS` value.
---
Follow up to: https://github.com/vercel/next.js/pull/13663