Skip to content
On this page

Feb. 2023

1 st

Vitepress docsearch

  • 使用 algolia 新增搜尋功能
    Details
    1. 註冊 algolia
    2. 在 algolia 創建 index 並獲取
      Application IDSearch-Only API KeyAdmin API Key
    3. 修改 docs/.vitepress/config.ts
    ts
    defineConfig({
      themeConfig: {
        ...
      },
      algolia: {
        appId: '', // 填入 Application ID
        apiKey: '', // 填入 Search-Only API Key
        indexName: '' // 填入剛剛創建的 index 名稱
      },
    })
    1. 修改 Github Secrets
      Your Repo -> Settings -> Security / Secrets and variables / Actions
      新增兩個 repository secret
    • API_KEY:填入 Admin API Key
    • APPLICATION_ID:填入 Application ID
    1. 在專案的根目錄下創建 crawlerConfig.json
      這是告訴 algolia 需要爬取的配置
    json
    {
      "index_name": "...", // 填入 index 名稱
      "start_urls": ["..."], // 填入專案網址
      "rateLimit": 8,
      "maxDepth": 10,
      "selectors": {
        "lvl0": {
          "selector": "",
          "defaultValue": "Documentation"
        },
        "lvl1": ".content h1",
        "lvl2": ".content h2",
        "lvl3": ".content h3",
        "lvl4": ".content h4",
        "lvl5": ".content h5",
        "content": ".content p, .content li"
      },
      "selectors_exclude": [
        "aside",
        ".page-footer",
        ".next-and-prev-link",
        ".table-of-contents"
      ],
      "js_render": true
    }
    1. .github/workflows 目錄下,建立 algolia.yml 檔案(名稱可自行更改)
    yaml
    name: algolia
    on:
      push:
        branches:
          - main # 若主分支為 master 記得更改
    jobs:
      algolia:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: Get the content of algolia.json as config
            id: algolia_config
            run: echo "config=$(cat crawlerConfig.json | jq -r tostring)" >> $GITHUB_OUTPUT
          - name: Push indices to Algolia
            uses: signcl/docsearch-scraper-action@master
            env:
              APPLICATION_ID: ${{ secrets.APPLICATION_ID }}
              API_KEY: ${{ secrets.API_KEY }}
              CONFIG: ${{ steps.algolia_config.outputs.config }}

    這裡是使用 Github Actions 在 Docker 中執行的 AlgoliaDocSearch scraper action,當我們推送到 main 分支時就會立即執行這個任務。

    ⋯ Reference
    ⋯ 補充 2023/04/14

2 nd

VueUse

  • useWindowScroll

    響應式的 window scroll。

    ts
    const { x, y } = useWindowScroll()

問題

  • refcomputedwatch 只能在 setup 使用
  • computed 裡面不能有副作用
  • watch 的對象只能是 refgetter(內部要取用到響應式資料)

學習資源

  • 前端森林

    整理了前端知識網頁、期刊、工具等網站。

  • Learn Git Branching

    互動式的 git 視覺化和教學,可利用此應用程式來學習和挑戰掌握 git。

4 th

工具

後端框架

  • Koa.js

    • HTTP 服務(處理 HTTP Request、HTTP Response)
    • 中間件容器(中間件的載入、執行)

    基本設置

    1. 安裝 Koa.js
    pnpm install koa -D

    -D

    將下載的套件歸類在 package.jsondevDependencies

    1. 加入路由設定
    pnpm install koa-router -D
    1. 加入 koa-body
    pnpm install koa-body -D
    1. 新增 CORS
    pnpm install @koa/cors -D
  • 新增並設置 server.js 檔案

HTTP

CodeContent意義
200OK請求成功
201Created請求成功且有一個新的資源已經依據需要而被建立
204No Content請求成功,但客戶端不需要更新目前的頁面
400Bad Request被認為是客戶端錯誤,服務器不能或不會處理請求
401Unauthorized客戶端請求尚未完成,因為缺少所請求資源的有效身份驗證憑據
404Not Found服務器找不到請求的資源

6 th

HTTP

  • CORS Cross-Origin Resource Sharing,跨來源資源共用。

    瀏覽器在發送請求之前會先發送 preflight request (預檢請求),確認伺服器端設定正確的 Access-Control-Allow-MethodsAccess-Control-Allow-HeadersAccess-Control-Allow-Origin 等 header,才會實際發送請求。
    使用 cookie 的情況下還需額外設定 Access-Control-Allow-Credentials header。
    針對不同源的請求而定的規範,透過 JavaScript 存取非同源資源時,server 必須明確告知瀏覽器允許何種請求,只有 server 允許的請求能夠被瀏覽器實際發送,否則會失敗。

    同源的條件

    1. 相同的通訊協定 (protocol),即 http / https
    2. 相同的網域 (domain)
    3. 相同的通訊埠 (port)

    ⋯ Reference

