This is a Next.js project bootstrapped with create-next-app
and then Bazelified.
TypeScript transpilation and type checking has been broken out into fine-grained ts_project
targets.
This is a small example with only two Typescript source directories so the performance benefit of using fine grained targets will be negligible here.
In a large application or monorepo, splitting Typescript transpilation & type checking across many targets can speed up the build with parallelization and caching. It also allows for massive parallelization with remote execution. Read https://blog.aspect.dev/typescript-with-rbe for more information on using remote execution with Typescript.
The package.json
scripts have been updated to call Bazel instead of Next.js so these scripts can be
used as they would be in a typical Next.js configuration.
For example, run npm run dev
to run the development server in watch mode (equivalent to running next dev
).
Run npm start
to run the production server in watch mode (equivalent to running next start
).
We recommend installing a node_modules
folder in the source tree, like with any frontend project.
Just run pnpm install
.
Bazel itself doesn't depend on that folder, but it is needed so your editor can find typings.
Run pnpm run build
. This runs bazel build //next.js:next
, the Bazel equivalent of running next build
.
The output .next
folder can be found under bazel-bin/next.js/.next
.
Run pnpm run export
. This runs bazel build //next.js:next_export
, the Bazel equivalent of running next export
.
The output out
folder can be found under bazel-bin/next.js/out
.
NB This target will fail on some systems or cause unnecessary rebuilds of the .next
target due to next export
writing
back to the .next
input directory which is write-protected input under Bazel. See vercel/next.js#43344.
TODO: Fix issue in Next.js (vercel/next.js#43344) or find work-around.
This example only has the .css styles generated by create-next-app
. These don't require any build steps. Showing how to create fine grained
targets to pre-process .scss
and .less
into .css
would be useful in this example in the future.
TODO: add .scss and/or .less styles and pre-process targets
This examples doesn't directly cover releasing and deploying a Next.js application built with Bazel
but it should not diverge much from releasing and deploying a Next.js application built outside of Bazel
since the output of the Bazel build is the shape as the output you would get from running the vernacular
Next.js tooling, namely a .next
folder with all of the output artifacts that application is
comprised of:
$ pnpm run build
> next.js@0.1.0 build /Users/greg/aspect/rules/bazel-examples/next.js
> bazel build //:build
INFO: Analyzed target //:build (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //:build up-to-date:
bazel-bin/.next
INFO: Elapsed time: 0.260s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
$ ls -la bazel-bin/.next
total 608
drwxr-xr-x 16 greg wheel 512 28 Sep 14:06 .
drwxr-xr-x 11 greg wheel 352 28 Sep 14:06 ..
-rw-r--r-- 1 greg wheel 21 28 Sep 14:06 BUILD_ID
-rw-r--r-- 1 greg wheel 1078 28 Sep 14:06 build-manifest.json
drwxr-xr-x 5 greg wheel 160 28 Sep 14:06 cache
-rw-r--r-- 1 greg wheel 93 28 Sep 14:06 export-marker.json
-rw-r--r-- 1 greg wheel 441 28 Sep 14:06 images-manifest.json
-rw-r--r-- 1 greg wheel 103383 28 Sep 14:06 next-server.js.nft.json
-rw-r--r-- 1 greg wheel 20 28 Sep 14:06 package.json
-rw-r--r-- 1 greg wheel 312 28 Sep 14:06 prerender-manifest.json
-rw-r--r-- 1 greg wheel 2 28 Sep 14:06 react-loadable-manifest.json
-rw-r--r-- 1 greg wheel 2598 28 Sep 14:06 required-server-files.json
-rw-r--r-- 1 greg wheel 335 28 Sep 14:06 routes-manifest.json
drwxr-xr-x 10 greg wheel 320 28 Sep 14:06 server
drwxr-xr-x 5 greg wheel 160 28 Sep 14:06 static
-rw-r--r-- 1 greg wheel 115279 28 Sep 14:06 trace
When built with Bazel, this folder doesn't end up as .next
in your source tree
because Bazel doesn't write output files to the source tree. Instead the folder can be found
via the bazel-bin
symlink create by Bazel as bazel-bin/.next
. You release and deploy tooling
would use this folder after running the Bazel build.