沒穿方服

首頁

隨著 next-on-pages 停止維護,附送網址 feeders.pages.dev 也中死的宣告,還是趕快買個網域給它吧。

Feeders 首頁擷圖

仍然使用 feeders 這個名字

其實「feeders」本來只想暫用,等真的要買網域再亮底牌。 但後來想想原計畫的名字表態明顯,就是反餵食直接批判, 而在快一年營運之下,餵食地圖的用量幾乎是 0,反而「事實」頁面比較有人看,跟原本想像已經不一樣了。 如果無法燃起反餵食的火力,那還是繼續用比較中性的 feeders 好了。

候選域名們

最有公信力的 .com .org 都搶不到了,.tw 一年要 800 有點貴(台幣),屈於現實的考量這些就先算了。

有些新興域名定價在 310 像 .foo .boo 也還可以,但太隨便。

帶點惡意的 .icu 其實不錯(餵食癖.加護病房,你在餵.我在看),還有 .rip 也類似而稍貴一點,但這樣就辜負前述 feeders 的立意良善了。

.dog 很適合,但很貴要 1343,不愧是特權物種,我反對。

最後考慮 feeders.ccfeeders.fyi

.cc 在台灣有 PTT 和 KKTIX、Wretch 等用過,有點知名度,好記又好打,硬要說的話我的名字也曾被略為 CC。

最後基於尊重語意的理念,拒絕 cc,選了 fyi,這個域名本來就是設計給 For Your Information 用途的,還算貼切。

Telescope 官方 README 建議不要追 master 版本,我也真的踩過雷,所以一直停在 0.1.8,18 個月前的東西了。

前幾天終於釋出 0.1.9,變動列出來很長:
Release v0.1.9 · nvim-telescope/telescope.nvim (我也貢獻了一個 PR)
光看標記為 feat 的就要花些時間了,本篇選幾個列出來。

新增 actions.select_tab_drop

選擇檔案後要怎麼開啟,身為分頁使用者當然是用 tab drop 啊。

這個 2022 年就實作的東西一直沒有釋出,我用自己寫的 function 代用很久,終於能換掉了。

