2018年9月19日水曜日
Next.js 7
投稿者26回のカナリアリリースと340万回のダウンロードを経て、製品版のNext.js 7をリリースできることを誇りに思います。主な特徴は次のとおりです。
- DXの改善:起動が57%高速化、再コンパイルが42%高速化
- エラーレポートの改善(react-error-overlayを使用)
- コンパイルパイプラインのアップグレード:Webpack 4とBabel 7
- 動的インポートの標準化
- 静的CDNのサポート
- 初期HTMLペイロードの削減
- アプリとページ間のSSRでのReact Context
最後に、新しくなったNextjs.orgでこのニュースをお届けできることを楽しみにしています
DXの改善
Next.jsの主な目標の1つは、可能な限り最高の開発者体験で、最高のプロダクションパフォーマンスを提供することです。このリリースでは、ビルドおよびデバッグパイプラインに多くの大幅な改善がもたらされています
コンパイル速度
webpack 4、Babel 7、およびコードベースに対する多くの改善と最適化のおかげで、Next.jsは開発中に最大57%高速に起動するようになりました。
新しいインクリメンタルコンパイルキャッシュのおかげで、コードに対する変更は、40%高速にビルドされるようになりました。
これらは、収集した数値例です
6.0 | 7.0 | デルタ | |
---|---|---|---|
起動時間(基本アプリケーション) | 1947ミリ秒 | 835ミリ秒 | 57% 高速化 |
コード変更(基本アプリケーション) | 304ミリ秒 | 178ミリ秒 | 42% 高速化 |
おまけとして、開発およびビルド時に、webpackbarのおかげで、よりリアルタイムなフィードバックが表示されるようになりました。


React Error Overlayによるエラーレポートの改善
正確で役立つエラーのレンダリングは、優れた開発とデバッグのエクスペリエンスにとって非常に重要です。これまで、エラーメッセージとそのスタックトレースをレンダリングしていました。今後は、react-error-overlay
を使用して、スタックトレースを以下で強化します。
- サーバーとクライアントのエラーの両方に対する正確なエラー位置
- コンテキストを提供するためのソースの強調表示
- 完全な豊富なスタックトレース
これは、エラーの修正前と修正後の比較です


