在 Vercel 上的 Revalidation 和 ISR 的一個坑點

我對某件事感到驚訝,所以我寫了一篇文章來介紹。 第一次測試 ISR,這是 Next.js 提供的一個非常酷的功能。 基本上,我們可以在構建時靜態生成網站,因此一開始就提前獲取了所有的數據,然後 Next.js 提供了網頁的緩存版本。 但是我們也可以告訴 Next.js 網頁應該每隔 n 秒重新驗證一次。 所以我們可以設置(Next.js 13 應用文件夾): export const revalidate = 30 然後每 30 秒重新驗證一次該頁面。 該頁面會以超快的速度提供給在上一次驗證後 30 秒之後首次訪問該 URL 的用戶(需要有人在重新驗證之前訪問該 URL,它不是一個定時任務),但在後台它會再次構建,完成任何需要進行的數據獲取。 這很酷。 但在 Vercel 上,重新驗證流程運行在一個無服務器函數中。 這讓我花了好幾個小時來解決一個我認為是一個 BUG 的問題(新的應用程序文件夾仍處於 beta 階段,所以可能會發生),但是我要麼沒有閱讀正確的文檔,要麼文檔並沒有很好地記錄。 重新驗證的無服務器函數運行在與第一次構建不同的環境中。 第一次構建可以寫入文件系統。重新驗證的無服務器函數無法這樣做。它可以寫入系統的臨時文件夾,您可以使用 os.tmpdir()(首先需要 import os from 'os')獲取該臨時文件夾,但與其他構建之間沒有"通信"。 我試圖下載一些圖像,並將其作為站點的一部分,但這種工作流程是行不通的。 此外,我們無法訪問原始構建中下載的先前文件,因為我們看不到它們,我們處於全新的環境中。 這可能在無服務器函數環境中是常識,但對我來說是個驚喜。 不管怎樣,一旦您了解到這一點,您就會知道限制並找到解決方法。 例如,我可以將資源託管在 S3 上,或者像我最終為快速解決方案所做的那樣,將小圖像編碼為數據 URI。 哦,還有一個提示:為了調試重新驗證,我使用了按需重新驗證,這真的很酷。 因此,我可以訪問 API 端點來重新驗證特定的頁面路由,而無需等待重新驗證的時間。 使用按需重新驗證的一個坑點是,我在一個不獲取數據的路由上啟用了重新驗證(因為我將所有要解決的問題)從中剝離了所有數據獲取),當我嘗試使用 ODR 時,我遇到了這個問題,它顯然表示無法完成重新驗證,因為沒有數據可以重新驗證。基本上,它被標記為服務器錯誤,但實際上不是。這可能是一個在以後的更新中被修復的問題,請記住本文章的日期。

在 VS Code 中使用正則表達式進行搜索和替換

我需要對我的網站存儲庫進行一個相當大的更改。 我有數百個 Markdown 文件,而在我的 Markdown 中,有時會包含帶有空格的圖像,這主要是因為它們是截圖,所以格式類似於 Screen Shot 2021-10-16 at 09.45.47.png 加載圖像的字符串是: ![Alt text](/images/vscode-search-replace-regex/Screen\_Shot\_2021-10-16\_at\_09.45.47.png) 這在我安裝的 Hugo 版本中運行良好,但最近在版本 0.100 中,他們刪除了我使用的 Markdown 库,名為 Blackfriday,現在只支持 Goldmark,它不再允許圖像中有空格(還有其他更改)。 為了跟上 Hugo,我真的需要更新我的網站,因為我使用的是舊版本,已經停止更新 10 個月了。 這就是我的問題所在。我需要更新所有的圖像鏈接。 嗯,其實不是這樣。我可以在圖像名稱中加上 <>: ![Alt text](/images/vscode-search-replace-regex/Screen\_Shot\_2021-10-16\_at\_09.45.47.png) 然後一切又正常了。 我只需要搜索和替換所有的圖像鏈接! 我有成千上萬個這樣的鏈接,這不是我要做的事情。 所以我記得在 VS Code 中的查找/替換功能中有正則表達式。 經過一番試驗,使用如下的正則表達式: !\[(.+)\]\((.\*\s+.\*)\) 我能夠創建 2 個捕獲組,一個用於 alt 文本,一個用於文件名。 然後在替換框中,我可以使用 $1 作為 alt 文本,使用 $2 作為文件名: !\[\]\((.\*\s+.\*)\) 這個替換字符串 ![](/images/vscode-search-replace-regex/$1)對於沒有 alt 文本的圖像有效(我知道,我知道…): 我是如何得出這些正則表達式的? 主要通過我的 JavaScript 正則表達式教程。 我之前寫過那篇文章,但它仍然是我首選的資源。 然後是一些谷歌搜索和使用 https://regex101.com 快速測試正則表達式。 正則表達式對我來說仍然有點神奇,但有時它是唯一能做到的工具。 就像在這個例子中一樣。

