この記事では,Nixを使ってNext.jsアプリをビルドします.GitHubにこの記事の内容を実行したリポジトリを用意したのでそちらもご覧ください.
Nixを使う利点は適当にググってください.
まずはプロジェクトディレクトリを作成してgitリポジトリを初期化しましょう.
$ mkdir build-next-with-nix
$ cd build-next-with-nix/
$ git init
Initialized empty Git repository in /path/to/build-next-with-nix/.git/
つぎに,ビルドに必要なツールをインストールします.このプロジェクトでは以下のツールを使います.
- gitignore.nix: .gitignoreに応じて必要なファイルをフィルタします.
- nix-npm-buildpackage: npm(yarn)プロジェクトのビルドに使います.
nivを使ってインストールします.さくっと入れれてハッシュも自動で計算してくれるのはすごい!
$ niv init
Initializing
Creating nix/sources.nix
Creating nix/sources.json
Importing 'niv' ...
Adding package niv
Writing new sources file
Done: Adding package niv
Importing 'nixpkgs' ...
Adding package nixpkgs
Writing new sources file
Done: Adding package nixpkgs
Done: Initializing
$ niv add hercules-ci/gitignore.nix
Adding package gitignore.nix
Writing new sources file
Done: Adding package gitignore.nix
$ niv add serokell/nix-npm-buildpackage
Adding package nix-npm-buildpackage
Writing new sources file
Done: Adding package nix-npm-buildpackage
それではNextアプリを作っていきましょう.今回はTypeScript + ESLint + Jestのテンプレートを使うことにします.
まずはshell.nix
を作ってnpm
のインストールされた開発環境を立ち上げます.
# shell.nix
{ sources ? import ./nix/sources.nix }:
let
pkgs = import sources.nixpkgs {};
in
pkgs.mkShell {
buildInputs = [
pkgs.nodejs
];
}
$ nix-shell
[nix-shell:~/build-next-with-nix]$
テンプレートを展開しましょう.これには少し時間がかかります.
$ npx create-next-app next-app --example https://github.com/vercel/next.js/tree/master/examples/with-typescript-eslint-jest
それでは,サーバを起動してみましょう!
$ cd next-app/
$ npm run dev
> with-typescript-eslint-jest@1.0.0 dev /home/pan/build-next-with-nix/next-app
> next dev
ready - started server on http://localhost:3000
event - compiled successfully
うまくいきましたね.
つぎに,このプロジェクトをNixを使ってビルドします.
まず,next.config.js
を使ってNextの設定を変更する必要があります.
// next.config.js
module.exports = {
distDir: 'output',
generateBuildId: async () => {
return process.env.NEXT_BUILD_ID || 'next-build'
},
}
ひとつ目の設定はNextの出力ディレクトリを変更しています.これは.gitignoreに含まれないディレクトリを指定しなければいけません1.
次の設定はビルドを決定的にするために必要です.NextはデフォルトでビルドIDをランダムに生成するため,固定値に上書きしてあげる必要があります.ここではNixから環境変数経由で与えることにします.
次のdefault.nixをプロジェクトルートに作成してください.
# default.nix
{ sources ? import ./nix/sources.nix }:
let
pkgs = import sources.nixpkgs {};
bp = pkgs.callPackage sources.nix-npm-buildpackage {};
inherit (import sources."gitignore.nix" { inherit (pkgs) lib; }) gitignoreSource;
src = gitignoreSource ./next-app;
in
bp.buildNpmPackage {
inherit src;
npmBuild = "npm run build";
extraEnvVars = {
NEXT_NIX_BUILD = "true";
NEXT_BUILD_ID = builtins.hashString "sha256" "${src}";
};
}
ビルドしてみましょう!
$ nix-build
成功したら,result
フォルダからサーバを起動してみましょう.
$ cd result
$ ./bin/npm run start
> with-typescript-eslint-jest@1.0.0 start /nix/store/wmw2hld9cdfxy7kdggb4qaxk7ravl8a4-with-typescript-eslint-jest-1.0.0
> next start
ready - started server on http://localhost:3000
😁
Dockerイメージを作ることもできます.Dockerfile.nix
を次の内容で作成します.
# Dockerfile.nix
{ sources ? import ./nix/sources.nix }:
let
pkgs = import sources.nixpkgs {};
contents = import ./default.nix { inherit sources; };
in
pkgs.dockerTools.buildImage {
name = "build-next-with-nix";
tag = "latest";
inherit contents;
config = {
Env = [ "NODE_ENV=production" ];
Cmd = [ "/bin/npm" "run" "start" "--scripts-prepend-node-path" ];
};
}
ビルドしてみましょう.
$ nix-build Dockerfile.nix
作成したDockerイメージはdocker load
で読み込めます.
$ docker load -i result
Loaded image: build-next-with-nix:latest
実行してみましょう!
$ docker run -p 3000:3000 build-next-with-nix
> with-typescript-eslint-jest@1.0.0 start /nix/store/231hhb2sbpqvcg1y4jsmhzycfwnhnvbn-with-typescript-eslint-jest-1.0.0
> next start
ready - started server on http://localhost:3000
😎👍
-
なぜかは分かりません. ↩
Top comments (0)