今天跑去看 Svelte 原始碼,摸熟架構的同時順便看看有沒有什麼簡單的 issue 可以拿來練手。然後看到了這個 — emits warning。
雖然我覺得以這個 issue 的描述來看,沒有 href
的 a tag 應該是不合法的才對(至少不符合 a11y),後來我去查了一下,在 StackOverflow 上有提到目前的規範有些不統一的地方。
但基本上 href 可以是空的,只是在這種情況下就不要用 a
而是考慮用 button 之類的標籤取代,這樣對 screen reader 比較友善。
後來我去看了一下 eslint-plugin-jsx-a11y,發現這個 eslint 會去幫你判斷 href 是否為合法值,裡頭非法值有:
<a onClick={foo} /> // 可以用 button 取代
<a href="#" /> // 只有 # 沒有 id
<a href={"#"} /> // 字面值
<a href={`#`} /> // 字面值
<a href="javascript:void(0)" /> // 不應該用 javascript:void(0)
<a href={"javascript:void(0)"} /> // 字面值
<a href={`javascript:void(0)`} /> // 字面值
還有 href 為空的情況:
<a />
<a href={undefined} />
<a href={null} />
Svelte 會幫你檢查基本的 a11y
,像是 missing href 或是 href value invalid 等,因為 Svelte 本身有先過一層編譯器,所以檢查都會在編譯階段做:
// compiler/compile/nodes/Element.ts
// L425
if (this.name === 'a') {
const attribute = attribute_map.get('href') || attribute_map.get('xlink:href');
if (attribute) {
const value = attribute.get_static_value();
if (value === '' || value === '#') {
component.warn(attribute, {
code: `a11y-invalid-attribute`,
message: `A11y: '${value}' is not a valid ${attribute.name} attribute`
});
}
} else {
component.warn(this, {
code: `a11y-missing-attribute`,
message: `A11y: <a> element should have an href attribute`
});
}
}
在這個階段,svelte 幫你把語法變成了語法樹(AST),所以檢查起來也很方便。
不過定睛一看,咦? javascript:void(0)
的 case 好像沒有處理到,目前只會針對 value 為空跟 #
的情況做處理。所以就順手加了一行檢查: if (value === '' || value === '#' || /^\\W*javascript:/.test(value))
提 Pull Request 了。
另外紀錄一下比較麻煩的是 svelte 現在只會針對值是 is_static
做檢查,所以像是:
<a href={undefined} />
<a href={null} />
<a href={`#`} />
<a href={"javascript:void(0)"} />
<a href={`javascript:void(0)`} />
因為 {}
裡都是 Expression svelte 檢查不到(會直接把 is_static 標記成 false)。想要檢查的話就要另外針對這些 Expression 做處理,有空(黃金週也快到了)再一次全部修修看。
感覺不是什麼很有用的功能啦,反正是在編譯階段做也不會影響到 bundle size,現在越來越覺得編譯器這條路感覺是行得通的耶,喜歡用什麼樣的方式寫自己決定,反正 compile 完變成 JavaScript 就好。
雖然這也不是什麼新想法,像是 LiveScript
或是 Elm
等等,或多或少都是這樣的概念,但我覺得 Svelte 能夠被大家注意到(或比較容易被使用)的原因在於它保留了大部分的 JavaScript 語法,template 學習成本幾乎是 0(如果你會 React 或 Vue),寫起來就像 HTML, CSS, JavaScript 寫在一起的 Vue 而已。
另外就是 svelte 的 Reactive 機制和動畫控制,這些東西是常常是前端在實作頁面時需要特別考慮的,也是其他編譯器沒辦法提供的。大家都想要 Functional Programming,但實際上如果沒有解決到開發者真正的問題,那麼也只是少數愛好者的執念而已。