沒穿方服

首頁

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 萬。

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

說八分話

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

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

公共政策網路參與平臺上的「第四次動野保大戰」第一輪,官方逐字稿還沒出來,先寫一些感想。

2025-9-16 公共政策網路參與平臺提案「落實收容所人道安樂死,強化飼主責任管理,餵食者同管領人應依動保法承擔飼主責任」意見蒐集會議 - YouTube


  1. 動保司江文全主持,代表農業部,其實主持得不錯。
  2. 正方積怨已久,這次動搖了野保=理性、毛寶=偏激的形象。

    「推動人」大量發言,提案人反而很少講話。 會議一開始就無視議程,逕自檢討技正洩資、打十年前的黃泰山、質疑利益團體入場。 後面也跟陳祺忠搭配開火,讓很多人看了「很爽」。

    但對我而言是扣分,沒有打到點上,加重對立誤會。

  3. 正方蕭舜庭、劉正吉的內容都很實在、切題,風格理性順暢。
  4. 議程的「施政內容」部分直接「跳過」,這是程序上的一大進步。 大家都認可是廢話,浪費時間。
  5. 動保司有整理國際上餵食管理的法規,這個很棒。
    • 新加坡:《環境公共衛生法》裁罰餵養造成髒亂,初犯 2 千新幣,再犯 4 千,累犯最高 1 萬(約 23 萬新台幣)
    • 日本:《動物愛護及管理法》授權地方餵養自治,例如和歌山縣規定僅能餵養已絕育的貓,且需維護整潔,罰鍰 5 萬日圓以下
    • 澳洲:州法規授權地方管理,地方直接規定犬貓「是否能存在於公共空間」,罰鍰各不相同,可為數百至數千澳幣(換算新台幣約 20 倍)
    • 歐盟:
      • 西班牙馬德里自治區:禁止餵食遊蕩犬,最重罰 1,500 歐元(約 5 萬新台幣)
      • 義大利托斯卡納地區:類似
    • 美國:
      • 明尼蘇達州 Callaway 市:原則禁止,例外允許餵養(獸醫、有管理遊蕩職權者),罰 90 天拘役或 1000 美元以下,或並罰
      • 康乃狄克州:貓隻餵養人需登記為 keeper,未負責或配合可罰 60 美元
      • 依利諾州 芝加哥市:貓隻餵養人需註冊為 owner,負飼主責任,但參與照顧者可以不必視為飼主

    ※動保司應該是本來就有做功課,這次剛好拿出來撐場面,沒關係還是給肯定。

  6. 地方動保單位幾乎都偏向正方(支持落實人道處理、禁餵),嘉義、台北、宜蘭、高雄都蠻明顯的。
    台南其實也是,但不愧是成效最差的縣市,話講比較輕,還講不到兩分鐘,全場最速。
  7. 反方動平會、相信動物還是以重複講他們做法為主,性質跟前面跳過的「廢話」很像,大家都聽膩了。
    郭璇最末一小段有跳回問題主軸,但毛病依舊,在我看來理據是經不起考驗的,偏偏缺少讓人反駁的機會。
  8. 反方柯元傑(代表台南市流浪動物愛護協會,但他同時也是共生聯盟發言人)嘗試針對提案內容逐條對抗,頻頻被陳祺忠大聲打斷。
    我是想看血流成河,但需要的是直接辯論,否則這樣拼氣勢也不痛不癢,擔心外人只看到正方妨礙表達。
  9. 打圓場部分,吳宗憲運用一種不知道在說什麼的文體已經爐火純青,我不知道這段是否有看的價值,如果有價值的話就值得一看。
  10. 張錕盛、顏紘頤兩位法律人講得很中肯,一直拿公報主張「餵食視同飼主」說動保司胡亂解釋法條的人,首先就該正面面對他們的論點,把邏輯理順再說。
    公報內容參考:立院公報86卷45期,144 頁

總結,農業部還是照他的步調在走,提案也不真的代表動保、野保群體,不要對平台有錯誤期待,更不要當成聖戰。

vim-cycle 1.4.0

14 年前發布 vim-cycle 0.1.0貼文)有得到一些迴響,但後來可能宣傳上被同名 zef/vim-cycle 掩蓋,接著又有 switch.vim 打破限制支援 pattern,繼續用 vim-cycle 的理由就不多了。

今年為了清掉古早 issue,幫專案加了 test,體質提昇後就開始加功能,結果變出了不錯的成果。

新增 regex 選項,大致就是跟 switch.vim 一樣的機制,例如 ruby 的 :bar => 可以變成 bar: ,以往是做不到的。 設定上也可以收割 switch.vim 的豐富資產,只要做一些微調(主要是把 vim dictionary 換成 list)即可。

新增 matcher / changer 定義,也就是「什麼東西要 cycle」「要怎麼 cycle」變成可抽換的,這麼一來 regex 也只是一種變體而已。

於是出現了紀年轉換,可以從民國年、日本元号、泰國佛曆、西元年之間轉換。
還有 naming convention 也被獨立出來,變成跟 regex 不太一樣的思維,比較好維護和擴充。

前陣子新增的 select 介面有時也很實用,將選項列出來用選的,而不是一個一個跳,也支援 telescope 等不同 UI。

錄了 demo 影片(影片有聲音):

歡迎多加利用或宣傳,至少讓類似專案的「類似專案」不要老是忽略我。