コンテンツにスキップ
ブログに戻る

2018年6月27日水曜日

Next.js 6.1

投稿者

本日、本番環境に対応したNext.js 6.1を発表できることを誇りに思います。主な特徴は以下の通りです。

  • ホットリロードの信頼性の向上
  • コードベースの改善
  • Next.js コードモッド

Next.js 6.1のリリースに加え、nextjs.orgオープンソースになったことを発表できることを嬉しく思います。

ホットリロードの信頼性の向上

Next.js 6.1より前のバージョンでは、Next.jsはユーザーに代わってreact-hot-loaderを実装していました。このライブラリは、ホットリロード間でReactの状態を保持します。

そうすることで、react-hot-loaderはReactにいくつかの非標準的な動作を追加します。例えば、shouldComponentUpdateを無視し、要素のtypeは実際のReactコンポーネントではなくプロキシコンポーネントになっていました。

Next.jsが可能な限りデフォルトのReactに近づくように、react-hot-loaderを依存関係から削除しました。これにより、開発モードと本番モードの動作が互いに近くなります。なお、Next.jsのホットリロード機能は削除されておらず、ホットリロードは常にNext.jsによって内部的に処理されていました。

TypeScriptおよびその他のカスタム拡張機能のホットリロード

デフォルトでは、Next.jsはpagesディレクトリ内の任意の.jsまたは.jsxファイルを自動的に検索してルートを定義します。

Next.js 5でユニバーサルWebpackが導入されたことで、JavaScriptにコンパイルされるトップレベルページを持つことが可能になりました。良い例はTypeScriptで、.tsおよび.tsxを使用します。

pageExtensionsは、Next.jsプラグインがページと見なされるべき拡張子を定義できるようにすることを目的としたnext.config.jsの構成キーです。例えば、@zeit/next-typescript.ts.tsxを定義し、@zeit/next-mdxはトップレベルの.mdxページを持つ方法を説明しています

以前は、pageExtensionsを実装する際、Next.jsプラグインはホットリロードに使用されるhot-self-accept-loaderを実装する必要がありました。これはもはや必要ありません。pageExtensionsに拡張子を追加すると、hot-self-accept-loaderが自動的に適用されます。

コードベースの改善

最近、今後の機能のために準備を進めており、これには長期的にコード品質を向上させるための内部変更が含まれています。

これらの変更の1つは、server/buildディレクトリがトップレベルのbuildに移動されたことです。これにより、新規コントリビューターがWebpackおよびBabelの構成を見つけやすくなります。

また、コードベース全体にFlowの型を追加することにも注力してきました。

ユーザーにとってより目に見える変更として、.next/dist.next/serverに名称変更されました。.nextディレクトリはビルド出力を保持します。例えば、next buildを実行すると、結果は.nextに保存されます。

プリレンダリングファイルは現在、serverディレクトリにあります。

同じ定数の出現箇所が共通ファイルに移動されました: constants.js

Next.js コードモッド

Next.js 6.0がリリースされた際、ページコンポーネントに自動的に注入されるurlプロパティは非推奨となりました。urlが廃止される理由は、物事を非常に予測可能で明示的にしたいからです。どこからともなく現れる魔法のurlプロパティは、その目標に貢献しません。

urlプロパティが持っていたのと同じプロパティを取得する推奨される方法は、withRouterを使用することです。

page.js
// old
class Page extends React.Component {
  render() {
    const { url } = this.props;
    return <div>{url.pathname}</div>;
  }
}
export default Page;

Next.js 6より前のバージョンでurlを使用してパス名にアクセスする方法

page.js
// new
import { withRouter } from 'next/router';
class Page extends React.Component {
  render() {
    const { router } = this.props;
    return <div>{router.pathname}</div>;
  }
}
export default withRouter(Page);

Next.js 6以降のバージョンでwithRouterによって注入されたrouterを使用してパス名にアクセスする方法

Next.jsアプリケーションのアップグレードパスをシンプルに保つことに尽力しているため、urlの使用箇所をwithRouterにアップグレードする簡単な方法を作成することに着手しました。

この取り組みの結果、特定の非推奨機能を新しい使い方に簡単にアップグレードできるコードモッドのライブラリであるnext‑codemodが誕生しました。

私たちが提供する最初のコードモッドはurl-to-withrouterで、urlが使用されていた多くのケースを自動的にwithRouterに変換します。

ターミナル
  jscodeshift -t ./url-to-withrouter.js pages/**/*.js

これにより、urlの使用がwithRouterに変換されます。

詳細はこちら

Next.jsへの貢献

Next.jsコミュニティは成長しており、すでに450人以上のコントリビューターがNext.jsコアまたは例に少なくとも1つのコミットを行っています。

Next.jsに貢献する方法は多数あります。

  • コミュニティに参加し、GitHubでアドバイスをする

  • 一般的なユースケースの例を貢献する: examplesディレクトリ

  • good first issuehelp wantedのラベルが付いたGitHubのイシューを確認する

    good first issueラベルの付いたオープンなイシューが30件あります。これにより、新しいコントリビューターに貢献する機会を提供しています。

nextjs.orgのオープンソース化

nextjs.orgオープンソースになったことを発表できることを嬉しく思います。これにより、Next.jsの実装の参照として機能し、問題や改善点をプロジェクトに直接提出できるようになります。

今後の展望

信頼性とパフォーマンスを向上させるためのいくつかの新機能に取り組んできました。主なハイライトをいくつかご紹介します。

Webpack 4

Webpack 4は多くの改善をもたらします。より優れたコード分割、デフォルトで必要な設定の削減、そして最も重要なのはビルド時間の高速化です。200ページ以上あるアプリケーションで最初に行ったテストでは、next buildの平均実行時間が100秒から70秒に短縮されました。2回目の実行(キャッシュあり)では、next buildの平均実行時間は21秒でした。

サーバーレスNext.js

next startを独自のパッケージであるnext-serverに移行するための準備を段階的に進めています。このパッケージは、インストールサイズと起動時間に対して大幅に最適化されます。これらの最適化は、アプリケーションの新しいインスタンスがリクエストごと、または数リクエストごとに実行される「サーバーレス」のユースケースに必要です。つまり、アプリケーションの「コールドスタート」を可能な限り高速に最適化する必要があります。