
今天,是「AI 全端投資實驗室」正式出生的日子。
過去兩週,我在本地端跟 Python 腳本、SQL 指令與 Excel 表格搏鬥。那些日子是孤獨的,所有的成果都只存在於我的 VS Code 終端機裡。但今天,我要把它推向世界。
我以為這只是一個簡單的 git push,沒想到卻是一場耗時四小時的「配置檔反恐行動」。
隱形的殺手:.gitignore 的無差別攻擊
最早的挫折來自於 Zeabur 的構建失敗。錯誤訊息很短:「Module not found: Can't resolve '@/lib/api-client'」。
這不合理。我在本地端跑得好好的,檔案就在那裡,我看得到它,摸得到它。為什麼雲端的伺服器就是找不到?
我嘗試了無數種解法:修改 tsconfig.json 的路徑別名、把絕對路徑改成相對路徑、甚至懷疑是不是 Linux 與 Windows 的大小寫敏感度在作祟。
直到我執行了 git check-ignore,真相才水落石出。
原來,我的專案是從一個 Python 樣板開始的。Python 的 .gitignore 裡有一行不起眼的規則:
lib/
這原本是用來忽略 C extension 編譯出的函式庫。但當我把 Next.js 引入這個 Mono-repo 時,前端慣用的 lib/ 資料夾(存放 API 客戶端程式碼)就這樣被這行規則「無差別攻擊」了。
Git 忠實地忽略了它,導致這個關鍵檔案從來沒有離開過我的電腦。雲端的伺服器當然找不到它。
教訓:在 Mono-repo 架構下,寫 .gitignore 必須要在路徑前加上 /(如 /lib/),將規則限制在根目錄,才不會誤殺子專案的檔案。
Next.js 14 的震撼教育
解決了檔案遺失,網頁終於跑起來了。但當我興沖沖地點擊「開發日誌」時,迎接我的卻是 404 Not Found。
這又是一個不合理。後端有資料,路由有設定,為什麼?
經過一番地毯式排查,才發現我又踩到了 Next.js 14 的新坑。在 App Router 中,動態路由的 params 現在被視為非同步物件。
錯誤寫法:
// 直接拿 id,導致拿到 undefined
const post = await getDevLog(parseInt(params.id));
正確寫法:
// 必須先 await params
const { id } = await params;
const post = await getDevLog(parseInt(id));
這個改動微小卻致命。它提醒我,即使是最熟悉的框架,在版號推進的洪流中,昨天的常識也可能變成今天的錯誤。
從終端機到網頁:視覺的最後一哩路
除了功能,我也對視覺做了最後的打磨。
我不希望這個網站看起來像是一個普通的部落格。它是一個「實驗室」,它應該要冷靜、深邃、充滿科技感。
- 強制深色模式:拒絕白底黑字的平庸,採用深黑背景搭配青色(Cyan)的發光文字。
- 磨砂玻璃質感:讓卡片懸浮在背景之上,邊框在滑鼠滑過時隱隱發光。
- 拔除超連結底線:透過 CSS 的
!important暴力美學,去除了破壞美感的藍色底線,讓連結回歸純粹的文字互動。
成果
現在,當我打開 https://aiferryman.zeabur.app,看著那一行行我過去 13 天寫下的開發日誌,整齊地排列在螢幕上,每一篇都能點開,每一段文字都清晰可見。
那種成就感是難以言喻的。
這不只是一個網站,這是我與 AI 在這 13 天裡的共同記憶。從中年失業的焦慮,到重拾技術的熱情,都在這些程式碼與文字裡了。
明天,我們要開始讓這個實驗室更聰明。也許是 AI 自動摘要,也許是即時股價儀表板。具體做什麼還沒決定,但重點是,舞台已經搭好了。
這是我 55 歲轉職 AI 開發的第 13 天筆記。 如果這篇文章對你有啟發,歡迎留言與我交流。