Node Package Managers · Part 3 — Yarn Classic (v1)
What Yarn v1 fixed about 2016-era npm: deterministic installs, the yarn.lock format, parallel fetching and offline cache — and why it is now frozen in maintenance mode.
Đây là Phần 3 của series 12 phần về package manager Node. Ta đã đi qua mô hình tư duy và npm chuyên sâu. Giờ là Yarn Classic, version 1.
Yarn v1 quan trọng vì hai lý do: nó vẫn nằm trong hàng triệu repo bạn sẽ kế thừa, và hiểu vì sao nó xuất hiện là chìa khoá để hiểu vì sao Yarn v4 chẳng giống nó (Phần 4).
1. Vì sao Yarn ra đời (2016)
Năm 2016, npm có ba vấn đề đau đớn mà Facebook gặp ở quy mô lớn:
1. NON-DETERMINISM {không xác định}
npm install at different times → different node_modules.
The old npm-shrinkwrap was opt-in and rarely used.
2. SLOW, SERIAL {chậm, tuần tự}
npm fetched and installed packages mostly one after another.
3. NO OFFLINE {không offline}
No first-class global cache to install without the network.
Yarn v1 trả lời cả ba: một lockfile luôn bật cho tính xác định, mạng + I/O song song cho tốc độ, và một cache offline toàn cục. Nó nhanh và đáng tin hơn hẳn npm thời đó.
Bối cảnh quan trọng: nhiều cải tiến của Yarn sau này được npm hấp thụ. npm v5 (2017) thêm
package-lock.jsonluôn bật; npm nhanh hơn và cónpm ci. Khoảng cách từng biện minh cho Yarn v1 phần lớn đã khép lại.
2. Kiến trúc — tương thích npm, chỉ là kỹ thuật tốt hơn
Quan trọng: Yarn Classic dùng cùng node_modules phẳng, hoisted như npm. Nó không phải mô hình dependency khác — nó là bản hiện thực nhanh hơn, xác định hơn của mô hình npm:
package.json + yarn.lock
│ yarn install
▼
resolve → parallel fetch → global cache (~/.cache/yarn) → flat node_modules/
↑ same hoisting as npm
Đây là lý do Yarn v1 kế thừa mọi vấn đề layout của npm từ Phần 2: phantom dependency và doppelganger cũng tồn tại ở đây. Yarn v1 cải thiện bản hiện thực, không phải mô hình.
3. Định dạng yarn.lock
Lockfile của Yarn v1 là định dạng văn bản tuỳ chỉnh, đọc được. Mỗi entry ánh xạ range được yêu cầu tới một version đã resolve:
# yarn.lock — note: multiple ranges can share one resolution
lodash@^4.17.0, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#abc..."
integrity sha512-v2kDEe57lecT...
react@^19.0.0:
version "19.1.4"
resolved "https://registry.yarnpkg.com/react/-/react-19.1.4.tgz#def..."
integrity sha512-AbCdEf...
Hai lựa chọn thiết kế cần để ý:
- Khử trùng range:
lodash@^4.17.0cả hai cùng resolve về một version, liệt kê một lần. File gọn và cây phẳng hơn. resolved+integrity: cùng đảm bảo như npm — URL tarball chính xác và hash xác minh được.
Nó làm cùng việc với package-lock.json, chỉ là cú pháp gọn hơn, dễ diff hơn.
Chuyển integrity sha1 → sha512
File yarn.lock cũ (trước 2019) ghi integrity là fragment #sha1 trên URL resolved; bản hiện đại dùng dòng riêng integrity sha512-...:
# OLD — weak, attached to the URL
resolved "https://.../lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
# MODERN — strong SHA-512, separate field (what you want)
resolved "https://.../lodash-4.17.21.tgz#..."
integrity sha512-v2kDEe57lecT...
SHA-1 đã bị phá về mặt mật mã. Nếu bạn kế thừa lockfile cổ chỉ có sha1, tạo lại nó (xoá + yarn install) trên máy tin cậy để mọi entry có integrity sha512.
4. Bộ lệnh hằng ngày
CLI của Yarn v1 là thứ mà phần lớn “trí nhớ cơ bắp yarn” dựa vào:
yarn # install from yarn.lock (alias of `yarn install`)
yarn add react # add a dependency
yarn add -D vite # add a devDependency
yarn remove lodash # remove a dependency
yarn upgrade react@^19 # change a range and re-resolve
yarn install --frozen-lockfile # CI: fail if yarn.lock would change
yarn why lodash # explain why a package is in the tree
Chú ý --frozen-lockfile: đây là tương đương npm ci của Yarn v1 và là flag CI đúng. Ở Yarn Berry flag này đổi tên thành --immutable (Phần 4).
--frozen-lockfile vs --pure-lockfile — bẫy CI tinh vi
Hai flag nghe giống nhau làm việc khác nhau, chọn sai làm yếu CI:
--pure-lockfile don't WRITE yarn.lock, but it MAY still resolve new
versions in memory → NOT a real guarantee
{không GHI yarn.lock, nhưng VẪN có thể resolve version mới → không đảm bảo thật}
--frozen-lockfile FAIL if the install would change yarn.lock at all
→ this is the one you want in CI
{FAIL nếu install làm đổi yarn.lock → đây là cái bạn cần trong CI}
Một vết cũ đã biết: ở vài version Yarn v1, --frozen-lockfile không bắt mọi trường hợp lệch. Mẫu CI vững là chạy thêm yarn check --integrity hoặc kiểm tra lockfile không đổi bằng git diff --exit-code yarn.lock sau install.
5. Điểm mạnh vẫn còn giá trị
- Ổn định cực vững: một thập kỷ tôi luyện production; gần như không bao giờ làm bạn bất ngờ.
- Lượng cài đặt khổng lồ: vô số tutorial, template CI, image Docker mặc định
yarn. yarn whythực sự hữu ích để debug cây phình to.- CLI quen thuộc, công thái học:
yarn adddễ chịu hơnnpm install --savetừng có.
Hai tính năng mạnh bạn sẽ gặp trong repo v1
resolutions và nohoist có trước overrides của npm và phổ biến trong codebase cũ:
{
// force a deep transitive version (npm's "overrides" equivalent)
"resolutions": { "**/minimist": "1.2.6" },
// workspaces only: keep a package OUT of the hoisted root
// (needed for React Native and other tools that hate duplicate copies)
"workspaces": {
"packages": ["packages/*"],
"nohoist": ["**/react-native", "**/react-native/**"]
}
}
Và offline mirror — Yarn v1 có thể vendor mọi tarball vào repo, cho phép install hoàn toàn offline, không cần mạng (tổ tiên tinh thần của zero-install ở Berry):
# .yarnrc
yarn-offline-mirror "./.yarn-offline-mirror"
yarn-offline-mirror-pruning true
6. Vì sao nó bị đóng băng — chế độ bảo trì
Team Yarn ra một quyết định khó: v1 chỉ còn bảo trì. Mọi phát triển mới chuyển sang bản viết lại từ đầu, Yarn Berry (v2+). Tài liệu chính thức nói thẳng project mới nên dùng dòng hiện đại.
Yarn 1.x ──────────────● frozen: critical fixes only, no new features
\
●──→ Yarn 2/3/4 (Berry): different codebase,
different config, Plug'n'Play by default
{khác codebase, khác config, PnP mặc định}
Vậy phán quyết thật năm 2026:
- Project mới? Đừng chọn Yarn v1. Dùng pnpm, Yarn Berry, Bun, hoặc npm.
- Kế thừa repo v1? Cứ để nó chạy — nó ổn định. Lên kế hoạch migrate khi cần nghiêm ngặt, tiết kiệm disk, hoặc tốc độ.
- Đừng nhầm v1 và v4. Chúng chung cái tên và gần như không gì khác. Sự nhầm lẫn đó chính là lý do Phần 4 tồn tại.
Giờ bạn đã biết gì
- Yarn v1 sửa các khoảng cách không-xác-định, tốc độ, offline của npm 2016.
- Nó dùng cùng
node_modulesphẳng hoisted, nên kế thừa phantom dep + doppelganger. yarn.locklà lockfile văn bản gọn với khử trùng range + integrity.- v1 chỉ bảo trì; cái mới dùng Berry/pnpm/Bun.
Bài tập
- Chạy
yarn why <dep-transitive>và lần ra vì sao nó được cài. - So sánh
yarn.lockvàpackage-lock.jsoncho cùng dep — chú ý cách Yarn khử trùng range. - Đọc đầu
yarn.lock: nó cảnh báo “file tự sinh, đừng sửa” — giải thích cho đồng đội vì sao điều đó quan trọng.
Tiếp theo — Phần 4: Yarn Berry (v2–v4) & Plug’n’Play: