File này là luật hệ thống bắt buộc. Mọi session làm việc trên repo này PHẢI đọc và tuân thủ trước khi thao tác.
- Repo gốc: JavaGuide — tài liệu tiếng Trung về Java backend & phỏng vấn (455 file
.md, ~9.5MB), build bằng VuePress 2 + theme-hope. - Mục tiêu: tạo bản tiếng Việt hoàn chỉnh của tài liệu, đặt trong thư mục
vi/ở root repo, giữ nguyên 100% cấu trúc thư mục củadocs/.docs/java/basis/reflection.md→vi/java/basis/reflection.mddocs/roadmap/java-roadmap.md→vi/roadmap/java-roadmap.md
- Thứ tự dịch: theo lộ trình học (
docs/roadmap/), không dịch ngẫu nhiên — để người đọc có thể học tuần tự ngay khi bản dịch đang tiến hành. - Tiến độ: theo dõi tại
vi/PROGRESS.md. Luôn đọc file này đầu session để biết dịch tiếp từ đâu.
| # | Luật |
|---|---|
| 1 | KHÔNG sửa, xoá, di chuyển bất kỳ file gốc nào trong docs/, media/, scripts/, .vuepress/. Repo gốc là read-only. |
| 2 | Mọi bản dịch chỉ ghi vào vi/. Không đụng package.json, sidebar, navbar gốc. |
| 3 | Giữ nguyên core — không thêm ý, không bịa, không "bổ sung cho đầy đủ", không thêm lời bình của người dịch. |
| 4 | Không dịch lan man. Câu tiếng Việt ngắn hơn hoặc bằng độ dài ý gốc. Tiếng Trung vốn súc tích — bản dịch không được phình ra. |
| 5 | Bất kỳ ký tự tiếng Trung nào cũng phải được dịch, kể cả trong code block, comment code, tên biến mô tả, chú thích ảnh, bảng, sơ đồ ASCII. Không để sót chữ Hán. |
| 6 | Ưu tiên English-first cho technical/domain terms theo ngữ cảnh (xem §4). GLOSSARY.md là baseline, không phải whitelist; không ép Việt hoá term đã chuẩn hoặc term mà dịch ra làm câu kém tự nhiên/chính xác. |
Dịch title, description, tagline, category, tag, content (keywords), text trong actions.
Giữ nguyên: icon, head, sitemap, changefreq, priority, heroImage, footer, home, tên khoá YAML.
# Gốc # Dịch
title: Java 基础常见面试题总结 → title: Tổng hợp câu hỏi phỏng vấn Java Basics thường gặp
category: Java → category: Java # tên category kỹ thuật giữ nguyên
tag:
- Java基础 → - Java BasicsTiếng Trung dùng dấu hai chấm fullwidth : (an toàn trong YAML). Tiếng Việt dùng : thường
→ làm vỡ YAML và fail build. Đây là lỗi đã thực sự xảy ra:
error YAMLException: incomplete explicit mapping pair; a key node is missed
Quy tắc: nếu giá trị trong frontmatter chứa : (hai chấm + khoảng trắng), kết thúc bằng :,
hoặc chứa # → phải bọc trong dấu nháy kép.
# SAI - vỡ build
title: Tổng hợp lộ trình học: Java backend, AI Agent
# ĐÚNG
title: "Tổng hợp lộ trình học: Java backend, AI Agent"Script quét & sửa hàng loạt (chạy sau mỗi batch dịch):
python3 - <<'EOF'
import glob,re
for f in glob.glob('vi/**/*.md', recursive=True):
src=open(f,encoding='utf-8').read()
if not src.startswith('---\n'): continue
end=src.index('\n---\n',3); fm=src[4:end+1]; rest=src[end+1:]
out=[];ch=False
for line in fm.split('\n'):
m=re.match(r'^(\s*(?:-\s+)?[A-Za-z_][\w.-]*:)\s(.*)$', line)
v=m.group(2).strip() if m else ''
if m and v and v[0] not in '"\'|>[{&*!%@`' and (': ' in v or v.endswith(':') or ' #' in v):
out.append(f'{m.group(1)} "{v.replace(chr(92),chr(92)*2).replace(chr(34),chr(92)+chr(34))}"');ch=True
else: out.append(line)
if ch: open(f,'w',encoding='utf-8').write('---\n'+'\n'.join(out)+rest); print('fixed',f)
EOF- Đường dẫn link nội bộ:
./java-basic-questions-01.md,/home.md— giữ y nguyên (cấu trúcvi/mirrordocs/nên link tự đúng). - URL ngoài, ảnh
https://oss.javaguide.cn/...,![...]()— giữ nguyên URL, dịch phần alt text. - Directive VuePress:
<!-- @include: @article-footer.snippet.md -->,::: tip,::: warning,:::— giữ nguyên cú pháp, dịch nội dung bên trong. Nhãn::: tip 提示→::: tip Gợi ý. - Code: tên class/method/biến/keyword/API/config key, output log, SQL, JSON — giữ nguyên. Chỉ dịch comment và chuỗi string tiếng Trung.
- HTML thô,
<!-- markdownlint-disable -->, badge, table alignment.
// GỐC
// 创建一个线程池,核心线程数为 5
ExecutorService pool = Executors.newFixedThreadPool(5);
System.out.println("任务执行完成");
// DỊCH
// Tạo một thread pool với core thread số lượng là 5
ExecutorService pool = Executors.newFixedThreadPool(5);
System.out.println("Task thực thi hoàn tất");Chỉ 3 trường hợp, ngoài ra không có ngoại lệ nào khác:
- Mã định danh pháp lý / số đăng ký: ví dụ
鄂ICP备2020015769号-1trong footer. Là số giấy phép, dịch ra sẽ sai. - Từ khoá người dùng phải gõ/nhắn nguyên văn: ví dụ nhắn
微信cho bot WeChat, nhắn学习路线cho tài khoản công khai. Giữ nguyên chữ Hán, thêm chú giải tiếng Việt trong ngoặc:nhắn "**微信**" (WeChat). - Tên riêng trong URL / đường dẫn ảnh: không đụng tới URL.
Mọi chữ Hán khác đều phải dịch. Khi verify thấy sót, kiểm tra xem có rơi vào 3 ca trên không — nếu không thì phải dịch.
- Xưng hô: "bạn" (người đọc), tránh "chúng ta/tôi" trừ khi bản gốc dùng ngôi thứ nhất.
- Văn phong kỹ thuật, trực tiếp, không hoa mỹ.
- Câu hỏi phỏng vấn giữ dạng câu hỏi.
- Dịch nghĩa, không dịch từng chữ. Thành ngữ Trung → diễn đạt tự nhiên tiếng Việt.
Mục tiêu: bản dịch phải đọc giống tài liệu kỹ thuật do developer Việt viết, không phải bản Việt hóa từng từ.
GLOSSARY.mdlà baseline, không phải whitelist. Term chưa có trong glossary vẫn giữ English nếu đó là technical/domain concept và cách dùng English tự nhiên, chính xác hơn trong ngữ cảnh.- Không ép dịch một term chỉ vì có từ tiếng Việt tương đương. Ưu tiên giữ English cho các concept trong architecture, runtime, workflow và domain model như
system,backend,frontend,service,module,request,response,payload,repository,entity,transaction,query,filter,handler,listener,message,event,job,task,workflow,upstream,downstream,sync,async,batch,retry,timeout,fallback,cache,validation,mapping,binding,build,deploy. - Với domain/business workflow, ưu tiên term mà system/team dùng như một concept:
order,approval,inventory,fulfillment,procurement,finance,payment,price, ... nếu Việt hóa làm mất tính nhất quán với model/API/flow. - Technical verbs có thể giữ English khi cách đó tự nhiên và chính xác hơn:
validate,map,bind,serialize,deserialize,persist,flush,commit,rollback,retry,resolve,reserve,publish,consume,mock,override. - Dịch phần ngữ pháp, liên từ và diễn giải thông thường sang tiếng Việt. Mục tiêu là một câu tiếng Việt có English technical terms đúng chỗ, không phải biến cả câu thành English.
- Quyết định theo meaning trong câu, không theo token. Ví dụ:
requestlà HTTP/domain object thì giữrequest; “request access” dùng như động từ thông thường có thể dịch là “yêu cầu quyền truy cập”.orderlà domain entity thì giữorder; “in order to” phải dịch theo nghĩa ngữ pháp. - Một concept dùng một term nhất quán trong cùng file/section. Không xen kẽ
request/“yêu cầu”,transaction/“giao dịch”,repository/“kho lưu trữ” nếu đang nói cùng technical concept. - Không tự thêm bản dịch tiếng Việt trong ngoặc sau mỗi English term. Chỉ giải thích ở lần đầu nếu concept khó và source/ngữ cảnh thực sự cần làm rõ.
- API/type/identifier giữ đúng casing gốc như
Authentication,JpaRepository; prose term dùng casing thông thường nhưrequest,transaction,repository.
Ví dụ style mục tiêu:
System chủ yếu phục vụ nhân viên procurement và finance, phụ trách tra cứu sản phẩm, tạo order, approval, đồng bộ trạng thái thanh toán và tra cứu fulfillment. Backend được tách thành các module order, inventory và approval; khi tạo order, trước tiên sẽ validate request và price, sau đó tạo order và reserve inventory. Sau khi thành công, system gửi message để downstream hoàn thành các task async như thông báo approval.
Không sửa meaning của source chỉ để làm câu “kỹ thuật hơn”; chỉ giữ English khi term đó thực sự là technical/domain concept trong ngữ cảnh.
Các term sau mặc định giữ English khi được dùng như technical concept (danh sách mở rộng khi gặp term mới):
Java core: thread, thread pool, heap, stack, garbage collection (GC), class loader, bytecode, JVM, JDK, JRE, reflection, generic, wildcard, type erasure, serialization, annotation, lambda, stream, interface, abstract class, override, overload, encapsulation, inheritance, polymorphism, autoboxing, immutable, singleton, enum, record, virtual thread, checked/unchecked exception.
Concurrency: lock, deadlock, race condition, atomic, volatile, synchronized, CAS, AQS, JMM, happens-before, memory barrier, context switch, blocking/non-blocking, fair/unfair lock, reentrant, CountDownLatch, Semaphore, ThreadLocal.
Collection: List, Map, Set, Queue, hash, hash collision, load factor, capacity, red-black tree, linked list, array, iterator, fail-fast.
Database: index, clustered index, transaction, isolation level, dirty read, phantom read, ACID, MVCC, B+ tree, sharding, replication, master-slave, deadlock, lock escalation, execution plan, connection pool, binlog, redo log, undo log.
Distributed / System design: load balancing, cache, cache penetration/breakdown/avalanche (cache xuyên thấu / sập cache / cache avalanche — dịch kèm giữ tiếng Anh lần đầu), CAP, BASE, consistency, availability, partition tolerance, RPC, message queue, idempotent, rate limiting, circuit breaker, service discovery, distributed lock, CDN, microservice.
Network / OS: TCP, UDP, HTTP, HTTPS, handshake, DNS, socket, process, thread, context switch, kernel, user space, paging, virtual memory, deadlock, I/O multiplexing, epoll, zero-copy.
AI: LLM, prompt, token, embedding, RAG, Agent, MCP, fine-tuning, inference, context window, function calling, vector database.
Chung: framework, middleware, source code, build, deploy, commit, merge, refactor, performance, throughput, latency, backend, frontend, API, SDK, CLI.
| Tiếng Trung | Tiếng Việt |
|---|---|
| 面试题 | câu hỏi phỏng vấn |
| 学习路线 | lộ trình học |
| 总结 | tổng hợp / tóm tắt |
| 详解 | giải thích chi tiết |
| 原理 | nguyên lý |
| 底层 | tầng dưới / bên trong |
| 常见 | thường gặp |
| 优缺点 | ưu / nhược điểm |
| 使用场景 | trường hợp sử dụng |
| 注意事项 | lưu ý |
| 建议阅读顺序 | thứ tự đọc đề xuất |
| 适合谁看 | dành cho ai |
| 学习重点 | trọng tâm học |
- Đọc
vi/PROGRESS.md→ xác định file tiếp theo trong hàng đợi. - Đọc file gốc bằng CodeGraph (§6), không dùng grep/find mò mẫm.
- Dịch nguyên file, ghi vào đúng đường dẫn mirror trong
vi/. - Verify:
grep -P '[\x{4e00}-\x{9fff}]' <file dịch>→ phải rỗng. Nếu còn chữ Hán, dịch tiếp cho sạch. - Cập nhật
vi/PROGRESS.md(đánh dấu ✅, ghi ngày). - Không commit trừ khi người dùng yêu cầu.
Giai đoạn 1 — Trục lộ trình: docs/roadmap/**, docs/README.md, docs/home.md
Giai đoạn 2 — Java core: docs/java/README.md → basis → collection → concurrent → jvm → io → new-features
Giai đoạn 3 — CS basics: docs/cs-basics/** (network, os, data-structure, algorithms)
Giai đoạn 4 — Database: docs/database/** (mysql, redis, sql, mongodb, elasticsearch)
Giai đoạn 5 — Framework: docs/system-design/**
Giai đoạn 6 — Phân tán: docs/distributed-system/**, high-performance, high-availability
Giai đoạn 7 — Còn lại: docs/ai/**, ai-coding/**, tools/**, books/**, interview-preparation/**, v.v.
Trong mỗi thư mục: dịch README.md trước (nó là mục lục + thứ tự đọc), rồi theo đúng thứ tự README.md liệt kê.
Repo đã index (.codegraph/ tồn tại), nhưng CodeGraph chỉ index source code (.vuepress/** — TypeScript, Vue), KHÔNG index file .md. Đã xác minh: codegraph_node docs/snippets/*.md → "No indexed file matches".
| Việc cần làm | Công cụ |
|---|---|
Đọc file tài liệu .md để dịch |
cat / Read — CodeGraph không phủ |
| Hiểu cấu hình VuePress, sidebar, navbar, theme, component Vue | mcp__codegraph__codegraph_explore "<symbol/câu hỏi>" — bắt buộc dùng trước grep/find |
Tìm một symbol trong .vuepress/ |
mcp__codegraph__codegraph_node <symbol> |
| Quét sót chữ Hán trong bản dịch | grep -P '[\x{4e00}-\x{9fff}]' |
Khi cần tra cứu cấu trúc site (thứ tự sidebar, alias @snippet, route), luôn hỏi CodeGraph trước, đừng grep mò trong .vuepress/.
vi/
├── PROGRESS.md # bảng tiến độ — nguồn sự thật duy nhất về trạng thái dịch
├── GLOSSARY.md # thuật ngữ đã chốt, bổ sung dần khi gặp từ mới
├── README.md # bản dịch docs/README.md
├── roadmap/
├── java/
├── cs-basics/
└── ... # mirror y hệt docs/
vi/ không chứa .vuepress/, snippets/*.snippet.md được dịch và giữ nguyên tên file.
vi/ không chỉ là thư mục bản dịch, nó là một site VuePress hoàn chỉnh thứ 2, dùng chung
theme/component/style với site gốc nên UI giống hệt. File gốc trong docs/ không bị đụng tới.
vi/.vuepress/
├── config.ts base:"/vi/" dest:"./dist/vi" lang:"vi-VN" ← khác bản gốc
├── theme.ts docsDir:"vi", SEO/JSON-LD tiếng Việt, canonical /vi
├── navbar.ts đã dịch
├── sidebar/ đã dịch (11 file)
├── components/ đã dịch chuỗi UI (LayoutToggle, unlock, mermaid, image preview)
├── features/ đã dịch comment
├── styles/ đã dịch comment (SCSS y hệt bản gốc → UI không đổi)
└── public/ copy nguyên (logo, favicon, icon)
pnpm install # lần đầu
pnpm vi:dev # dev server site tiếng Việt
pnpm vi:build # build ra dist/vi
pnpm build:all # build site gốc (dist/) RỒI site vi (dist/vi/) — đúng thứ tựThứ tự build quan trọng: vuepress build docs ghi vào dist/, có thể xoá sạch thư mục đó.
Luôn build docs trước, vi sau — pnpm build:all đã làm đúng thứ tự.
| Mục | Trạng thái |
|---|---|
base: "/vi/" |
Mọi asset/route đều có prefix /vi/. Đổi base phải rebuild toàn bộ. |
linksCheck: build "warn" |
Tạm hạ từ "error" vì sidebar trỏ tới trang chưa dịch. Đổi lại "error" khi dịch xong toàn bộ. |
legacyRedirects = {} |
Đã làm rỗng — redirect cũ là URL tiếng Trung của site gốc, vô nghĩa dưới /vi/. |
trimDescription() |
Đã đổi dấu câu 。!?,、 → . ! ? , ; — không đổi thì hàm không bao giờ tìm được điểm ngắt trong văn bản tiếng Việt. |
PROGRESS.md, GLOSSARY.md |
Đã loại khỏi pagePatterns, không build thành trang. |
pnpm vi:build # phải "success"
grep -o 'href="/vi/assets[^"]*"' dist/vi/index.html | head -1 # phải có prefix /vi/
grep -o '<html[^>]*>' dist/vi/index.html # phải lang="vi-VN"Fork này phải pull được code mới từ repo gốc mà không bao giờ conflict. Muốn vậy:
KHÔNG sửa bất kỳ file nào mà upstream cũng sửa.
Mọi thứ của bản dịch nằm trong các file/thư mục mà upstream không hề có:
| Đường dẫn | Chủ sở hữu | Ghi chú |
|---|---|---|
docs/** |
upstream | Read-only tuyệt đối. Kể cả .vuepress/. |
package.json, pnpm-lock.yaml |
upstream | KHÔNG được đụng. 54/200 commit gần nhất sửa file này. |
vi/** |
fork | Nội dung dịch + site VuePress riêng |
i18n/** |
fork | Nút đổi ngôn ngữ + công cụ sync |
Makefile |
fork | Toàn bộ lệnh (thay cho npm scripts) |
CLAUDE.md |
fork | File luật này |
❌ Đừng bao giờ thêm script vào package.json — dùng Makefile.
❌ Đừng bao giờ sửa docs/.vuepress/ để thêm tính năng — bọc ngoài bằng i18n/cn.config.ts.
Site tiếng Trung cần nút chuyển ngôn ngữ, nhưng navbar của nó nằm trong docs/.vuepress/ (của upstream).
Giải pháp: wrapper config + root component, không đụng docs/:
i18n/cn.config.ts import config upstream → spread → thêm plugin
i18n/lang-switch/plugin.ts VuePress plugin, inject __LANG_SITE__ + __VI_ROUTES__
i18n/lang-switch/client.ts đăng ký root component
i18n/lang-switch/LangSwitch.vue nút [中文 | VI], Teleport vào .vp-navbar-end
i18n/lang-switch/vi-routes.mjs quét vi/**/*.md → danh sách route đã dịch
Chạy site CN bằng npx vuepress dev docs -c i18n/cn.config.ts (đã gói trong make cn-dev).
Vị trí nút: component được <Teleport> vào .vp-navbar-end của theme (góc trên-phải,
cạnh nút GitHub/theme) sau khi mount — lúc SSR đích teleport chưa tồn tại nên component
render rỗng, tránh hydration mismatch. Nếu không tìm thấy .vp-navbar-end (theme đổi cấu trúc),
nó tự rơi về chế độ pill nổi góc dưới-phải thay vì biến mất.
grep lang-switch dist/...
để kiểm tra. Phải dump DOM sau khi JS chạy:
chromium --headless --disable-gpu --no-sandbox --virtual-time-budget=8000 \
--dump-dom http://localhost:9099/roadmap/java-roadmap.html | grep -o 'lang-seg[^>]*'Ánh xạ trang: page.path không chứa base nên giống nhau ở cả 2 site.
/java/basis/reflection.html ↔ /vi/java/basis/reflection.html.
Trang chưa dịch → nút VI mờ đi và trỏ về /vi/ thay vì link gãy.
git remote add upstream https://github.com/Snailclimb/JavaGuide.git # lần đầu
git fetch upstream && git merge upstream/main # không conflict vì docs/ chưa bị đụng
make sync # xem file mới / file gốc đã đổi
# ... dịch các file đó vào vi/ ...
make sync-mark # đánh dấu đã đồng bộ tới HEADmake sync báo 3 thứ:
- Chưa dịch: có trong
docs/nhưng chưa có trongvi/ - Gốc đã đổi: file
docs/thay đổi kể từ commit đánh dấu lần cuối → bản dịch bị cũ - Orphan: có trong
vi/nhưng upstream đã xoá/đổi tên
Trạng thái lưu ở i18n/.sync-state.json.
Site CN và site VI là hai VuePress app riêng, mặc định chạy hai port khác nhau.
Nút đổi ngôn ngữ dùng đường dẫn tuyệt đối (/ và /vi/) nên bắt buộc hai site
phải cùng một origin, nếu không sẽ 404.
Giải pháp: dev server CN (8080) proxy /vi/* sang dev server VI (8081), khai báo qua
extendsBundlerOptions trong langSwitchPlugin (option devViPort).
make dev # chạy cả hai, LUÔN mở http://localhost:8080/make cn-dev một mình → /vi/ sẽ 502 (không có server 8081).
http://localhost:8081/vi/ → nút 中文 sẽ 404 (port đó không có site CN).
make dev có preflight chặn trường hợp này; dọn bằng pkill -f 'vuepress[ ]dev'
(viết dấu ngoặc như vậy để pkill không tự khớp chính nó).
Bug đã gặp và đã sửa: site VI có base /vi/ nên trả 404 cho /vi (thiếu / cuối).
Proxy có rewrite thêm dấu / cho đúng path đó.
make help # danh sách lệnh
make dev # CẢ HAI site trên :8080 (dùng cái này để test nút đổi ngôn ngữ)
make cn-dev # chỉ site tiếng Trung :8080
make vi-dev # chỉ site tiếng Việt :8081/vi/
make build # build cả hai, đúng thứ tự -> dist/ + dist/vi/
make sync # trạng thái đồng bộ sau khi pull
make check # quét chữ Hán còn sót trong vi/Một project Vercel duy nhất phục vụ cả hai site: / là 中文, /vi/ là Tiếng Việt.
Khớp đúng với base: "/vi/" đã cấu hình.
vercel.json (file của fork, upstream không có → zero-conflict):
{
"buildCommand": "vuepress build docs -c i18n/cn.config.ts && vuepress build vi",
"outputDirectory": "dist",
"framework": null
}Vì sao viết vậy:
| Mục | Lý do |
|---|---|
Hai lệnh nối bằng && |
Build CN trước (ghi dist/, xoá sạch thư mục), rồi VI (ghi dist/vi/). Đảo thứ tự là mất bản VI. |
Không dùng make |
Build image của Vercel không đảm bảo có make. Gọi thẳng vuepress. |
-c i18n/cn.config.ts |
Không có cờ này thì site CN mất nút đổi ngôn ngữ. |
framework: null |
Không để Vercel tự đoán preset và ghi đè lệnh build. |
Không bật cleanUrls |
VuePress sinh link có đuôi .html. Bật cleanUrls là gãy toàn bộ link nội bộ. |
Không đặt trailingSlash |
Để mặc định Vercel; /vi/ tự trỏ dist/vi/index.html. |
git add CLAUDE.md Makefile vercel.json i18n/ vi/
git commit -m "feat: bản dịch tiếng Việt + site VuePress thứ 2"
git pushRồi trên Vercel: Add New Project → import repo → Deploy.
Không cần chỉnh gì trong UI, vercel.json đã khai báo đủ.
Vercel tự nhận pnpm từ pnpm-lock.yaml và packageManager trong package.json.
dist/nằm trong.gitignore— đúng, Vercel tự build chứ không lấy bản có sẵn.- Build CN render 641 trang nên chậm hơn hẳn build VI. Số đo thực tế ở §10.4.
- Deploy lên domain khác cho riêng bản VI thì phải đổi
basetrongvi/.vuepress/config.tstừ"/vi/"về"/", và sửa lại đường dẫn trongi18n/lang-switch/LangSwitch.vue. - Repo gốc là Apache 2.0 → được phép redistribute, nhớ giữ file
LICENSEvà ghi nguồn.
| Chỉ số | Giá trị | Giới hạn Vercel | |
|---|---|---|---|
| Thời gian build (CN + VI) | 61 s | 45 phút | ✅ |
| Peak RAM (build CN) | 2.93 GB | 8 GB | ✅ |
Tổng file trong dist/ |
1.639 | ~15.000 | ✅ |
Dung lượng dist/ |
93 MB | — | ✅ |
| File lớn nhất | 2.3 MB (feed.json, atom.xml, rss.xml) |
100 MB/file | ✅ |
Kết quả: EXIT=0, dist/index.html (667 trang CN) + dist/vi/index.html (11 trang VI).
Không cần NODE_OPTIONS=--max-old-space-size.
Đo lại khi số trang tăng nhiều:
rm -rf dist && time bash -c "$(python3 -c "import json;print(json.load(open('vercel.json'))['buildCommand'])")"
find dist -type f | wc -l && du -sh dist