後端框架

  • Express.js

    Express 是 Node.js 環境下提供的一個輕量後端框架,自由度極高,透過豐富的 HTTP 工具,能幫助快速開發後端應用程式。
    ⋯ Reference

7 th

套件

  • FormKit

    免費開源的 Vue 表單構建框架,可簡化表單結構、生成、驗證、主題、提交、錯誤處理等。

JS

  • Compose

    從右到左參數執行。

    js
    (fa, fb, fc) => x => fa(fb(fc(x)))

    可以填入多個參數。

    js
    const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x)
  • Pipe

    從左到右參數執行。

    js
    (fa, fb, fc) => x => fc(fb(fa(x)))

    可以填入多個參數。

    js
    const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x)

⋯ Reference

8 th

JS 事件循環

  • 執行順序

    同步任務 —> 異步任務 微任務(microtask) —> 異步任務 宏任務(macrotask)

  • 同步任務

    主執行緒上排隊執行的任務,只有前一個任務執行完畢,才能繼續執行下一個任務。
    包括:new promise()console.log()

  • 異步任務

    不進入主執行緒、而進入「任務佇列」的任務。
    只有等主執行緒任務全部執行完畢,「任務佇列」的任務才會進入主執行緒執行。
    分成微任務(microtask)和宏任務(macrotask)。

    微任務(microtask)

    • 發起者

      JS 引擎

    • 具體事件:
      1. Promise
      2. MutationObserver
      3. Object.observe(已廢棄,Proxy 物件替代)
      4. process.nextTick(Node.js)

    宏任務(macrotask)

    • 發起者

      宿主(Node、瀏覽器)

    • 具體事件:
      1. script (可以理解為外層同步程式碼)
      2. setTimeout / setInterval
      3. UI rendering / UI 事件
      4. postMessage, MessageChannel
      5. setImmediate, I/O(Node.js)

⋯ Reference

瀏覽器

  • 瀏覽器多執行緒

    1. JS 引擎執行緒

    用於解釋執行 JS 程式碼、使用者輸入、網路請求等。

    2. GUI 渲染執行緒

    繪製使用者介面,與 JS 主執行緒互斥。
    (因為 JS 可以操作 DOM,進而會影響到 GUI 的渲染結果)

    3. http 非同步網路請求執行緒

    處理使用者的 GET、POST 等請求,等回傳結果後將 callback function 推入到任務佇列。

    4. 定時觸發器執行緒

    setInterval、setTimeout 等待時間結束後,會把執行函式推入任務佇列中。

    5. 瀏覽器事件處理執行緒

    在 click、mouse 等 UI 互動事件發生後,將要執行的 callback function 放入到事件佇列中。

⋯ Reference

15 th

工具

學習資源

JS

  • process.nextTick()

    是 Node 的一個定時器,讓任務可以在指定的時間運行。
    其中 Node 一共提供了 4 個定時器,它們分別是 setTimeout()setInterval()setImmediate()process.nextTick()
    它是在本輪循環執行的,而且是所有異步任務裏面最快執行的。
    Node 執行完所有同步任務,接下來就會執行 process.nextTick 的任務隊列。

    微任務隊列追加在 process.nextTick 隊列的後面,也屬於本輪循環。
    所以,下面的程式碼總是先輸出 nextTick,再輸出 .then
    以下全部 process.nextTick 的回調函式,執行都會早於 Promise 的。

    js
    process.nextTick(() => console.log(1))
    Promise.resolve().then(() => console.log(2))
    process.nextTick(() => console.log(3))
    Promise.resolve().then(() => console.log(4))
    
    // 1 3 2 4

17 th

CSS 函式庫

  • Stylify

    輕量級的 CSS 函式庫,可以根據所寫的 HTML 動態產生實用且優先的 CSS。
    預設使用本地的 CSS 屬性值作為選擇器,可以匹配多個瀏覽器的 CSS 屬性。
    可以為每個檔案、元件、頁面或佈局單獨產生 CSS。

指令

  • Curl

    在 Linux 上用來透過 HTTP Protocol(HTTP HyperText Transfer Protocol 定義存取網路資源的協定,讓我們可以使用 client / server 模式來取得網路資源)下載和上傳檔案的指令。
    ⋯ Reference

Vue

  • nextTick()

    獲取更新後的 DOM 的 Vue Function。
    放在 Vue.nextTick() 中的 callback function 執行的應該是會對 DOM 進行操作的 JS 程式碼。
    是將 callback function 延遲在下一次 DOM 更新資料後呼叫:當資料更新了,在 DOM 中渲染後,自動執行該 function。

    ⋯ Reference

18 th

