HTML 解析器規格三處勘誤、Node.js 同日釋出 26.8.1 與 24.20.0,加上 Lint 自動修復的併發健全性問題
github.com/whatwg/html · 2026-08-26
WHATWG 在 2026-08-26 對 HTML 標準的解析器章節推送三個規格修正 commit,同一天 Node.js 專案發布了 v26.8.1、v26.8.0 兩支 Current 版本與 v24.20.0 LTS,而 elm-review 作者 Jeroen Engels 也發表文章,指出多數 linter 在同時套用多個自動修復時存在邏輯上的健全性問題。三則消息分別觸及規格層、執行環境層與工具鏈層,但共同點都是「看似獨立的修改,合在一起可能互相踩線」。
HTML 解析器規格三處勘誤
WHATWG 編輯 Anne van Kesteren(annevk)與 noamr 在同一批修訂中處理了三個解析器邊界案例。window.open() 搭配 noopener 不再一律回傳 null 是其中最貼近日常開發的一項:舊規格規定只要 noopener 為真就回傳 null,但這與瀏覽器實作不符——當目標是 _self、_parent 或 _top 這類指向既有視窗而非開新視窗的情況,實際上不需要隔離,理應回傳視窗參考。
64b4096— window.open() with noopener should not always return null,對齊 web-platform-tests PR #62213b17ff2b— Honor a template's insertion target when foster parenting,修正 issue #1706849de3b— Parser scripting mode should default to Normal or Disabled,修正 issue #12847
第二項牽涉到 HTML 解析中的「foster parenting(寄養)」錯誤修復機制:當內容被錯置在 <table> 內卻不是合法的表格內容時,解析器不會丟出錯誤,而是把該節點「寄養」到最後一個表格元素之前的節點上,實質上將其挪出表格樹。此次修正處理的是當寄養目標剛好是 <template> 時的邊界情況——先前實作會忽略 template 本身的插入目標(insertion target),導致像 <template for> 這類永遠不會真正進入 DOM 的 template 場景發生內容遺失。第三項則是把「scripting mode」補上明確的初始值定義:解析器建立時,若文件已啟用 scripting 則預設為 Normal,否則為 Disabled,填補了先前規格只講屬性存在、未講初始狀態的空白。
Node.js 同日釋出 26.8.1、26.8.0 與 24.20.0
Node.js v26.8.1 是緊接在 v26.8.0 之後的 out-of-band 熱修版本。v26.8.1 只做了一件事:還原 v26.8.0 意外標成 alpha 的版本號(commit ebd35a9eec),另外修了 tools/nix/list-requisites.sh(0b0dd87fcc),不涉及安全性問題,單純是版本號誤標的即刻修正。
同日發布的 v24.20.0(代號 Krypton)則是一支功能豐富的 LTS 更新,重點包含 AsyncLocalStorage 支援 using 語法的資源管理、新增 permission.drop 與 --permission-audit 兩項權限系統能力、新的 node:stream/iter 模組、WebAssembly 的 JSPI(JavaScript Promise Integration)支援,以及測試執行器新增 context.log() 與 test:log 事件。根憑證也同步更新至 NSS 3.125。
| 版本 | 類型 | 重點內容 |
|---|---|---|
v26.8.0 | Current | 常規更新,版本號誤標為 alpha |
v26.8.1 | Current(熱修) | 還原版本號誤標,無新功能 |
v24.20.0 | LTS(Krypton) | permission.drop、node:stream/iter、WASM JSPI 等 SEMVER-MINOR 功能 |
Lint 自動修復的併發健全性問題
elm-review 作者 Jeroen Engels 在部落格文章中指出,像 ESLint 這類 linter 常把多條規則各自產生的自動修復一次性批次套用、再重新分析,但兩個編輯範圍互不重疊的修復仍可能在邏輯上互相衝突。他舉的例子是:一條規則把手寫的平均值計算改成呼叫既有的 average() 函式,另一條規則同時判定這個 average() 函式未被使用而將其刪除。
// 修復前
function average(nums) { ... }
const avg = (a + b) / 2; // 規則 A: 建議改為呼叫 average(a, b)
// average 從未被呼叫 → 規則 B: 判定為未使用,建議刪除
// 兩項修復同時套用後
const avg = average(a, b); // 參照到已被刪除的函式,ReferenceError兩個修復各自檢視都正確,合在一起卻產生「參照不存在的函式」錯誤。Engels 說明 elm-review 採用的作法是每次只套用一個修復就重新分析,而非批次套用後才重新分析:分析專案、套用一個修復、重新分析,再進入下一輪。這會犧牲一些效能,但能保證規則之間(尤其是維護者無法預期的第三方自訂規則)不會因為併發套用而產生邏輯衝突。
原始來源:WHATWG HTML commit 64b4096、commit b17ff2b、commit 849de3b、Node.js v26.8.1、Node.js v26.8.0、Node.js v24.20.0、jfmengels.net