I am working on building a Next.js project with Bazel. My aim is to write as little custom Bazel code as possible, leveraging the Next.js CLI as much as I can.
One of the constraints of Bazel is that builds operate within a file system sandbox. By default, build commands must read only from known "source" paths and write to predefined "output" paths. Source paths are set to read-only on the file system, so it's not possible to write files to those paths.
Next.js checks whether the source directory is writable at the beginning of the build, so this error is raised by Bazel:
$ bazel build //...
INFO: Analyzed 2 targets (1 packages loaded, 8 targets configured).
INFO: Found 2 targets...
ERROR: /path/to/bazel-frontend-examples/nextjs-app/BUILD:17:1: Action nextjs-app/build failed (Exit 1) next_build.sh failed: error executing command bazel-out/host/bin/nextjs-app/next_build.sh --src_dir nextjs-app/src --out_dir bazel-out/darwin-fastbuild/bin/nextjs-app/build ... (remaining 2 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
Error: > Build directory is not writeable. https://err.sh/zeit/next.js/build-dir-not-writeable
at build (/private/var/tmp/_bazel_spencerelliott/d59f504d8c6ae58caa702041c7337ba9/sandbox/darwin-sandbox/11/execroot/bazel_frontend_examples/node_modules/next/dist/build/index.js:1:6840)
at async main (/private/var/tmp/_bazel_spencerelliott/d59f504d8c6ae58caa702041c7337ba9/sandbox/darwin-sandbox/11/execroot/bazel_frontend_examples/nextjs-app/next-build.js:19:3)
INFO: Elapsed time: 5.136s, Critical Path: 4.83s
INFO: 0 processes.
FAILED: Build did NOT complete successfully
error Command failed with exit code 1.
I understand that Next.js needs the source directory to be writable for certain cases, like when starting a new project, certain config files need to be initialized like next-env.d.ts, etc. Could we make these optimistic / emit a warning rather than a hard requirement?
See https://github.com/Yolk-HQ/bazel-frontend-examples/tree/9bf95e584f2d5b8ac226deaeb31e3a6bffdd2a43 and follow steps in the README. Relevant build files are in the nextjs-app/ directory.
No error should be raised if the source directory is not writable.
N/A
Related feature request: https://github.com/zeit/next.js/issues/9588
Something I just realized is that my attempt to configure the distDir to Bazel's output path is not effective. Due to this code:
Next.js always joins the distDir value with the source dir value.
For example, Bazel's writable output path could be
/private/var/tmp/_bazel_spencerelliott/d59f504d8c6ae58caa702041c7337ba9/sandbox/darwin-sandbox/12/execroot/bazel_frontend_examples/bazel-out/darwin-fastbuild/bin/nextjs-app/build
But Next.js concats this path with the source path, resulting in the wrong path:
/private/var/tmp/_bazel_spencerelliott/d59f504d8c6ae58caa702041c7337ba9/sandbox/darwin-sandbox/12/execroot/bazel_frontend_examples/nextjs-app/src/private/var/tmp/_bazel_spencerelliott/d59f504d8c6ae58caa702041c7337ba9/sandbox/darwin-sandbox/12/execroot/bazel_frontend_examples/bazel-out/darwin-fastbuild/bin/nextjs-app/build
At this point we're not investigating this. Might be something we can look into under enterprise support. Feel free to email [email protected].
For anyone finding this in the future, I worked around this problem by copying all the files in the src directory to the out directory. See https://github.com/andy-zhou/bazel-frontend-examples for an example.