Greg, thanks for starting this discussion.

On Tue, Jan 23, 2018 at 4:34 PM, Gregory Szorc <g...@mozilla.com> wrote:

> Speaking as a maintainer of the Firefox build system, we try to be
> conservative about the set of dependencies required to build Firefox from
> source. We recognize that every required dependency is a potential source
> of failure and complexity. Dependencies can create complications for
> packagers. From a build system perspective, it's in our best interest to
> minimize the dependencies required to build Firefox.
>
> Our desire to keep things simple can be at odds with the wishes of Firefox
> developers who wish to leverage new and exciting tools and technologies. In
> short, the policy of minimizing build dependencies can externalize costs
> onto overall Firefox development by hindering people from using better
> tools. This adversely affects the development velocity of Firefox and can
> cause product quality to suffer.
>
> For a few years now, various pockets of Firefox development have wanted to
> use Node.js as part of the development workflow. I wouldn't say they
> directly want to use Node.js: they want to use the large ecosystem of tools
> built around Node.js. But that's splitting hairs. Our build system policy
> has been that leveraging Node.js and its ecosystem for supplemental
> workflows is fine, but shipping a build dependency on Node.js is not. Many
> Firefox developers are now using Node.js in their day-to-day workflow for
> things like running ESLint. We're using Node.js in CI. But we're not
> forcing people to have Node.js installed to build Firefox.
>

I got interested in "paving Node.js/NPM cowpaths" in existing projects that
are in some way in mozilla-central a little while ago.  I started
interviewing people and teams in such projects, and have produced an
"ecosystem matrix" of what such projects are doing at

https://docs.google.com/document/d/1beGX-xA3qtZQme-JKa2gOgyXo-GPdEXbapeYO3dY858/

