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

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 が導入されたことで、JS にコンパイルするトップレベルのページを持つことが可能になりました。TypeScript は ` .ts` と ` .tsx` を使用する良い例です。

`pageExtensions` は `next.config.js` 内の設定キーで、Next.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);

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

Next.js アプリケーションのアップグレードパスをシンプルに保つことに取り組んでいるため、`url` の使用を `withRouter` にアップグレードする簡単な方法を作成することにしました。

この取り組みの結果がnext-codemodです。これは、特定の非推奨機能を新しい使用方法にアップグレードすることを、1つのコマンドを実行するほど簡単にするコードモッドのライブラリです。

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

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

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

詳細はこちら

Next.js への貢献

Next.js コミュニティは成長しており、すでに Next.js コアまたはサンプルに少なくとも1つのコミットを寄せた450人を超える貢献者がいます。

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

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に移行するための変更を段階的に行っています。このパッケージは、インストールサイズと起動時間の最適化に重点を置いています。これらの最適化は、リクエストごと、または数リクエストごとにアプリの新しいインスタンスが実行される「サーバーレス」ユースケースに必要なものです。つまり、アプリケーションの「コールドスタート」を可能な限り高速にする必要があります。