除了一些檔案類 picker 能直接設定 mappings 例如 ['<CR>'] = 'select_tab_drop' 這樣,在一些 LSP picker 也能用 jump_type = 'tab drop' 達到相當效果(#2218#2751)。

顯示 * 表示正在搜尋

就是搜尋框後面會多一個顯示,跑完就會消失 (#2637)。

新增 actions.delete_buffer

給 buffers picker 用的,預設按鍵是 <M-d>。 (#3145

新事件 TelescopeResumePost

原來 telescope 有幾個自訂 User 事件 (autocmd),doc 沒寫,只有 README 有提到。
但應該是 plugin 開發者比較有機會用到。 (#2433

插入 <cWORD><cfile>

以前在 picker 輸入框裡想用 <C-R><C-W>(貼上游標文字)或 <C-R>%(目前檔案路徑)會發現貼不出東西,現在特別加了幾個預設 mapping 來做這些事。 (#3134 等)

新增「bcommits_range」 picker

以前雖然有 bcommits picker 可以列出目前檔案的歷史,但沒辦法針對「特定幾行」或「目前這一行」比較精準地追溯,現在新增 bcommits_range 滿足你的願望,#2398

不過預設動作只有 checkout 或者打開 diff,我的習慣還是用 vim-gitdiffall 這老東西:

※這個範例用到我自己寫的 vim function,所以不能真的拿來用,僅供參考
gitdiff = function(bufnr)
  -- Refer to builtin: actions.git_checkout_current_buffer
  local cwd = action_state.get_current_picker(bufnr).cwd
  local selection = action_state.get_selected_entry()
  actions.close(bufnr)

  local fugitive_path = vim.fn.FugitivePath(selection.current_file)
  local display_name = vim.fn.fnamemodify(fugitive_path, ':.')
  local command = string.format("tabnew %s | silent GitDiff @%s", display_name, selection.value)
  vim.cmd(command)
end,

gitdiffall = function(bufnr)
  local cwd = action_state.get_current_picker(bufnr).cwd
  local selection = action_state.get_selected_entry()
  actions.close(bufnr)

  local toplevel = vim.fn.eval("fugitive#repo().tree()")
  vim.fn.TmuxNewWindow({
    text = "gitdiffall @" .. selection.value,
    title = '⎇',
    directory = toplevel
  })
end,
next-on-pages README 上的告知

Cloudflare 九月底把 next-on-pages 專案封存,issue 全關,npm package 棄用,不再維護了,建議大家改用 OpenNext 的 Cloudflare adapter

太無情了吧,哪有這樣說換就換的…… 只能搬家了。

轉換提要

原本 next-on-pages 是把 Next.js 的產出轉換成可以在 Cloudflare Pages 平台上跑的東西,改用 @opennextjs/cloudflare 的話,主要就是改成轉給 Cloudflare Workers 而已。

文件參考:

基本開發環境不變

因為開發時仍然是用 Next.js 自己的 next dev,所以受 pages 或 workers 影響較小。

程式變更

  • 不再使用 edge runtime

    現在反而是只支援 node.js runtime,還不支援 edge,幸好 edge 是比較弱的,問題相對少。

    我是單純移除所有的 export const runtime = 'edge'; 即可。

  • 套件當然要換掉

    安裝 @opennextjs/cloudflare@latest 取代 @cloudflare/next-on-pageseslint-plugin-next-on-pages(相關的東西也都刪掉)。

  • 取得開發環境的 Cloudflare binding 資源

    開發時必須取得 local 的 CF 資源(D1 資料庫、R2 儲存空間等),在 next.config.mjs 裡面,以前是用:

    import { setupDevPlatform } from '@cloudflare/next-on-pages/next-dev';
    要改成:
    import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";

  • DB 要在每個請求中動態取得

    參考 Db - OpenNext。 有些 ORM 會受影響,像我是用 drizzle-orm,以前可以直接設一個 global db,現在要改成 getDb(),幸好改起來還算單純。

設定檔變更: .open-next.config.ts

第一次跑 opennextjs-cloudflare build 會建立這個設定檔,內容如下:

// default open-next.config.ts file created by @opennextjs/cloudflare
import { defineCloudflareConfig } from "@opennextjs/cloudflare/config";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";

export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
});

那個 r2IncrementalCache 是 Next.js 快取會用到的,參考文件,視情況可能還有 DO和 D1 的 binding 會跑出來?

設定檔變更: wrangler.jsonc

原本的 "pages_build_output_dir": "./dist" 要拿掉,然後我增加的部分如下:

"main": ".open-next/worker.js",
"assets": {
  "directory": ".open-next/assets",
  "binding": "ASSETS"
},
"r2_buckets": [
  {
    "binding": "(原本在用的 binding 名,這桶是原本就有的)",
    "bucket_name": "(原本在用的 bucket 名,原本就有)"
  },
  {
    "binding": "NEXT_INC_CACHE_R2_BUCKET",
    "bucket_name": "feeders-next-inc-cache(自己命名,這個只是舉例)"
  }
],
"preview_urls": true,
"observability": {
  "enabled": true,
  "head_sampling_rate": 1
},
"workers_dev": true,

其中 mainassets 是必要的。

NEXT_INC_CACHE_R2_BUCKET 是跟前述 build 出來的 .open-next.config.ts 對應,這個 bucket 要另外手動開出來。

build、預覽和部署

以前用 pnpm next-on-pages --outdir=dist build 到 dist 目錄, 現在換成 pnpm opennextjs-cloudflare build,會 build 到 .open-next 目錄,可以觀察一下生成的檔案內容。

原本用 wrangler pages 開頭的指令都要換掉,改成例如 wrangler deploy 等。

Production 的環境變數

以前我是將 production 的環境變數通通當成 secret 上傳到 Cloudflare,不然要維護本地的 .dev.vars、Next.js 的 .env.*、寫在 wrangler config 中的變數、…… 等等有點麻煩。

現在雖然建議管理方式仍是在 CF 後台設定變數或 secret, 但我發現 opennextjs build 會直接把所有環境的 .env.* 都包進去: opennextjs-cloudflare/packages/cloudflare/src/cli/build/open-next/compile-env-files.ts#L4

所以除非 build 的時候有隔離這些 .env 檔案,不然其實 worker 是吃得到變數的。 實測確實如此,且這些變數在 CF 後台也看不見。

參考文件: Env Vars - OpenNext

網址 xxx.pages.dev 沒了

沒救,可憐,現在附送的網址是 xxx.workers.dev,還是買個自己的網域吧。

實際 commits

這次轉換的是 feeders 專案,相關 commit 可以看: Commits 10/2 ~ 10/5 · bootleq/feeders

示例(影片有聲音)

Noise 4.2.0 新功能「Multiple Sounds」

可以在事件上綁定「多個」聲音,可選擇是否隨機播放。

安裝 Noise:

註:套件裡面「沒有提供」影片中的聲音檔,要自己去生喔。

法規頁 擷圖

Feeders 法規頁,這是第一篇試做 digest,記錄近期比較有意思的判決。

廢清法

社維法「驅使或縱容動物嚇人」

  • 1/7 雲林地院 113 年六秩字 7

    公司員工長期餵食,狗從公司空地竄出,嚇到送貨員。

    一開始也辯稱是流浪狗,但認「因公司員工長期固定的飼養行為,因此才會以公司內部為活動範圍,進出往返於公司內部空地,關係緊密,客觀上已非單純之流浪犬與不特定飲食提供者之關係」。

    結果公司負責人被認定為飼主之一,確定罰 3 千。

    註:判決書看起來,沒有深入追究餵食以外的行為,只說狗沒有綁、自由進出,大致以長期餵食和活動範圍認定。

動物加害人應將動物送醫(新北市動保自治條例)

  • 7/2 臺北高等行政 地方庭 113 年簡字 410

    開車撞到狗(當場死亡)未送醫,也未下車查看,一審要罰駕駛 3 萬。

    提行政訴訟後,認定當場撞死「送醫治療並無法達成保護動物生命之目的」所以撤銷。(有說仍算過失傷害致死,但不在這個裁判的範圍)

說八分話

既然有法規保護流浪動物生命,那麼讓狗流浪,儘管讓牠暴露在危險中,但對牠的生命是有保障的?

美化流浪,民眾會以為這樣可以,而不是萬不得已才流浪。 越是容忍,動物福利越差。