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/prepare build 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 schematitle / 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---

八個欄位的設計哲學:

欄位用途為什麼重要
titleSEO + card 標題完整描述、含語言
shortTitle列表縮排顯示避免長標題斷行
language路由 + filterjs/css/python/...
tagsfilter + relatedarray,多標籤
covercard 圖(Unsplash)視覺辨識
excerptcard description≤140 字
listed是否上 listing可暫時隱藏
dateModifiedsort + freshness不用 published

§4 Helper scripts:bin/ 三件套

package.jsonscripts 區塊 + 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 可引用,標註來源即可
建內部知識站公司技術 teamfork → 換 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 audit
  • prismjs:歷史上有過 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」(讀者用眼睛就看得到)
tag2-4 個精準 tag10 個 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 重點摘要

  1. 30soc 是 solo-maintainer 高品質知識站的範本:128k stars / 8 年 / 單一作者 / 內容資產與程式碼授權分離(CC-BY-4.0 / MIT)
  2. 三層學習價值:(a) 內容本身(拿來查 / 引用)、(b) bin/prepare + Astro pipeline(拿來抄 build chain)、(c) CONTRIBUTING.md writing guideline(拿來當寫作 SOP)
  3. 使用三線:網站直接搜 / clone 後 grep / 本機跑 dev server
  4. 架構核心content/snippets/<lang>/s/*.md (MDX frontmatter) → bin/preparesrc/lib/contentUtils/ → Astro SSG → static HTML + JSON search index
  5. 不收新內容:PR 只收 bug fix,想貢獻新 snippet 請建自己的 fork / 自己的站
  6. 資安 🟢 低風險:純前端 SSG,主要依賴升版由 dependabot 自動維護
  7. 與本知識庫的最強串接點:作為「solo knowledge site」的 reference,給未來想做內部 wiki / 個人 blog 的 builder 參考
  8. MDX frontmatter schema 直接可抄title / shortTitle / language / tags / cover / excerpt / listed / dateModified 八欄是業界標準
  9. writing SOP 直接可抄:American spelling / ≤20 字句 / single focus / Grade 10 / 避免 jargon
  10. 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)。