Kalan's Blog

Kalan 頭像照片,在淡水拍攝,淺藍背景

四零二曜日電子報上線啦!訂閱訂起來

Software Engineer / Taiwanese / Life in Fukuoka
This blog supports RSS feed (all content), you can click RSS icon or setup through third-party service. If there are special styles such as code syntax in the technical article, it is still recommended to browse to the original website for the best experience.

Current Theme light

我會把一些不成文的筆記或是最近的生活雜感放在短筆記,如果有興趣的話可以來看看唷!

Please notice that currenly most of posts are translated by AI automatically and might contain lots of confusion. I'll gradually translate the post ASAP

Svelte Notes (2): Compiler is more clever than you mess

Today I went to check out the Svelte source code, familiarizing myself with its architecture while also looking for any simple issues to practice on. And then I came across this - emits warning.

Although I think, based on the description of this issue, an a tag without an href should be considered invalid (at least not compliant with a11y). Later, I looked it up and found that there are some inconsistencies in the current specifications mentioned on StackOverflow.

However, in essence, href can be empty, but in this case, it is recommended to use a button or similar tags instead of a for better screen reader compatibility.

Later, I checked eslint-plugin-jsx-a11y and found that this eslint plugin helps to determine whether the href is a valid value. The following are considered invalid values:

<a onClick={foo} /> // can be replaced with button
<a href="#" /> // only # without an id
<a href={"#"} /> // literal value
<a href={`#`} /> // literal value
<a href="javascript:void(0)" /> // should not use javascript:void(0)
<a href={"javascript:void(0)"} /> // literal value
<a href={`javascript:void(0)`} /> // literal value

There are also cases where href is empty:

<a />
<a href={undefined} />
<a href={null} />

Svelte checks basic a11y issues for you, such as missing href or invalid href values, because Svelte itself goes through a compilation phase, making these checks during the compilation stage:

// 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`
				});
			}
		}

At this stage, Svelte converts the syntax into an abstract syntax tree (AST), making the checks convenient.

However, upon closer inspection, huh? The case of javascript:void(0) seems to have been missed. Currently, it only handles cases where the value is empty or #. So I added a check: if (value === '' || value === '#' || /^\\W*javascript:/.test(value)) and submitted a Pull Request.

Another thing worth noting is that Svelte currently only checks for values that are is_static, so for cases like:

<a href={undefined} />
<a href={null} />
<a href={`#`} />
<a href={"javascript:void(0)"} />
<a href={`javascript:void(0)`} />

Because the content inside {} is an expression, Svelte cannot detect it (it marks is_static as false). To check these cases, additional handling is required for these expressions. I will fix them all when I have time (the Golden Week is coming up).

It doesn't seem like a very useful feature, to be honest. Since it is done during the compilation phase and doesn't affect the bundle size, I'm starting to feel that the compiler approach is feasible. You can write code in whatever way you prefer, and as long as it compiles to JavaScript, it's all good.

Although this is not a new idea, similar concepts can be found in languages like LiveScript or Elm, to some extent. However, I think the reason why Svelte has gained attention (or is more easily adopted) is that it retains most of the JavaScript syntax, making the template learning curve almost zero (if you know React or Vue). It feels like writing HTML, CSS, and JavaScript together, just like Vue.

Another advantage is Svelte's reactive mechanism and animation control, which are often important considerations when implementing front-end interfaces and are not easily provided by other compilers. Everyone wants functional programming, but in reality, if it doesn't solve the developers' real problems, it remains a pursuit of a few enthusiasts.

Prev

How to record video using XCode Simulator

Next

How to bring Github Actions to your project

If you found this article helpful, please consider buy me a drink ☕️ It'll make my ordinary day shine✨

Buy me a coffee