架構概念

  • Single-repo Monolith

    所有的功能或 dependencies 都統一放在同一個 repo 底下。

    優點

    1. 開發初期或非大型規模專案,是個簡單方便的好方法。

    缺點

    1. 當 repo 越來越大,會導致打包和部署時間過長、效率差。
    2. 相依管理 (dependency management) 困難、難以擴充、缺乏彈性。
  • Multi-repo

    將個別功能放在不同 repo 底下,擁有各自獨立的 repo,同時也能擁有各自的環境和工具的設定檔與技術線。

    優點

    1. 專案體積小、高效率開發、技術線獨立、相依管理簡單、高彈性,因此權責切分乾淨、不同框架時更顯優點。

    缺點

    1. 不易共享,像是環境與設定檔重複配置 (CI/CD、webpack、test suite 等)、資源難以共用。
    2. 當資源更新時,個別 repo 難以被通知而及時更新。
    3. 修 bug 或是 i18n 字串更新時若涉及多個 repo,處理與測試的困難度也會變高。
    4. 建構、測試與發佈流程上甚至是 rollback 都較困難。
  • Monorepo

    將個別功能放在同一 repo 的不同 package 底下。

    優點

    1. 能共享資源,在同框架時更顯優勢。
    2. 當資源更新時,個別 app 能夠及時被通知而更新。
    3. 能共享配置,像是共享環境設定和 config 檔,不需每個 app 再自建一套。這在建構、測試與發佈流程上甚至是 rollback 是很方便的。

    缺點

    1. 跟 Monolith 同樣有 repo 龐大的問題,這在 codebase 很大的狀況下很可能造成 Git 效能差、SourceTree 當掉。
    2. 是否共用要切分清楚,由於太過容易共用,在開發上需要制定明確規範。
    3. 難以控管檔案權限,無法針對 package 來限制能瀏覽或編輯的人員,同時也會反應到開 issue、回覆 PR 和通知過於紊亂的問題上。

⋯ Reference

20 th

TypeScript 驗證庫

  • Zod

    用於型別宣告和驗證的開源 TypeScript 庫。

    1. 具有零依賴性,可以在沒有任何其他庫的情況下安裝和使用 Zod,維持更小的包。
    2. 適用於 Node.js 和所有主流瀏覽器(包括 IE 11)。
    3. TypeScript 優先,該驗證庫將自動為資料結構推斷靜態 TypeScript 類型。
      消除了兩次聲明類型的需要(一次在 Zod 中,一次在 TypeScript 中)。
      節省大量輸入,並幫助您保持程式碼更改同步。
    4. API 簡潔且可連結,這使得建立複雜的資料類型變得容易。

CSS

21 st

網頁資料儲存

  • Cookie

    小型的文字檔,特性是當送出 request 時會自動把 cookie 帶到 server 端,而 server 端也可以把資料寫到 response 的 header 中 set-cookie,傳到 client 端。
    限制大小為 4k 以下,且不同的 domain 會有不同的 cookie,一個 domain 只能儲存 20 個 cookie。

    主要功用為辨識身份(e.g. 廣告追蹤、身份驗證、購物車...)。
    由於限制容量小並且大量的資料透過 Cookie 傳輸會影響效能。

    常見的做法是在 cookie 存放「能代表使用者的 ID」,類似通行證一樣,而 Server 端則是儲存此 ID 的資料,當從 client 端發出 request 時,server 端就會回傳這個 ID 相對應的資料,就能辨認身份。

  • Web Storage

    類似 Object 的格式,key 對應 value 的方式儲存資料。
    value 只能是字串,因此如果想要儲存 JSON 的資料,可以使用 JSON.stringify() 存入並用 JSON.parse() 取資料。

    • Local Storage
      能跨分頁的儲存資料,關閉頁面資料也不會消失。(沒有過期時間)
    • Session Storage
      不能跨分頁的儲存資料,關閉頁面資料會消失。

⋯ Reference

22 nd

JS 執行過程

名稱簡寫全名
執行上下文棧ECSExecution Context Stack
執行上下文ECExecution Context
全域性變數GOGlobal Context
活動物件AOActivation Object
變數物件VOVariable Object
全域性上下文GECGlobal Execution Context
函式呼叫棧Call Stack
垃圾回收GCGarbage Collection
詞法環境Lexical Environment
變數環境Variable Environment
變數記錄Environment Record
作用域鏈Scope Chain
  1. 瀏覽器會在電腦記憶體中分配一塊記憶體,專門用來供程式碼執行的 Stack,稱作 ECStack 。
  2. 同時會建立一個 GO,將內建的屬性方法(isNaNsetIntervalsetTimeout ...等等)存放到一塊單獨的 Heap 空間,並且使用 window 指向 GO。
  3. 在執行程式碼前,還需要建立一個 GEC,建立完成後,進入到 Stack 中去執行(進棧)。
  4. 在當前 GEC 中,因為會建立很多變數並且賦值,所以會建立一個 VO 來進行儲存。
  5. 在函式私有上下文中的 VO 叫做 AO,每個 EC 都有一個單獨的 VO。

