Monday, March 26th 2018
Next.js 5.1: Faster Page Resolution, Environment Config & More
Posted byWe are happy to introduce Next.js 5.1, which features support for environment configuration, phases, source maps, and new Next.js plugins.
Major performance improvements are introduced: resolving pages is 102x faster, and error pages are loaded more efficiently.
To upgrade or install, run:
npm i next@latest react@latest react-dom@latest
In addition to bumping Next.js, we upgrade the peer dependencies
react
andreact-dom
Be sure to upgrade next-plugins like @zeit/next-css
, @zeit/next-sass
, @zeit/next-less
or @zeit/next-typescript
as well.
Faster page resolution
Thanks to the architectural changes in Next.js 5.0, we were able to simplify the logic that resolves pages based on url path. These changes were based on research from @oliviertassinari. Previously resolving a page took an average of 2.347ms. With the new logic resolving the same page takes on average 0.023ms. That's a 102x speedup for one of the most commonly invoked methods in Next.js applications.
Environment configuration
Typical Node.js environments often depend on passing environment variables to the application, for example: API_URL=https://api.vercel.com node index.js
and then you can use API_URL
anywhere in your application using process.env.API_URL
.
With universal rendering process.env
is not available on the client side. So with Next 5.1 we're introducing a new feature: publicRuntimeConfig
and serverRuntimeConfig
. These can be set in next.config.js
and will then be available using the next/config
module.
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
mySecret: 'secret',
},
publicRuntimeConfig: {
// Will be available on both server and client
staticFolder: '/static',
},
};
Both
serverRuntimeConfig
andpublicRuntimeConfig
are defined innext.config.js
import getConfig from 'next/config';
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
console.log(serverRuntimeConfig.mySecret); // Will only be available on the server side
console.log(publicRuntimeConfig.staticFolder); // Will be available on both server and client
export default function Index() {
return (
<div>
<img src={`${publicRuntimeConfig.staticFolder}/logo.png`} />
</div>
);
}
The
getConfig
method from thenext/config
module is used to get configuration values
Improved Error Handling
Previously Next.js had a special error handling mechanism for detecting server errors when loading page bundles. A page bundle is the javascript file that is loaded on the client side to load the page, for example /_next/-/page/index.js
.
If there were an error, like a build ID mismatch, the page bundle would still be served with a 200 HTTP status, but the contents would be a JSON representation of an error generated by the Next.js server. The reason for this is that there was client side error handling that depended on more than just the page being a 404. This solution worked really well, until you try to upload assets to a static file host or CDN that doesn't support a fallback.
With Next.js 5.1 we've completely refactored the error handling logic, when a page bundle returns a 404 HTTP status the router will automatically detect it and reload the page, to make sure navigation between multi-zones is possible.
In rewriting this logic, we removed the Router.onAppUpdated
hook; which was mainly used to trigger a page reload. Now the page will be automatically reloaded
In addition to this, we've added a new set of integration tests on error recovery in the development mode, to avoid regressions on error recovery in future releases.
Phases / config function
Some next-plugins like @zeit/next-css
are only required when Next.js is in development mode or when running next build
.
You can now export a function that returns the configuration object instead of immediately exporting the object.
module.exports = (phase, { defaultConfig }) => config;
next.config.js
exporting a function that returns the user configuration
Exporting a function will give you access to the phase
in which Next.js is running, for example development, production, building, export. This allows plugins to be loaded only when needed, but also gives access to the default configuration.
We've introduced a new module called next/constants
holding commonly used constants, including phases.
const {PHASE_DEVELOPMENT_SERVER} = require('next/constants')
module.exports = (phase, {defaultConfig}){
if(phase === PHASE_DEVELOPMENT_SERVER) {
return { /* development only config options here */ }
}
return { /* config options for all phases except development here */ }
}
A
next.config.js
that checks for the development phase
Improved production source map generation
With the introduction of universal webpack in Next.js 5 adding source maps to your production environment became as simple as adding a few lines to next.config.js
:
module.exports = {
webpack(config, { dev }) {
if (!dev) {
config.devtool = 'source-map';
for (const plugin of config.plugins) {
if (plugin['constructor']['name'] === 'UglifyJsPlugin') {
plugin.options.sourceMap = true;
break;
}
}
}
return config;
},
};
Manually enable source maps in
next.config.js
@zeit/next-source-maps can be added to a project to automatically enable production source maps for you, add the following to next.config.js
:
const withSourceMaps = require('@zeit/next-source-maps');
module.exports = withSourceMaps();
Using
@zeit/next-source-maps
to enable source maps innext.config.js
This enabled outputting of source maps for all but one file, app.js
, the reason for this was that app.js
consisted of multiple files (manifest.js
and commons.js
) combined with a webpack plugin. A side effect of this was that webpack couldn't generate source maps for the combined file.
Thanks to a pull request from @ptomasroos the app.js
file was replaced by main.js
. This file will hold the code that was previously compiled to manifest.js
and commons.js
and webpack will generate a source map for main.js
. Source maps will be automatically served, allowing external error tracking tools to show the actual file an line number when errors are detected.
New plugins / improvements to existing ones
We've introduced two new official plugins. @zeit/next-bundle-analyzer allows for easily setting up webpack-bundle-analyzer
to analyze the server side and client side bundles separately.
Additionally there were a lot of improvements to the official css
, less
, and sass
plugins regarding hot reloading and bundling. For example there is no longer a flash of unstyled content in development mode. And styles in subcomponents get picked up as well.
Community
You can now find the Next.js community on GitHub. Recently a list of notable companies using Next.js was posted there. Feel free to post projects in the thread.
Thank you
We would like to thank everyone who has contributed to Next.js for this release. Whether it's contributing to the core or expanding and improving our ever growing examples directory.
If you are looking to start contributing to Next.js you can find issues with the good first issue or help wanted label.
A special thank you to Trulia for their valuable feedback related to environment configuration and the new error page handling.