Feature flags in Bazel builds
pigweed.dev
pigweed.dev
That said, I've never made the leap in using Bazel for frontend stuff, I always use NPM/pnpm/yarn without any Bazel trimmings.
With Bazel setup, and it was a beast to setup, developers could run all that, with remotely cached incremental builds, efficient parallel execution, and all reproducible (and same as CI) from a local developer environment with just one command.
But even as a xoogler I think that the common wisdom of "don't use bazel until you can afford a team" or "use bazel if you are the only developer" are probably right.
My somewhat janky series of dockerfiles and bash scripts is at least debuggable to my business partner.
I'm just not ready to commit our future frontend developers to having to use bazel yet.
I'm sort of sticking to a lowest common denominator technology stack for most things except where we are spending our innovation tokens in wasm land.
But someday, probably. In the meantime I may setup sccache.
was it through bazel rules? The worry is if some of those rules will get bug or missing necessary feature, it will be pita to deal with.
Unfortunately the open source set of rules is a bit rough right now, with a decent happy path but a cliff if you’re off of it, but given some time…
To be frank, I would avoid introduction of Bazel unless you are experiencing major pains with your current system and have at least a small centralized team willing to build expertise and provide support.
If you got a big polyglot application its perfect for you. If your app is largely all in one language then you don't need that complexity in you life.
Our codebase uses a single build system for CPP, Python, CPP, GoLang, and more.
I've used with Java, Python, some C++, some R, bash, sawzall and few other langs. The beauty of it is that it can express dependencies across things from different languages (where this makes sense). Another cool thing (for Java) and FFI C/C++ code is that it can build custom java runner that embeds everything in single binary. So your FFI C/C++ code and the Java code becomes one binary.
But basically you can say - in order to build this, you also need to build this in a single language.
On top of that you can express tests too. And then it knew how to take/combine unit tests of same "size" and shard them to execute across machines.
And because you have to size your tests (e.g. RAM / CPU wise), it knows which to pick, and if your test does not fall anymore in that category it'll tell you to fix it. Might even offer command-line (nowadayws buildozer command-line) how to fix it. (That was ~2014-2016)
Then for C++ (and other langs) it'll track whether you've specified your header deps. To think about it, let's say you've said - here is a.cpp and a.cpp includes a.h - but forgot about adding explicitly a.h - Bazel (blaze) can catch that. One of the ways is simply to "symlink" only explicitly placed files in random temp folder, and compile from there - so "a.cpp" won't find "a.h" there and it'll tell - "Here run this command to add a.h to your target".
so actually quite the opposite - you want build system that unites all these different languages/runtimes/environments.
Not like - python/pip rust/cargo dotnet/nuget javascript/npm java/maven - because with each such different language specific build layer you lose how to express depedencies between them.
And not only that - in bazel deps are static, e.g. with a.h missing explicitly in your BUILD file, and bazel would tell you that. In the examples above is healthy mix of everything - from dynamic discovery to who knows what.
Then again, I get it - it's not the easiest to get through, the .bzl is dark magic sometimes, but the BUILD files should be easy to use to anyone - engineer, linguist, statistician, producers, tech art, etc.
Its funny you highlight this as a feature, because my #1 piece of feedback for the bazel ecosystem is that it really sucks to have to give up language-native tools. Whether it's LSP servers, documentation that says "add this to your gradle file", "add this to your build.sbt", it's always an uphill battle.
And then it's an uphill battle convincing product engineers to forget everything they know, do it the bazel way instead.
I get why bazel is cool, but I think it's worth highlighting that for a lot of folks it very well can make their inner development loop worse than without it, particularly if they don't have someone (or several people) dedicated solely to developer experience.
Or if you are trying to maintain bazel for an org. Invariably, you will receive requests of the form "I would like to achieve [well document thing in language-specific build tool], please help me do that in Bazel". The net result for me, who was once in that role, is that understanding the original build system, then bending bazel to match a certain behavior (usually with no or inadequate docs) is a huge amount of effort. Enough that I now am skeptical of the value-add of bazel.
In my experience, Bazel works best when:
- You have a monorepo.
- You have one engineer who knows it in and out and can stay current.
- You use several languages well-supported by Bazel (Protobuf, Go, Java, Kotlin).
The benefits are a single way to build and run all tests and binaries across all languages. Bazel CI providers (BuildBuddy, EngFlow) are much nicer than YAML engineering in other CI systems.
I have an old comment that's still representative of my experience: https://news.ycombinator.com/item?id=32831555
https://pigweed.dev/docs/overview.html
(If you're reading this, hello Keir!)