おまけとして、react-error-overlay
を使用すると、特定のコードブロックをクリックするだけで、テキストエディタを簡単に開くことができます。
Webpack 4
最初のリリース以来、Next.jsは、コードをバンドルし、豊富なプラグインと拡張機能のエコシステムを再利用するためにwebpackを利用してきました。Next.jsが最新のwebpack 4によって駆動されるようになったことを発表できることを嬉しく思います。webpack 4には、多数の改善とバグ修正が含まれています。
これらの中には、次のものがあります。
.mjs
ソースファイルのサポート- コード分割の改善
- より良いツリーシェイキング(未使用のコードの削除)のサポート
もう1つの新機能は、WebAssemblyのサポートです。Next.jsはWebAssemblyをサーバーレンダリングすることもできます。ここに例があります。
注:このアップグレードは完全に後方互換性があります。ただし、next.config.jsを介してカスタムwebpackローダーまたはプラグインを使用している場合は、アップグレードが必要になる場合があります。
CSSインポート
webpack 4では、mini-extract-css-pluginと呼ばれる、バンドルからCSSを抽出する新しい方法が導入されました。
@zeit/next-css
、@zeit/next-less
、@zeit/next-sass
、および@zeit/next-stylus
は、mini-extract-css-plugin
によって駆動されるようになりました。
これらのNext.jsプラグインの新しいバージョンは、CSSインポートに関連する20件の既存の問題を解決します。例として、動的なimport()
でのCSSのインポートがサポートされるようになりました。
import './my-dynamic-component.css';
export default function MyDynamicComponent() {
return <h1>My dynamic component</h1>;
}
import dynamic from 'next/dynamic'
const MyDynamicComponent = dynamic(import('../components/my-dynamic-component'))
export default function Index() {
return () {
<div>
<MyDynamicComponent/>
</div>
}
}
大きな改善点は、pages/_document.js
に以下を追加する必要がなくなったことです。
<link rel="stylesheet" href="/_next/static/style.css" />
代わりに、Next.jsはCSSファイルを自動的に挿入します。本番環境では、Next.jsはCSS URLにコンテンツハッシュも自動的に追加するため、変更があった場合に、エンドユーザーがファイルの古いバージョンを取得せず、不変の永続的なキャッシュを導入できるようにします。
要するに、Next.jsプロジェクトで.css
ファイルのインポートをサポートするために必要なのは、next.config.js
でwithCSSプラグインを登録するだけです。
const withCSS = require('@zeit/next-css');
module.exports = withCSS({
/* my next config */
});
標準化された動的インポート
Next.jsは、バージョン3からnext/dynamic
を通じて動的インポートをサポートしてきました。
この技術の初期採用者として、私たちはimport()
を処理するための独自のソリューションを記述する必要がありました。
その結果、Next.jsは後でwebpackが導入したサポートから乖離し始め、いくつかの機能が欠落していました。
このため、Next.jsはwebpackが導入して以来、いくつかのimport()
機能をサポートしていませんでした。
たとえば、特定のファイルをまとめて手動で名前を付けたり、バンドルしたりすることはできませんでした。
import(/* webpackChunkName: 'my-chunk' */ '../lib/my-library');
もう1つの例は、next/dynamic
モジュールでラップせずにimport()
を使用することです。
Next.js 7以降、デフォルトのimport()
の動作には触れなくなりました。つまり、完全なimport()サポートがすぐに利用できるということです。
この変更は完全に後方互換性もあります。動的コンポーネントの利用は、以下のように依然として簡単です。
import dynamic from 'next/dynamic';
const MyComponent = dynamic(import('../components/my-component'));
export default function Index() {
return (
<div>
<MyComponent />
</div>
);
}
この例では、my-component
用の新しいJavaScriptファイルを作成し、<MyComponent />
がレンダリングされた場合にのみロードします。
最も重要なことは、レンダリングされない場合、<script>
タグは初期HTMLドキュメントのペイロードに含まれないということです。
Next.js 7では、コードベースをさらに簡素化し、優れたReactエコシステムを利用するために、next/dynamic
はreact-loadable
(いくつかのマイナーな変更あり)を利用するように書き直されました。これにより、動的コンポーネントに2つの優れた新機能も導入されました。
next/dynamic
のtimeout
オプションを使用したタイムアウトnext/dynamic
のdelay
オプションを使用したローディングコンポーネントの遅延。この遅延により、インポートが非常に速い場合など、ローディング状態をレンダリングする前に、loading
コンポーネントがx時間待機できます。
Babel 7
Next.js 6では、Babel 7がまだベータ版だったときに導入しました。それ以来、Babel 7の安定版がリリースされ、Next.js 7ではこのバージョンが使用されています。
変更の完全なリストについては、Babelのリリースノートを参照してください。
主な機能の一部は次のとおりです。
- Typescriptのサポート。Next.jsでは、
@zeit/next-typescript
を使用できます。 - フラグメント構文
<>
のサポート babel.config.js
のサポート- プリセット/プラグインをファイルのサブセットまたはディレクトリにのみ適用するための
overrides
プロパティ
Next.jsプロジェクトでカスタムBabel構成を使用していない場合は、破壊的な変更はありません。
ただし、カスタムBabel構成を使用している場合は、それぞれのカスタムプラグイン/プリセットを最新バージョンにアップグレードする必要があります。
Next.js 6より前のバージョンからアップグレードする場合は、優れたbabel-upgrade
ツールを実行できます。
Babel 7へのアップグレードに加えて、Next.js Babelプリセット(next/babel
)は、NODE_ENV
がtest
に設定されている場合、デフォルトでmodules
オプションをcommonjs
に設定するようになりました。
この構成オプションは、多くの場合、Next.jsプロジェクトでカスタム.babelrc
を作成する唯一の理由でした。
{
"env": {
"development": {
"presets": ["next/babel"]
},
"production": {
"presets": ["next/babel"]
},
"test": {
"presets": [["next/babel", { "preset-env": { "modules": "commonjs" } }]]
}
}
}
Next.js 7では、これは次のようになります。
{
"presets": ["next/babel"]
}
この時点で、Babel構成がない場合、Next.jsは自動的にnext/babel
を使用するため、.babelrc
を削除できます。
より小さな初期HTMLペイロード
Next.jsはHTMLをプリレンダリングするため、ページを<html>
、<head>
、<body>
、およびページをレンダリングするために必要なJavaScriptファイルを含むデフォルト構造にラップします。
この初期ペイロードは、以前は約1.62kBでした。Next.js 7では、初期HTMLペイロードを最適化し、1.5kBになりました。これは7.4%の削減であり、ページがよりスリムになります。
6.0 | 7.0 | デルタ | |
---|---|---|---|
ドキュメントサイズ(サーバーレンダリング) | 1.62kb | 1.50kb | 7.4% 小さくなった |
サイズを縮小した主な方法は次のとおりです。
__next-error
divが削除されました。- インラインスクリプトは縮小され、将来のリリースで完全に削除されます。
- 未使用の
__NEXT_DATA__
プロパティ(たとえば、nextExport
やassetPrefix
プロパティ)が使用されていない場合は、コンパイルされません。
静的CDNサポート
Next.js 5では、assetPrefix
のサポートが導入されました。これは、Next.jsに特定の位置(通常はCDN)からアセットを自動的にロードさせる方法です。このオプションは、CDNがプロキシをサポートしている場合に最適です。次のようなURLをリクエストします。
https://cdn.example.com/_next/static/<buildid>/pages/index.js
通常、CDNはキャッシュにファイルがあるかどうかを確認し、それ以外の場合はオリジンから直接リクエストします。
アセットのプロキシは、まさにEdge Networkが機能する方法です。
ただし、一部のソリューションでは、ディレクトリをCDNに直接プリアップロードする必要があります。これを行う際の問題は、Next.jsのURL構造が.next
フォルダー内のフォルダー構造と一致しなかったことです。たとえば、上記の例では
https://cdn.example.com/_next/static/<buildid>/pages/index.js
// mapped to:
.next/page/index.js
Next.js 7では、.next
のディレクトリ構造をURL構造と一致するように変更しました。
https://cdn.example.com/_next/static/<buildid>/pages/index.js
// mapped to:
.next/static/<buildid>/pages/index.js
プロキシタイプのCDNを使用することをお勧めしますが、この新しい構造により、別のタイプのCDNを使用するユーザーは、.next
ディレクトリをCDNにアップロードできます。
Styled JSX v3
Next.jsにデフォルトで含まれているCSS-in-JSソリューションであるstyled-jsx 3を導入できることを嬉しく思います。これでReact Suspenseに対応できます。
不明確なことが多かったことの1つは、子コンポーネントが現在のコンポーネントスコープの一部でない場合に、その子コンポーネントをスタイルする方法です。たとえば、親コンポーネント内で使用されている場合にのみ特定のスタイルが必要な子コンポーネントを含めた場合
const ChildComponent = () => (
<div>
<p>some text</p>
</div>
);
export default function Index() {
return (
<div>
<ChildComponent />
<style jsx>{`
p {
color: black;
}
`}</style>
</div>
);
}
上記のコードでp
タグを選択しようとしても、styled-jsxのスタイルは現在のコンポーネントにスコープされているため、子コンポーネントにリークしないため、機能しません。これを回避する方法の1つは、:global
メソッドを使用して、p
タグからプレフィックスを削除することでした。ただし、これにより、スタイルがページ全体にリークするという新しい問題が発生します。
styled-jsx 3では、この問題は、新しいAPIであるcss.resolve
を導入することで解決されました。これにより、指定されたstyled-jsx文字列のclassName
と<style>
タグ(styles
プロパティ)が生成されます。
import css from 'styled-jsx/css';
const ChildComponent = ({ className }) => (
<div>
<p className={className}>some text</p>
</div>
);
const { className, styles } = css.resolve`
p {
color: black;
}
`;
export default function Index() {
return (
<div>
<ChildComponent className={className} />
{styles}
</div>
);
}
この新しいAPIにより、カスタムスタイルを子コンポーネントに透過的に渡すことができます。
これはstyled-jsxのメジャーリリースであるため、styles-jsx/css
を使用している場合にバンドルサイズを改善する1つの破壊的な変更があります。styled-jsx 2では、外部スタイルの「スコープ」バージョンのみが使用されている場合でも、「グローバル」バージョンを含めて、「スコープ」および「グローバル」バージョンの外部スタイルが生成されます。
styled-jsx 3では、グローバルスタイルはcss
の代わりにcss.global
でタグ付けする必要があります。これにより、styled-jsxはバンドルサイズを最適化できます。
すべての変更については、リリースノートを参照してください。
Appとページ間でのSSRを使用したReact Context
Next.js 7以降では、pages/_app.js
とページコンポーネントの間で新しいReact Context APIをサポートするようになりました。
以前は、サーバー側でページ間でReact Contextを使用することはできませんでした。これは、webpackがrequire.cacheを使用する代わりに内部モジュールキャッシュを保持していたためです。この動作を修正し、ページ間でモジュールインスタンスを共有するためにカスタムwebpackプラグインを記述しました。
これにより、新しいReact Contextを使用できるだけでなく、ページ間でコードを共有する際のNext.jsのメモリフットプリントも削減できます。
6.0 | 7.0 | デルタ | |
---|---|---|---|
メモリ使用量 | 57.5MB | 48.1MB | -16% メモリ |
nextjs.org
Next.js 7のリリースに合わせて、完全にリニューアルされたnextjs.orgを公開しました。
ブログ
現在お読みいただいているブログ記事は、nextjs.orgの新しいブログセクションの一部です。このブログは、Next.jsに関するコミュニケーション(例えば、新しいバージョンの発表など)の新しい拠点となります。


インスピレーションを得る
Next.jsを使用するアプリの数が継続的に増加しているため、これらの美しいアプリをすべて1つの概要で表示する方法が必要でした。新しい/showcase
ページをご覧ください。


この新しいショーケースでは、Next.jsで構築された新しいアプリを継続的に追加できます。
/showcase
にアクセスして、インスピレーションを得たり、Next.jsを使用したアプリを送信したりしてください!
コミュニティ
最初のリリース以来、Next.jsはフォーチュン500企業から個人のブログまで、あらゆるものに使用されています。Next.jsの採用が拡大していることに非常に興奮しています。
- 現在、Next.jsを使用している公開インデックス付きドメインは12,500以上あります。
- 少なくとも1回のコミットを成功させたコントリビューターは500人以上います。
- GitHubでは、プロジェクトは29,000回以上スターされています。
- 最初のリリース以来、約2200件のプルリクエストが送信されました。
Next.jsコミュニティには2000人近くのメンバーがいます。ぜひご参加ください!