4 ms·
My experience with Bazel at a startup (also used Blaze at Google): The good: - Amazing for Go backends. I can push a reproducible Docker image to Kubernetes w
by sa46 4y ago
My experience with Bazel at a startup (also used Blaze at Google):
The good:
- Amazing for Go backends. I can push a reproducible Docker image to Kubernetes with a single Bazel command. I can run our entire backend with a single command that will work on any developer's box.
- Amazing for testing. All of our backends tests use a fully independent Postgres database managed by Bazel. It's really nice not having to worry about shared state in databases across tests.
- We can skip Docker on macOS for development which provides on the order of a 10x speedup for tests.
- BuildBuddy provides a really nice CI experience with remote execution. Bazel tests are structured so I can see exactly which tests failed without trawling through thousands of lines of log output. I've heard good things about EngFlow but BuildBuddy was free to start.
- Really nice for schema driven codegen like protobufs.
The bad:
- Bazel is much too hard for TypeScript and JavaScript. We don't use Bazel for our frontend. New bundlers like Vite are much faster and have a developer experience that's hard to replicate with Bazel. Aspect.dev is doing some work on this front. One large hurdle is there's not automatic BUILD file dependency updater like Gazelle for Go.
- Windows support is too hard largely because most third party dependencies don't work well with Windows.
- Third party dependencies are still painful. There's ongoing work with bzlmod but my impression is that it won't be usable for a couple of years.
- Getting started was incredibly painful. However, the ongoing maintenance burden is a few hours per month.
- lhorie 4y ago> Bazel is much too hard for TypeScript and JavaScript. We don't use Bazel for our frontend. New bundlers like Vite are much faster and have a developer experience that's hard to replicate with Bazel. Aspect.dev is doing some work on this front. One large hurdle is there's not automatic BUILD file dependency updater like Gazelle for Go. I built this[0] for the Bazel + yarn setup that we use at Uber. We currently manage a 1000+ package monorepo with it. [0] https://github.com/uber-web/jazelle https://github.com/uber-web/jazelle
- hamandcheese 4y ago> Amazing for testing. All of our backends tests use a fully independent Postgres database managed by Bazel. It's really nice not having to worry about shared state in databases across tests. I would love to know more about this. We use bazel and Postgres, but there is no Postgres isolation between tests currently which is very predictably a large source of flakyness, and also a blocker for increasing test parallelism. I’ve been scheming on perhaps using pg_tmp orchestrated outside of bazel, but if there’s a way to do everything in bazel that would make the transition way easier.
- jvolkman 4y agoNot OP, but we start small postgres instances in our Python tests with some py.test fixtures. The actual postgres binaries are provided by Bazel, so nothing relies on outside installations. I posted this gist a while ago: https://gist.github.com/jvolkman/6e61c52d953677f66f32d8f77b157e61 https://gist.github.com/jvolkman/6e61c52d953677f66f32d8f77b1... That said, this requires one postgres instance for each test, which is pretty heavy. So we keep our tests pretty coarse at the Bazel level (i.e. one Bazel test is actually 10+ Python tests). I've thought about other approaches, such as using a Bazel persistent worker to wrap test execution and manage a single Postgres instance with empty databases created from templates, but never got around to trying anything.
- hamandcheese 4y agoNice, this seems a lot simpler than I thought. Nice tip on embedded-postgres-binaries (https://github.com/zonkyio/embedded-postgres-binaries https://github.com/zonkyio/embedded-postgres-binaries).
- sa46 4y agoOld comment with some details: https://news.ycombinator.com/item?id=28472062 https://news.ycombinator.com/item?id=28472062 In addition to the techniques in the linked comment, I'm currently investigating managing the entire Postgres data dir as a Bazel output directory. That way, we avoid executing the schema for every test. Instead, we'd start a new Postgres cluster against the existing data dir without re-executing the schema or creating from a template DB.
- badoongi 4y ago> I can run our entire backend with a single command that will work on any developer's box. Curious wouldn't `go run` give you the same? pure go code is supposed to be portable, unless you have cgo deps I guess? > I can push a reproducible Docker image to Kubernetes with a single Bazel command. That's definitely an upside over what would otherwise would probably default to a combination of Dockerfiles and scripts/Makefiles, does it worth bringing in the massive thing that is Bazel? depends I guess. I'm curious: would you say your experience with golang IDEs / gopls is degraded? did you do anything special to make it good? I often feel like development is more clunky and often I just give up on the nice-to-haves of a language server e.g often some dependencies in the IDE aren't properly indexed, I can probably get Bazel to do some fetching, reindex and get it working, but it will take 3-4 minutes and I just often choose to live with the thing appearing as "broken" in the IDE and getting less IDE features.
- sa46 4y ago> Curious wouldn't `go run` give you the same? We use protobufs and pggen. Bazel transparently manages the codegen from proto file to Go code. > would you say your experience with golang IDEs / gopls is degraded? Yes, that's our biggest pain point with Go and Bazel. I haven't been able to coax IntelliJ into debugging Bazel managed binaries. To enable IntelliJ code analysis, we copy the generated code into the src directory (with a Bazel rule auto-generated by Gazelle) but don't add it to Git. I've tried the IntelliJ with Bazel plugin a few times but I've always reverted back to stock IntelliJ.