30-seconds-of-code 詳細教學
§1 定位
30-seconds-of-code (30soc) 是 Angelos Chalaris 自 2017 年起獨自維護的 curated coding snippets 教學站。三句話說清楚它是什麼、不是什麼:
- 是:每篇「30 秒讀完」的短文 + code block + 解釋,分 JavaScript / CSS / Python / React / Git / HTML 六大類,由單一作者把關品質
- 不是:cheatsheet(沒有解釋)、不是社群 wiki(PR 只收 bug 不收新內容)、不是教材(沒有循序漸進的學習路徑)
- 128k stars / 12.5k forks / CC-BY-4.0 內容授權 — 是「solo-maintainer 高品質知識站」的代表
兩條使用線:
- 使用者線:去 https://30secondsofcode.org/ 找 snippet(搜尋 / 看 collection),用於 daily reference 或 interview prep
- 學習者線:clone repo,研究
content/目錄結構 +bin/preparebuild pipeline +CONTRIBUTING.md寫作 SOP,當「打造個人知識站」的範本
§2 怎麼用:三種使用情境
情境 A:直接用網站找 snippet(最常見)
11. 開 https://30secondsofcode.org/
22. 用 search bar 搜「debounce」/「flexbox center」/「python list comprehension」
33. 點 card 進文章 → 看 explanation + code + 範例
44. 複製 code block,貼到自己專案
55. 若要引用,標註「Source: 30secondsofcode.org by Angelos Chalaris (CC-BY-4.0)」
情境 B:clone repo 在本機翻 snippet
1# 1. 淺 clone(128k stars 但 disk usage 不算大)
2git clone --depth 1 https://github.com/Chalarangelo/30-seconds-of-code.git
3cd 30-seconds-of-code
4
5# 2. 用 ripgrep / grep 找關鍵字(比網站快、可離線)
6rg -i "debounce" content/snippets/js/s/
7rg -l "tags:.*\[.*react.*\]" content/snippets/react/s/
8
9# 3. 看 frontmatter + 內文
10cat content/snippets/js/s/async-function-composition.md
情境 C:本機跑 dev server(學 build pipeline 用)
1# 需要 Node.js >= 22.14.0
2node --version # 確認 >= v22.14.0
3
4# 安裝 deps(package-lock.json ≈ 12k stars 量級,~3-5 分鐘)
5npm install
6
7# Dev server
8npm run dev # astro dev --port 8000,含 bin/prepare 自動跑 content index
9# → 打開 http://localhost:8000
注意:repo 用 CC-BY-4.0(內容)+ MIT(程式),README 明寫「New content contributions are not accepted at this time」—— 你不能上游貢獻新 snippet,只能 fork 來改、或開 issue 報 bug。
§3 架構:內容 → MDX → Astro 靜態站
3.1 目錄分層
graph LR
A["content/ (CC-BY-4.0 內容資產)"] --> A1["snippets/ (各語言短文 MDX)"]
A --> A2["collections/ (主題集合 YAML)"]
A --> A3["components/ (內容專用元件)"]
A --> A4["rankingEngine.yaml (search 排序)"]
B["src/ (MIT 站台程式碼)"] --> B1["lib/contentUtils/ (content 處理工具)"]
B --> B2["astro/ (Astro page + layout)"]
B --> B3["serializers/ (JSON + search index)"]
C["bin/prepare (build CLI)"] --> A
C --> B1
C --> D["dist/ (Astro build 輸出)"]
3.2 內容流水線:MDX → 靜態站
flowchart LR
M["content/snippets/*/s/*.md (MDX frontmatter)"] --> P1["bin/prepare content"]
P1 --> CU["src/lib/contentUtils/ (front-matter + remark-gfm)"]
CU --> S1["MDX → AST"]
S1 --> SH["Shiki 高亮 (grammars.yaml)"]
SH --> S2["AST → HTML"]
S2 --> SER["src/serializers/ (生 JSON + search index)"]
SER --> AS["Astro 5 SSG build"]
AS --> OUT["dist/*.html (Netlify deploy)"]
關鍵節點:
- frontmatter schema:
title / shortTitle / language / tags / cover / excerpt / listed / dateModified—— 業界 snippet site 標準 - Shiki + colorized brackets:code block 高亮 + bracket pairing 視覺化
rankingEngine.yaml:v14 (2025-05) 重寫,定義 search 排序權重recommender:根據當前 snippet 推薦下一篇
3.3 MDX frontmatter 範本
實際 snippet content/snippets/js/s/async-function-composition.md:
1---
2title: Asynchronous function composition in JavaScript
3shortTitle: Async function composition
4language: javascript
5tags: [promises, function]
6cover: new-york-skyline
7excerpt: Learn how to perform function composition for asynchronous functions.
8listed: true
9dateModified: 2024-07-27
10---
八個欄位的設計哲學:
| 欄位 | 用途 | 為什麼重要 |
|---|---|---|
title | SEO + card 標題 | 完整描述、含語言 |
shortTitle | 列表縮排顯示 | 避免長標題斷行 |
language | 路由 + filter | js/css/python/... |
tags | filter + related | array,多標籤 |
cover | card 圖(Unsplash) | 視覺辨識 |
excerpt | card description | ≤140 字 |
listed | 是否上 listing | 可暫時隱藏 |
dateModified | sort + freshness | 不用 published |
§4 Helper scripts:bin/ 三件套
package.json 的 scripts 區塊 + bin/ 三個檔案:
1"scripts": {
2 "dev": "astro dev --port 8000", // 含 predev: bin/prepare dev --fast-highlight
3 "watch": "npm run dev & bin/prepare watch --fast-highlight",
4 "build": "astro build", // 含 prebuild: bin/prepare full
5 "preview": "astro preview --port 9000",
6 "create": "bin/prepare create", // 建立新 snippet
7 "create-component": "bin/prepare create-component",
8 "console": "bin/console", // interactive REPL
9 "test": "vitest"
10}
bin/prepare sub-commands:
1bin/prepare full # 全套 build(assets + content + index)
2bin/prepare dev # dev 模式(只 content + index)
3bin/prepare content # 只跑 content
4bin/prepare watch # watch + rebuild
5bin/prepare assets # 只跑 assets(含 --force 強制)
6bin/prepare create snippet <dir> <name> # 建新 snippet
7bin/prepare create-component <name> # 建新 component
bin/console:interactive REPL,可在 Node REPL 內存取 content models,方便除錯。
bin/deploy:deploy 入口(站台部署在 Netlify)。
§5 應用場景:誰會用、怎麼用
| 場景 | 目標讀者 | 用法 |
|---|---|---|
| Interview 速複習 | 求職者 | search「debounce / throttle / promise.all」直接看實作 + 解釋 |
| Daily reference | 在職工程師 | bookmark 30secondsofcode.org,遇到忘記語法時搜 |
| 教學素材來源 | 大學 / Bootcamp 講師 | CC-BY-4.0 可引用,標註來源即可 |
| 建內部知識站 | 公司技術 team | fork → 換 content → 保留 Astro pipeline = 內部 wiki |
| 學技術寫作 | 內容創作者 | 抄 CONTRIBUTING.md 的 writing guideline 當 SOP |
| 學 SSG pipeline | 前端工程師 | 研究 bin/prepare + src/lib/contentUtils/ |
注意各場景的授權邊界:
- 內容(snippets / articles)→ CC-BY-4.0,可商業引用但需標註來源
- 站台原始碼(src/ + bin/) → MIT,可自由使用
- Logo / Brand / “30 seconds of code” 名稱 → 需作者同意,不可 直接拿來掛自家品牌
§6 資安:低風險內容站 + 標準 Node 依賴鏈
整體評級:🟢 低風險
為什麼:
- 純前端 SSG(Astro),沒有 server 端 runtime,沒有 user input → DB pipeline,沒有 auth
- 內容站 → 唯一外部互動是「使用者瀏覽 + Netlify static hosting」
- License 清楚(CC-BY-4.0 / MIT)
仍要注意:
- devDependencies 33 個套件:astro、shiki、sass、sharp、prismjs、glob、vitest 等;近期 commits 大量 dependabot 升版(vite, defu, flatted, minimatch)—— 表示 supply chain 風險被持續處理
sharp套件:原生 binding,曾有 CVE(如 CVE-2024-21516)。Fork 前先npm auditprismjs:歷史上有過 ReDoS CVE;本 repo 用的 1.30+ 已修正- Node.js >= 22.14.0 要求:較新版本,避免老 Node 的潛在問題
建議掃描指令(若你 fork):
1npm audit # 標準 audit
2npm audit fix # 自動修
3npx better-npm-audit audit # 更嚴格的版本
4osv-scanner --recursive . # OSV 全 ecosystem 掃描(Google)
機密邊界:repo 本身不含任何 secret / API key(檢視過 .env* 不存在)。
§7 FAQ
Q1:我可以投稿新 snippet 嗎? 不行。README 明寫「New content contributions are not accepted at this time」。你只能 fork、或開 issue 報 bug / 建議改進。
Q2:CC-BY-4.0 內容可以放進我公司的內部教材嗎? 可以,但要標註來源(作者 + 原網址 + 授權)。商業使用 OK,內部使用更 OK。
Q3:可以把整套 fork 改成 公司wiki 嗎? 程式碼(MIT)可以;內容(CC-BY-4.0)可以;但不能用 30soc 的 logo / 名稱 / brand——必須換成你公司的。
Q4:search engine 怎麼運作?
v14 (2025-05) 完全重寫,定義在 content/rankingEngine.yaml。客戶端載入 index JSON,前端做 ranking。沒有 server-side search。
Q5:內容是 MDX 還是 Markdown?
Markdown + frontmatter,再加 content/components/ 提供的內容專用 component(callout / table / 等)。不是純 MDX,比較像「Markdown 帶 component 注入」。
Q6:為什麼用 Astro 而不是 Next.js? v14 release notes 沒寫換框架理由,但合理推測:純內容站不需 React runtime,Astro 的 zero-JS-by-default + island architecture 對 SSG 更適合。
Q7:repo size 多大?網路慢能 clone 嗎?
完整 clone ≈ 100MB 量級(含 logo / cover images)。建議 git clone --depth 1 把 history 排除,下載量降到 ~20MB。
Q8:可不可以用 Docker 跑?
官方沒提供 Dockerfile,但很容易自寫(node:22-alpine + npm install + npm run build + npx serve dist/)。
§8 進階:貢獻、品質標準、taxonomy
8.1 即使不收新內容,仍可貢獻的部分
- 修錯字 / 改 typo / 修 broken link:開 PR
- 報 search bug / accessibility bug:開 issue
- 建議新 feature:開 issue(接受度低,但作者會看)
8.2 CONTRIBUTING.md 的 writing guideline(精華)
抄錄重點,這份可直接拿來當你自己技術寫作的 SOP:
1Language(語言)
2- Use American spelling
3- Write short sentences (≤20 words)
4- Single focus per sentence
5- Edit unnecessary or repeated words
6- Avoid idioms and indirect / ironic meanings
7- Avoid jargon
8- Aim for Grade 10 reading level
9- Use contractions (but don't overdo)
這些原則同樣適用於:你寫 README、寫 release notes、寫團隊內部文件、寫 inbox/ md。
8.3 Snippet quality rubric(從 CONTRIBUTING.md + 既有 snippets 觀察)
| 維度 | 好範例 | 壞範例 |
|---|---|---|
| 長度 | 30 秒讀完(300-600 字) | 像 textbook chapter |
| focus | 單一概念 / 函式 | 一篇講三個 unrelated 主題 |
| code | 最簡 working example | 含 production-only 細節 |
| 解釋 | 「為什麼這樣寫」 | 「這段 code 做了 X / Y / Z」(讀者用眼睛就看得到) |
| tag | 2-4 個精準 tag | 10 個 tag、或 1 個太寬的 tag |
| dateModified | 每次有實質改動就更新 | 永遠停在初版日期 |
8.4 Taxonomy(分類體系)
1language(必填):javascript / css / python / react / git / html
2tags(必填):array of free-form labels
3collections(衍生):根據 tag 自動或手動歸類到 collection YAML
4cover(必填):Unsplash collection 9387655 內的圖片名稱
collections/ 內的 YAML 是「策展層」:定義哪些 tag / language 組合形成一個主題集合(例:webdev.yaml = JS + CSS + HTML 的精華)。
§9 整合:與本知識庫的串接
9.1 與 paper-tutorial(Layer 15)
paper-tutorial 的目標是「N 篇 paper → 整合 HTML 教學」;30soc 是同樣思路在程式碼內容上的成熟案例:
- 兩者都採「source 分離 / build pipeline 統一」
- 30soc 的
bin/prepare結構可參考、移植到paper-tutorial的 build chain(MDX → JSON → HTML)
9.2 與 kami slides(Layer 11)
把單篇 snippet 變成 slide 投影片:
1# 1. 挑一篇 snippet
2cat /tmp/30soc/content/snippets/js/s/async-function-composition.md
3
4# 2. 改成 slide 結構(每張投影片 = 一個概念)
5# 3. 用 kami slides-weasy 或 quarkdown slides 渲染
6bash scripts/kami.sh build my-slide.html
7# 或
8bash scripts/quarkdown.sh compile my-slide.qd --out-subdir slides
把 snippet collection(如 react/)的 10 篇打包,就是一份 React Hooks 教學投影片。
9.3 與 quarkdown(Layer 7)
snippet 本身就是 markdown,可直接走 qd from: 路徑做專業排版輸出:
1bash scripts/quarkdown.sh convert \
2 /tmp/30soc/content/snippets/js/s/async-function-composition.md \
3 --topic js-async-composition --preset report
9.4 與 paper-qa-lite(Layer 10)
把 content/snippets/ 整個目錄 index 進 pq cache,做「程式碼問答 RAG」:
1pq: 「如何寫 debounce」 /tmp/30soc/content/snippets/js/s/
注意:CC-BY-4.0 內容你拿來私下做 RAG 沒問題;如果產出要對外,需標註來源。
9.5 與 ai-gh-save(Layer 2)
本份報告本身就是 ai-gh-save + gh-tutorial-qd 的產物。模式可複用:
- 看到 high-stars 內容站 →
gh: <url>存 metadata - 想深入研究 →
gh-tutorial-qd: <url>做完整 tutorial - 想引用內容 → 看授權,CC-BY 系列大多 OK
§10 重點摘要
- 30soc 是 solo-maintainer 高品質知識站的範本:128k stars / 8 年 / 單一作者 / 內容資產與程式碼授權分離(CC-BY-4.0 / MIT)
- 三層學習價值:(a) 內容本身(拿來查 / 引用)、(b)
bin/prepare+ Astro pipeline(拿來抄 build chain)、(c)CONTRIBUTING.mdwriting guideline(拿來當寫作 SOP) - 使用三線:網站直接搜 / clone 後 grep / 本機跑 dev server
- 架構核心:
content/snippets/<lang>/s/*.md(MDX frontmatter) →bin/prepare→src/lib/contentUtils/→ Astro SSG → static HTML + JSON search index - 不收新內容:PR 只收 bug fix,想貢獻新 snippet 請建自己的 fork / 自己的站
- 資安 🟢 低風險:純前端 SSG,主要依賴升版由 dependabot 自動維護
- 與本知識庫的最強串接點:作為「solo knowledge site」的 reference,給未來想做內部 wiki / 個人 blog 的 builder 參考
- MDX frontmatter schema 直接可抄:
title / shortTitle / language / tags / cover / excerpt / listed / dateModified八欄是業界標準 - writing SOP 直接可抄:American spelling / ≤20 字句 / single focus / Grade 10 / 避免 jargon
- Taxonomy 是兩層:MDX frontmatter(language + tags)→ collections YAML(策展層) — 是好設計
§11 進一步閱讀
- 官方網站:https://30secondsofcode.org/
- GitHub repo:https://github.com/Chalarangelo/30-seconds-of-code
- v14.0.0 release notes:https://github.com/Chalarangelo/30-seconds-of-code/releases/tag/v14.0.0
- CONTRIBUTING.md(寫作 guideline):https://github.com/Chalarangelo/30-seconds-of-code/blob/master/CONTRIBUTING.md
- 作者 Twitter / 個人站:透過 GitHub @Chalarangelo profile 連到
- Astro 框架文件:https://docs.astro.build/
- Shiki 語法高亮:https://shiki.style/
- CC-BY-4.0 授權說明:https://creativecommons.org/licenses/by/4.0/
- 相關 awesome lists:搜尋「awesome javascript snippets」「awesome css tricks」可找到類似站
本份教學由 gh-tutorial-qd workflow 自動生成,內容根據 2026-05-22 的 repo 快照與作者公開資訊整理;snippet 範例引用自
content/snippets/js/s/async-function-composition.md(CC-BY-4.0 by Angelos Chalaris)。
Comments