在 VS Code 中清除終端機

我通常使用 cmd-k 來清除終端機,但在 VS Code 中,這個組合鍵並不起作用。 我不得不使用 cmd-shift-P,然後搜尋 Terminal: Clear 命令。 結果我發現我已經設置了 cmd-k 的組合鍵,但它並沒有起作用。 在鍵盤快捷方式設定界面中,When 列被設置為 terminalFocus && terminalProcessSupported。我將它設置為只有 terminalFocus,然後它就能正常工作了。 你也可以刪除 terminalFocus,這樣即使終端機沒有聚焦,cmd-k 也可以清除控制台,有時這很方便。

在 VS Code 中隱藏類別

最近我一直在使用一個名為 Tailwind Fold 的 VS Code 擴展。 使用這個擴展,您可以決定在 JSX 和 HTML 檔案中預設隱藏所有類別,只有在點擊它們時才顯示出來: 這是原始檔案的樣子: 如您所見,它看起來更乾淨。 我通常將這個擴展設定為非啟用狀態,這樣我就能看到所有的類別,但是當我想要一個"清爽的外觀"時,我有一個快捷鍵可以隱藏所有的類別。 相當方便。

在C語言中可以嵌套函數嗎?

想知道在C語言中是否可以嵌套函數嗎? 不可以。 在C語言中無法在其他函數內部定義函數。 例如JavaScript、Swift或Python等語言中,嵌套函數是很常見的用法。 然而C和C++並不支援這種選項。 你的下一個最佳選擇是將需要執行某些工作的函數放在一個獨立的文件中,並只公開客戶端程序需要使用的主要函數,這樣你就可以隱藏不需要公開的所有內容。

在Docker Hub上分享Docker鏡像

像我們在從頭開始創建Node.js Hello World Docker容器的文章中創建的映像一樣,它是簡單的,但它是嘗試Docker的一個很酷特性的完美範例,通過Docker Hub提供公共和私有Docker鏡像的官方托管服務。 然而,在我們這樣做之前,我們需要在Docker Hub上註冊。 Docker Hub的基本計劃是免費的,包括無限的公共倉庫和一個私有倉庫。如果需要更多,可以選擇付費計劃。 註冊並登錄後,您將看到您的儀表板: 現在,使用您的用戶名,您需要使用以下命令行來登錄: docker login --username <username> 現在,您可以使用docker tag創建映像,並使用docker push將其推送到Docker Hub: docker tag <image> <username>/<tagname> docker push <username>/<tagname> 如果您忘記登錄,當您運行docker push時,您將收到denied: requested access to the resource is denied的錯誤消息。 現在,您應該在Docker Hub的儲存庫列表中看到您的映像: 點擊它以查看更多詳細信息: 現在,由於映像是公開的,每個人都可以使用它來創建自己的容器,或者將其用作基礎映像。 您現在可以創建一個新的標籤,生成映像的新版本,還有很多其他您可以做的事情,例如: 從外部存儲庫(如GitHub)進行映像的自動構建 執行自動化測試 設置Webhook,在更新存儲庫映像時執行任何操作 創建組織和團隊

在Express中如何獲取解析後的body和原始body

了解如何在Express中使用body-parser獲取解析後的body和原始body。 在我正在構建的某個應用程序中,我遇到了這個問題。 使用Express,我可以導入body-parser來將body解析為JSON: import bodyParser from 'body-parser' app.use(bodyParser.json()) 然而,為了與Stripe支付API集成,我需要將原始body(未解析)暴露給一個端點,但我無法找出如何在解析body為JSON的同時實現這一點。 下面的代碼可以解決這個問題: app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf } })) 現在可以通過req.rawBody獲取原始body,並且通過req.body獲取JSON解析後的數據。 從body-parser的GitHub上我發現,這將使每次請求的RAM使用量翻倍,但由於我需要這個功能,我別無選擇。 除非為我想處理的Stripe webhook創建一個不同的伺服器。

在Express中處理表單