⋯ Reference⋯ Reference

24 th

HTML

  • 瀏覽器渲染流程

    1. 建立 DOM 樹

    用 HTML 分析器分析 HTML 元素,構建一顆 DOM 樹(標記化和樹構建)。

    2. 建立 StyleRules

    用 CSS 分析器分析 CSS 檔案和元素上的 inline 樣式,生成頁面的樣式表。

    3. 建立 Render 樹

    將 DOM 樹和樣式表,關聯起來,構建一顆 Render 樹(Attachment)。
    每個 DOM 節點都有 attach 方法,接受樣式資訊,回傳一個 Render 物件(Renderer)。
    這些 Render 物件最終會被構建成一顆 Render 樹。

    4. 佈局 Layout(重排)

    瀏覽器開始佈局,為每個 Render 樹上的節點確定在顯示螢幕上出現的精確座標。

    5. 繪製 Painting(重繪)

    Render 樹和節點顯示座標都有了,就呼叫每個節點 paint method,把它們繪製出來。

    DOM 樹

    DOM(Document Object Model)文件物件模型:瀏覽器將 HTML 解析成樹狀的資料結構。
    它是 HTML 文件的物件表示,同時也是外部內容(例如:JavaScript)與 HTML 元素之間的介面。
    解析樹的根節點是 Document 物件。

    ⋯ Reference

25 th

VueUse

  • until

    一次性的觀察變化(Promise)。

    ts
    await until(ref).toBe(true)
    await until(ref).toMatch(v => v > 10 && v < 100)
    await until(ref).changed()
    await until(ref).changedTimes(10)
    await until(ref).toBeTruthy()
    await until(ref).toBeNull()
    
    await until(ref).not.toBeNull()
    await until(ref).not.toBeTruthy()

Vue

  • watch / watchEffect
    • immediate:在偵聽器建立時立即觸發 callback。
    • deep:深度遍歷,以便在深層級變更時觸發 callback。
    • flush:callback function 的觸發時機。pre:DOM 更新前呼叫(Default)。
      post: DOM 更新後呼叫。
      sync:同步呼叫。
    • onTrack / onTrigger:用於偵錯的鉤子,在依賴收集和 callback function 觸發時被呼叫。

    ⋯ Reference

26 th

CI / CD

程式的流程自動化,自動 build code、執行 unit test、自動更新線上服務...... 等等所有反覆步驟都轉為自動化執行。

  • CI(Continuous integration)持續整合

    1. 程式建置

    每一次的 Commit & Push 後,都能夠於統一的環境自動 Build 程式,透過此一步驟可以避免每個開發人員因本機的環境或套件版本不相同,進而造成 Service 異常。

    2. 程式測試

    當程式編譯完成後,將會透過 unit test 測試新寫的功能是否正確,或者確認是否有影響到現有功能,透過該步驟進行測試,可以避免掉開發人員遺忘於本機先行檢查,作為「雙重驗證」功用。

    目的

    1. 減少手動的反覆步驟,同時降低人為疏失
    2. 進行版控管制
    3. 增加系統一致性與透明化
    4. 減少團隊 Loading
  • CD(Continuous Deployment)持續佈署

    1. 部署服務

    透過自動化方式,將寫好的程式碼更新到機器上並公開對外服務,另外需要確保套件版本&資料庫資料完整性,也會透過監控系統進行服務存活檢查,若服務異常時會即時發送通知告至開發人員。

    目的

    1. 保持每次更新程式都可順暢完成
    2. 確保服務存活

⋯ Reference

DevOps

Development(開發)+ Operations(營運)

  • 生命週期

    1. Plan

    在規劃階段中,DevOps 團隊會定義目前正在開發的程式與系統功能。
    分門別類追蹤進度,達到敏捷性開發,例如:建立代辦項目、儀表板呈現開發進度、使用工作流程看板等等。

    2. Develop

    開發過程中許多重複性或一般的步驟可以藉由自動化提升效率,透過自動化測試也能縮短開發週期。

    3. Deliver

    傳遞過程指的是將應用程式部署至生產環境的程序,包括環境的基礎結構設定與組成。
    利用自動化閘道將移動應用程式的程序自動化,讓其變得易於調整、重複和控制,藉由一致、可靠的傳遞方式實踐 DevOps 的精神。

    4. Operate

    作業階段包含在生產環境中維護及監視應用程式,並即時進行疑難排解。
    DevOps 團隊利用即時的遙測與警示發布機制,需迅速發現問題、速解決問題,確保應用程式的高可用性。

⋯ Reference