digital envelope routines::unsupported

Node.js 16 LTS 已經結束維護,所以手上的東西就開始需要升級升級,然後就必須要來正面面對這個我逃避已久的錯誤訊息:

digital envelope routines::unsupported

這錯誤基本上就是發生在幾個網站的專案,尤其是 build 專案時特別會容易看到,而且這個錯誤其實和一般看到的 JS 錯誤長得不太一樣,全貌其實是這樣:

digital envelope routines::unsupported

Error: error:0308010C:digital envelope routines::unsupported

首先是錯誤訊息,前面有一些 hex 值,不知道是什麼,然後下面 trace 的地方,可以看到幾乎都是 node_module 內的東西,不是因為我們自己的 code 造成的,所以就很讓人困惑,想說是不是什麼系統問題、還是有什麼偷用非公開 API 造成不相容的狀況。總之以前就是遇到這個問題就是又降版回來,沒有仔細深究,這次終於要來認真處理,不過搜尋結果,幾乎都是說加一個--openssl-legacy-providerflag,都沒人說到底是什麼問題,尋找許久,終於在 StackOverflow 找到一則最正確的答案,沒想到和 OpenSSL 1.x 的生命已經到盡頭有關。

結果這個錯誤,其實是因為 Node.js 17 開始,從 OpenSSL 1.x 換到 3.x,然後 OpenSSL 3.x 不是向下相容的,所以有些東西有機會出錯,這邊爛掉的,其實是一些 legacy 的 hash method 預設是拿掉的,而 Webpack 在建立 bundle 檔案時,如果檔名有用到 hash 的話,預設的 hash method 用的就是已經被淘汰的 md4,然後 md4 是用 Node.js 的 crypto 來呼叫 OpenSSL 做事,Node.js 的文件也有提到支援的演算法是依據你的 OpenSSL 版本和系統而定,所以其實並沒有保證 md4 一定可以用,而如果使用了 OpenSSL 不支援的演算法,跑出來的錯誤訊息就是像上面截圖一樣特別了,然後我還特別去用 OpenSSL 3 cli 跑跑看,結果出來的錯誤訊息真的就是差不多:

OpenSSL 3 error

使用 flag 開啟舊演算法的支援其實我覺得還算可以接受,畢竟是 build 而已,不是拿來跑服務,不過這個 flag 似乎有點特殊,似乎不能直接放在NODE_OPTIONS裡面,而且同個程式庫要是拿到舊版 Node.js 環境去跑,加這個 flag 反而跑不起來,所以最理想還是把問題解決掉。

那這個問題應該怎麼處理呢?其實簡單說就是把套件升級升級就好了,因為現在的套件新版本都有處理這個問題,不過走上升級這條路之前可以先試試看 StackOverflow 上的解法(有可能讓你專案爛掉,請先備份):

npm audit fix --force

如果你用的是 yarn,沒有audit fix可用,但是也有人提供用 npm 來修理的流程,不過我是沒試過這個流程,我自己有一個專案是靠yarn upgrade升級後解決問題的(實際上是把所有有用到的 loader-utils 都升級到 2.0.4,本來有個套件用到 2.0.0),剩下的還是無法修好的就要靠手工了,然後因為我處理的網站只有 Gatsby 和 CRE(Create React App) 兩種,所以以下就是只有說明這兩個系統的為主,兩者其實都是使用 Webpack 作打包工具的,而 Webpack 是從 v5.61.0 開始保證支援 Node.js 17 的,我稍微查了一下 Gatsby 是從 4.2.0,而 CRA 的則是要最新版 react-script 5.0.1 才保證支援,為什麼說是保證呢?因為^的 semver range 的關係,例如要是你的 react-script 是 5.0.0,那你本地可能會是裝到 Webpack v5.60.0,那就不支援 Node.js 17 了,像我就是有 Gatsby 3.x 的,升級到 4.x 就沒事了。

Gatsby 和 CRA 其實都還好,最慘的是 eject 過的 CRA 了,只能手工升級,基本上就是去 react-script 那邊,複製需要的檔案回到你的專案覆蓋過去,最主要的是scripts/config/下的檔案,然後根據自己的修改紀錄把自己作過的修改改回去,接著更新package.json裡面的 dependencies,版本號就是參照 react-script 那邊的 package.json,最主要的就是webpack相關的,接著安裝套件後重新 build,要是還有一樣的錯誤,就看 trace 看看是哪個相依套件,看有沒有新版有修正就更新試試看,大概就是這樣,很容易漏東西所以會一直重複測試,蠻花時間的,不過最後 build 成功還是有成就感的。

PS. 還要小心其他升級的後遺症,如果是 app 最好要測試過各種行為,像我遇到 Webpack 5 不支援 polyfill Buffer 的問題,剛好那個錯誤又被 catch 掉,所以我 build 是沒問題的,就是測試跑不過,後來參考網路上的文章處理。


Vim License 的故事(下)

Vim License on choosealicense

接續前一篇

Mike 在 SPDX License List 這邊提出的問題則是,為什麼會有 Vim 要替換,但是 Vim Maintainer 不要替換這樣特別的情形,所以我就是認真的解釋,並且說明這是跟原作者 Bram 確認過的細節並附上討論,還有舉我前面提過那個最極端的例子,然後我猜最重要的是現實世界有沒有人這樣使用過,還好我還真的找到幾個專案有認真的把條款內的 Vim 替換掉(當然是連 Vim Maintainer 也換掉了),像是 Tagbar;我的 PR 是 2019/07/11 提的,然後一直來回到 9/25 回了最後一個回應之後就沒人回我了,之後到了 10/19 就突然被合併了(其實 SPDX 有定期的會議,應該是在其中有討論過要不要合併這個 PR 吧),接著等到 2020 一月我發了 PR 到 choosealicense 把 vim.txt 加進去,這次就蠻順利就合併了。

閱讀「Vim License 的故事(下)」全文

Vim License 的故事(上)

‎vim-license-slide.‎001

這篇是我去年 COSCUP 分享的文字版,拖稿許久終於寫出來了,以下正文開始。

Open Source Software 一直是 GitHub 的心頭肉(?),也因此 GitHub 一直都有在各方面協助 OSS 開發者,其中也包括了對 Open Source License(開源授權)相關的協助。在 2013 年,GitHub 發佈了一個小網站choosealicense.com,用簡單的條列介紹各開源授權條款的特色,並且藉由一些問答互動來幫助開發者挑選開源軟體授權條款。

而到了 2016 年,GitHub 更進一步提供了授權條款的偵測功能,只要你的程式庫裡面有正確的授權條款資訊(像是 LICENSE 檔案),然後使用的條款也在偵測的範圍內,那在 GitHub 上就會顯示該專案所使用的授權條款,也會同時提供該授權條款的特色給訪客參考,不過這個偵測功能,能偵測到的授權條款只有一些,更精確的說,就是只有 choosealicense 網站上的那些。

在 GitHub 推出授權條款偵測功能後沒多久,我就發現到 Vim 所使用的 Vim License 並不在偵測的範圍內。Vim License 是一個很特別的授權條款,是 Vim 的作者 Bram Moolenaar 專為 Vim 使用而寫的,雖然內文是針對 Vim 本身寫的,不過其實有很多的 Vim Script 也是標注使用 Vim License,甚至常常是寫 "Same as Vim",所以實際上使用的專案並不少,所以我就一直想著,是不是有可能讓 GitHub 可以支援偵測 Vim License 呢?

閱讀「Vim License 的故事(上)」全文

更之前的文章