如何使用Express處理表單 以下是一個HTML表單的示例: <form method="POST" action="/submit-form"> <input type="text" name="username" /> <input type="submit" /> </form> 當用戶按下提交按鈕時,瀏覽器會自動發送一個POST請求到頁面所在的同源/submit-form URL。瀏覽器會將數據編碼為application/x-www-form-urlencoded格式發送。在這個例子中,表單數據包含了username輸入字段的值。 表單也可以使用GET方法發送數據,但是大多數情況下你會希望使用POST。 表單數據將會在POST請求的請求體中發送。 為了提取這些數據,你需要使用express.urlencoded()中間件: const express = require('express') const app = express() app.use(express.urlencoded({ extended: true })) 現在,你需要在/submit-form路徑上創建一個POST終點,任何數據都將在request.body上可用: app.post('/submit-form', (req, res) => { const username = req.body.username //... res.end() }) 在使用數據之前,別忘了對數據進行驗證,你可以使用express-validator來實現。

在Express中處理表單上傳的文件

如何在Express中管理存儲和處理通過表單上傳的文件 這是一個允許用戶上傳文件的HTML表單的示例: <form method="POST" action="/submit-form" enctype="multipart/form-data"> <input type="file" name="document" /> <input type="submit" /> </form> 不要忘記在表單中添加enctype="multipart/form-data",否則文件將無法被上傳 當用戶點擊提交按鈕時,瀏覽器會自動向與該頁面相同源頭的/submit-form URL 發送一個POST請求。瀏覽器將數據以multipart/form-data的形式而不是編碼的形式(即普通表單的application/x-www-form-urlencoded)發送出去。 在服務器端,處理multipart數據可能會很棘手且容易出錯,因此我們將使用一個名為formidable的實用庫。這是GitHub倉庫,它擁有超過4000顆星且得到良好的維護。 您可以使用以下命令來安裝它: npm install formidable 然後在您的Node.js文件中引入它: const express = require('express') const app = express() const formidable = require('formidable') 現在,在/submit-form路由的POST端點中,我們使用formidable.IncomingForm()實例化一個新的Formidable表單: app.post('/submit-form', (req, res) => { new formidable.IncomingForm() }) 在這樣做之後,我們需要能夠解析表單。我們可以通過提供一個回調函數來同步進行解析,這意味著所有文件都被處理,一旦formidable完成它們的處理,它就會使它們可用: app.post('/submit-form', (req, res) => { new formidable.IncomingForm().parse(req, (err, fields, files) => { if (err) { console.error('Error', err) throw err } console.log('Fields', fields) console.log('Files', files) for (const file of Object....

在GitHub上發布了我的密碼 / API金鑰

或者在GitLab或其他公共源代碼管理平台上。現在該怎麼辦? 我偶然發現了一個網站,該網站不斷掃描GitHub、GitLab和BitBucket,這是三個最常用的公開源代碼主機地方,並展示了提交的SSH密碼、常用服務的API金鑰、數據庫等等。 這讓人很害怕,對吧? 如果這從未發生過,請舉手。我們都會犯錯。當這種情況發生時,唯一的辦法就是迅速使公開的密碼或API金鑰失效。 對於新手來說,在Git中,你不能只是回滾提交,因為它仍然會保留在存儲庫的歷史記錄中。 你的聲譽、項目的聲譽、用戶的安全都面臨風險。 在解決緊急情況後,問題是:如何避免這個問題?答案是什麼?有什麼解決方案可以幫助我們避免將密鑰提交到公開可用的Git存儲庫中? 答案是:工作流程和工具。 首先,永遠不要將API金鑰或密碼添加到源代碼中。它們可能悄悄地藏在那裡。相反,始終將它們添加到項目根文件夾中的.env文件中,並將.env添加到.gitignore文件中,這樣就不會被提交。使用類似dotenv的工具來訪問它們。 使用git-secrets工具,它將幫助你避免將密鑰提交到Git中。 在macOS上,你可以使用Homebrew進行安裝: brew install git-secrets 然後進入要在其上啟用它的存儲庫中,運行: git secrets --install 以安裝Git pre-commit hook。這將確保在Git提交到存儲庫之前運行該工具。 如果你使用Amazon Web Services (AWS),運行以下命令以添加該服務的識別模式集: git secrets --register-aws 你可以立即使用以下命令掃描問題: git secrets --scan 理想情況下,該工具不應該打印任何內容。但如果有問題,它會提供詳細的信息。