(That document is supposed to be open for comment to anyone with the link;
if it's not, please let me know!)  I hope this matrix can help inform this
discussion by illuminating what's actually in use right now.  That document
also includes notes from my interviews (with the permission of the
interview subjects).


> Various groups have routed around the limitation that Node.js can't be
> required to build Firefox. There are now Firefox features that do require
> Node.js to build. However, the output from the Node.js tools is checked
> into the Firefox source repository. So from the perspective of the Firefox
> build system, Node.js doesn't exist and therefore isn't a build dependency.
>

In the dependency matrix above, the projects that are doing this are the
projects using WebPack.


> The status quo is not ideal. The more people I speak with, the more
> apparent it is that our current policy of not allowing Node.js tooling in
> the build system is causing more problems than it is preventing. Speaking
> as the build system module owner and someone who cares about developer
> workflows, tooling, and developer productivity, I don't think the current
> policy is good for Mozilla.
>
> I'd like to start a discussion about requiring Node.js to build Firefox.
>
> What do I mean by "require Node.js?" Let's assume I mean having a usable
> Node.js executable on the host system to be used during a Firefox build.
>
> What about npm or a package manager? I would strongly prefer to limit the
> required dependency to Node.js itself. While the Firefox build system would
> depend on 3rd party packages and tools (such as Babel), I'm pretty
> insistent (as a build system maintainer) that these dependencies be
> vendored into the Firefox source repository so as to not incur a run-time
> dependency on a packaging service. I've seen the chaos that "left-pad"
> caused. I don't fully trust the security model of JavaScript package
> distribution. I don't think we can risk the ability to build Firefox or the
> integrity of the Firefox product by the availability and integrity of a 3rd
> party packaging service. That may sound like a harsh thing to say. But it's
> the posture we've applied elsewhere (such as to Python packages and PyPI).
> So, this means that all JavaScript executed by Node.js as part of the build
> would either be provided by Node.js itself or the Firefox source
> repository. If we needed to use a package manager as part of the build,
> that package manager could be vendored in the Firefox repository along with
> other JavaScript libraries (not unlike how we currently vendor Python's pip
> package manager).
>

I whole-heartedly agree that vendoring required code -- that is, things
that must be NPM `dependencies` -- into mozilla-central is required for our
release management and product integrity efforts.

It's my belief that vendoring the NPM-based *tooling* -- that is, things
that could be NPM `devDependencies` -- that Firefox developers are actively
using right now would be impractical.

Just the node_modules from the testing configuration of our ES lint plugin
(eslint-plugin-{mozilla,spidermonkey}) is roughly 150 NPM packages totaling
5000 files.  We might have, say, 500-1000 NPM packages to vendor into
mozilla-central to support the existing toolchains of the 6 NPM-using
projects in the tree.  Some of those packages probably require multiple
versions.  Updating this vendored sprawl of code that *doesn't ship in
Firefox directly* seems like a waste of time and effort.  Yes, we could add
tooling to make this less painful, but I don't think we should eat that
cost; and any layer of tooling to handle this vendoring will make all
subsequent efforts more complex, and lead us to not update the vendored
code.  That in turn will lead us to not "follow the ecosystem" and make it
less likely that we'll use the best tool for the job at hand.

If we really want to avoid a build time dependency on NPM, then I think we
should think through a small set of build system primitives that we want to
support and not really think about NPM-based tooling at all.  That is, can
we support Babel, WebPack, ES lint, and perhaps Flow, for arbitrary NPM
packages checked into the tree?  (And vendor those hard dependencies into
the tree.)  If we can do that, we might even be able to stretch to running
those _limited_ dependencies in SpiderMonkey with the help of WebPack or
browserify or some other Node.js-in-the-browser conversion, plus special
sauce for SpiderMonkey and our build environment.

But that leaves us not using the NPM unit testing ecosystem (Mocha, Chai,
Sinon, Jasmine, Jest, etc), and not using the code coverage ecosystem, and
not using the editor integration ecosystem (natively), etc, etc.

On an entirely different front, Mozilla has some experience with requiring
a package service at build time.  Firefox for Android requires third-party
Maven repositories (BinTray's jcenter and Google's Android repository) at
build-time.  We have a two-stage build process in automation that collects
and caches dependencies, to isolate us from third-party outages.  Obviously
Firefox for Android is a small project compared to Gecko and Firefox for
Desktop, but early experience has been very positive.  And using Android
Studio and the features of the Android-Gradle build plugin has been a
phenomenal productivity win for the Firefox for Android teams; has enabled
proper unit testing and static analysis of the Firefox for Android code
base; and has allowed GeckoView to architect itself as a separable
component of Firefox for Android, which is critical for the long-term
success of GeckoView.

A few people at Mozilla have poked at this problem already. We have a
> general sense of where some pain points for us will be. We know that
> getting modern versions of Node.js installed on various distributions
> requires using 3rd party package repositories. We know that Windows support
> could be painful. We know that installing common packages can result of
> dozens if not hundreds of dependencies being added. We know this could lead
> to us having to install thousands of files as part of the Firefox build -
> an overhead I'm not keen on seeing. We know all of this can add up to a
> significant amount of overhead to support. (Yet it still feels like a
> lesser problem than having people work around not being able to use Node.js
> directly.)
>
> What we don't generally know is the impact requiring Node.js would have on
> downstream packagers. Our adoption of Rust last year was a long and
> sometimes painful process. I have a feeling that requiring Node.js would be
> a similar experience. But like Rust, I feel that adopting Node.js is in the
> best long-term interest for Firefox development velocity and product
> quality. I'm reluctant to cause more hardship by introducing a new build
> dependency. But it's very difficult to keep saying we can't use Node.js in
> the Firefox build system. I wish I could say "we'll build SpiderMonkey and
> use that instead." Unfortunately, many Node.js tools don't work with
> SpiderMonkey, so that's not an option. Plus there are difficulties with
> cross-compilation. As sad as it makes me to say it, SpiderMonkey is not an
> option: Node.js is the only viable option.
>

Even though I floated an alternative above (browserify and labour), I
concur that Node.js is the only viable option.


> If we require Node.js to build Firefox, what are the requirements,
> desires, and hardships of downstream packagers and consumers of the Firefox
> build system? Keep in mind that mozilla-central right now is Firefox 60.
> That will become ESR 60 in May.
>

I wish I could say more about downstream packagers but I have nothing to
add here.

Thanks again!  Long live the glorious web development ecosystem!
Nick
_______________________________________________
dev-builds mailing list
dev-builds@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-builds

Reply via email to