← 返回日报
略读 预计 4 分钟

Package Management as Org Chart

摘要

文章以 Conway’s Law 为起点,逐一讨论 Dependency management tooling 与 Org Chart 的关系,包括:Monorepo 和单版本策略(升级全量)、Workspaces(团队自主版本管理)、Git submodules(手动提交 SHA)、Bazel(显式声明 BUILD 文件)、Nix/Guix(纯函数构建避免 “在我机器上能跑”)、Maven 冲突解决(最近路径优先)、Artifactory 私有代理与 forks、deb/rpm 系统包、Terraform 模块、Module federation(浏览器运行时协商)、peerDependencies(框架强制约束)、Vendored 依赖(上游变化无影响)、No lockfile(每次安装最新)、semantic-release(基于 Conventional Commits 自动发布)、Go MVS(显式要求最高版本)、Brewfile(Onboarding 工具)等。每种方式都对应团队协作方式、升级成本、冲突解决机制、权限控制与实际案例,未涉及未提及的数字或结论。

荐读理由

许多依赖管理策略本质上是组织结构映射,Go MVS 按显式要求最高版本解决冲突,类似有据的组织变更决策。

原文

Conway’s Law says organisations produce systems that copy their own communication structure. Dependency management tooling is part of the system. A resolution strategy is an opinion about how disagreements get settled; a manifest format records who is allowed to depend on whom.

Monorepo, single version policy: every package in the tree must agree on one version of each dependency; upgrading anything means upgrading everyone at once. The org chart has been forbidden from appearing in the code. It works when there’s a standing migration workforce whose job is dragging every consumer along.

Monorepo with workspaces: one repository, but each package keeps its own manifest and can pin its own versions. One strong platform team, and leadership that believes coordination was solved at the 2019 offsite.

Git submodules: a dependency is referenced by exact commit SHA in a separate repository, and updating it is a manual two-step that never gets automated. Two teams agreed to collaborate and recorded, to the commit hash, exactly how little they meant it.

Bazel: every dependency edge between targets is declared explicitly in a BUILD file; nothing is ambient or inferred. Adopted when the org grew past the point where anyone knew who depended on whom by asking, so the build system was made to enforce what the humans had lost track of. Typically legible to one person, who came from Google.

Nix / Guix: builds are pure functions of their declared inputs; anything not listed in the derivation doesn’t exist at build time. “Works on my machine” has been made a structurally impossible sentence, at the cost of most of the hiring pipeline.

Maven nearest-wins mediation: when two paths through the tree want different versions of the same artifact, Maven picks whichever is fewer hops from the root, regardless of which is newer or satisfies more constraints. Conflict resolution by proximity to the top, which is also how the org settles most disagreements.

Artifactory in front of the public registries, private namespace full of forks: every install goes through a proxy the org controls, and packages that needed patching were forked in rather than contributed back. Trust is granted by a system rather than a person, and the forks date from an argument Legal won that hasn’t been reopened since.

deb/rpm packages for the in-house application: the app is built into an OS package and installed by the system package manager, and releasing goes through the same gate as a kernel update. Ops won, and has governed since. Releases are events with a runbook and at least one person whose job title contains the word “release”.

Docker: the application ships with its own copy of the operating system, so the deployment environment is whatever the developer decided at build time. Dev seceded from Ops and took the OS with them, and Ops can no longer reject an artifact that contains everything Ops used to control. The company finds out how many copies of Debian it’s running when the next xz happens.

Terraform modules from a private registry: infrastructure is packaged as versioned modules that application teams consume like any other dependency. The infra team built an interface so application teams would stop paging them, and now gets paged about the interface.

Module federation: separately built and deployed JavaScript bundles negotiate shared dependency versions with each other at runtime, in the browser. Teams report to different VPs who won’t share a meeting, so version resolution was deferred to the last possible moment, on the user’s machine, because nowhere earlier in the pipeline could agreement be reached.

peerDependencies: the package declares a version constraint on a dependency its host must provide, without shipping anything to satisfy it. A framework team issuing policy to application teams: you will be on React 18, we will check, satisfying the constraint is your problem.

Vendored dependencies: the source of each dependency is copied into the repository and committed; upstream can change or vanish without effect. An org that was hurt by an upstream once and now takes hostages; the cost is a manual merge that lives permanently in next sprint.

No lockfile, latest everywhere: each install resolves fresh against the registry, and the dependency set is whatever’s newest at that moment. The founder still commits to main, had a bad experience with npm-shrinkwrap.json years ago, and won’t touch a lockfile.

semantic-release on every merge: the version number is computed from Conventional Commits prefixes and a release is cut automatically whenever main changes. Publishing became a side effect of the commit prefix, because being the person who cut the release had become a liability.

Go MVS: resolves each dependency to the highest version anything in the graph explicitly requires, and no higher; nothing upgrades just because a newer version exists. Designed by someone who looked at SAT-solver resolution and concluded the problem was self-inflicted, and it encodes an org where change only happens when someone puts the requirement in writing.

Brewfile: the development environment is declared as a list of Homebrew packages that brew bundle installs in order. Onboarding as ritual: the file fails on line 14, and the actual mechanism for getting a working machine is a Slack thread called #dev-setup-help.


Most dependency strategies are attempts to avoid interpersonal negotiation. The tooling doesn’t remove the disagreement, it just picks who loses by default.

Lobsters · 2 赞 · 0 评 讨论 → 阅读原文 →

这条对你有帮助吗?