Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from glimmer.js to svelte #19

Merged
merged 81 commits into from
Oct 12, 2022
Merged

Migrate from glimmer.js to svelte #19

merged 81 commits into from
Oct 12, 2022

Conversation

chadian
Copy link
Owner

@chadian chadian commented Feb 28, 2022

This pull request migrates Vorfreude from glimmer.js to svelte (and addresses #6). Jumping from where glimmer.js was back when this project started to where it is now was too big of a leap to the point where it felt similar to a rewrite. The glimmer.js project doesn't feel as stable now, I ran into contradictory documentation and it looks like a few of the conventions are in flight as rfcs are changing. Considering this, along with the fact that Svelte is more stable and offered a new opportunity to learn, I decided to go ahead with Svelte.

It'll be interesting to compare what sort of bugs crop up from the migration as well as any benefits like performance or overall bundle size.

  • Remove glimmer.js implementation
  • Update README
  • Write acceptance tests
  • Finish migration with tests
  • Try object-fit with object-position and flex box instead of fixed/absolute and background-image (check for resize performance, too)
  • Manually test extension build steps in the chrome folder
  • Test routing works for settings from extension options
  • Verify other manifest.json relative build artifacts (ie: icons, etc) are loaded correctly
  • Add testing around the fetcher, manually test, and possible design differently

Takeaways from the migration

While glimmer.js has stagnated, it's bigger sibling Ember.js has a lot of out of the box that was lacking in Svelte(Kit), although Svelte(Kit) also had a few things that Ember could learn from.

  • (Routing) Ember's router is much more mature. SvelteKit's file-based routing borrows a lot of conventions from Ember and in some cases has some nice hooks that are easy to use but not being able to easily support hash-based routing and pushing a number of SSR and prerender techniques and configuration made it a bit confusing. Essentially, Sveltekit expects to be hosted in a way that can handle this from something like Netlify and the single-SPA mode was a bit awkward.
  • (Components) Svelte wins here in many ways. The way reactivity works with stores seems to be more obvious with how reactivity is handled. It's easier than useState in react, and a little more explicit that tracked with Ember since $ and the store interface feels more like "just javascript", ie: being able to use the subscribe method to subscribe to changes is nice and when used in templates $store is syntax sugar to tracking those changes in the DOM. Also the arbitrary javascript of react combined with similar template helpers of ember makes svelte work really well ({#if}{else} in svelte vs {{#if}} in ember vs weird ternary or condition && result in react). Defining a component interface via ES Module exports feels odd, like it betrays the semantics of modules and expectations around export 🤷.
  • (Testing) Ember wins here. Having to use testing-library with svelte and jest/js-dom along with SvelteKit's playwright left a lot to be desired. Playwright is nice in that it's "more real" in simulated browser interactions but ember's abstractions around haven't failed me yet. Playwright is great, but having to have different setups, jest/jsdom and playwright, for unit/component and acceptance test, respectively, it a bit more work and requires an understanding of different APIs and mental models of how the environment they're running in. With ember, you're always running in the browser, you're always using the test'em runner, and the apis are consistent across both. Overall though, the Svelte testing is much quicker.
  • (Build) This goes back to the (Routing) point but Ember is more versatile in how it builds. Maybe vite with Sveltekit has better chunking/tree-shaking support but the final artifacts for SvelteKit are so geared towards the SSR/prerender use cases that it seemed less flexible to the "just html, css and js" use cases. Also my SvelteKit build for the chrome extension required some hackery in the build to get SHA's around the artifacts as to satisfy content security policy (CSP) restrictions for browser extensions. This was due to the fact that to kick off the app SvelteKit uses inline javascript in the html and ember bundles this externally. While in "dev mode" the vite builds with SvelteKit were lightning quick and didn't require refreshing the page with hot module reloading "just working", that felt like magic.

All in all Svelte and SvelteKit look very promising. Much of it feels quick to pick up and the APIs seem barebones enough that you only reach for what you need and when you do the learning curve is incremental in a way that mostly works and feels natural. Some of the infrastructure and ecosystem around Svelte and SvelteKit seem like they still need more work but it does seem like it's setup in a way that it can be extensible and improve (ie: there was an extension adapter for building browser extensions but it failed out of the box with an unresolved issue that was listed on the GitHub).

There are other areas where Svelte should shine even more, like animations, but I didn't have a reason to explore these. After working around build and routing issues SvelteKit does feel like a good choice and hopefully provides a bit more opportunity for this little app to grow even more.

@chadian chadian force-pushed the svelte branch 2 times, most recently from 8a8029a to aaf72d9 Compare May 27, 2022 20:16
@chadian chadian force-pushed the svelte branch 6 times, most recently from 4c921a2 to 963f0da Compare August 23, 2022 16:29
@chadian chadian changed the title Implement Vorfreude using Svelte Migrate from glimmer.js to svelte Aug 23, 2022
Using hashes to track routes in urls is better for chrome
extensions. This is because the default of providing a route at
/settings for example doesn't map in extension land to a .html

There is probably a way of intercepting route changes in
extensions for urls and redirecting them but this would require
escalated privledges and be harder to test.

The other method of generating a prerendered .html file for every
route almost worked except svelte's routing doesn't recognize
a route at its .html location once it's loaded. It wants to deal
with goto("/settings"), it doesn't recognize
goto("/settings.html").

The hacky workaround I have here works pretty well. Every route
change that happens it goes and replaces the current route with
a corresponding hash representation.

If someone reloads the page the hash representation needs to be
mapped back to its corresponding route and then navigated to
that route by svelte's `goto`. Upon entering that route it will
again have its url replaced with its hash match.

This method also helps encapsulate the swapping of the routes
to be friendly for local dev server or extension. In the case of
the extension the hash is at "index.html#route" and when being
served by the local dev server it is replaced with "/#route".

While this is hacky it is consistent and allows for everything
to be handled entirely "in app". If this app were to increase the
number of routes it had to manage then this hash mapping would
become less sustainable and maybe more research into how other
svelte apps handle this challenge would be warranted.
If there was already a chrome tab opened then going to the options
would not open a new tab at #settings nor would it update the
existing opened tab to #settings, resulting in the options button
linked from the browser's extension page essentially noop'ing.

This dedicated settings.html does a local js redirect to
index.html#settings and that way every new tab opened by the
browser's extension option page will end up at index.html#settings
This means that the bg will be rendered before any js and css is
loaded and parsed, hopefully reducing the amount of "white" flash
This commit adds a route that is as an ugly hack for when
"index.html" loads and it tries to load the corresponding route.
Without this "index.html" route the router can't find a matching
route, throws an error, but still ends up at the default route
(so the user doesn't notice the issue) but it leaves an ugly
error in the console.

By having an "index.html" route which is a shortcoming of being
able to serve from static files like within extensions, this
route kicks things off by navigating to the root route "/".
@chadian chadian merged commit e864c02 into main Oct 12, 2022
@chadian chadian deleted the svelte branch October 12, 2022 22:57
@chadian chadian mentioned this pull request Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate to latest version of glimmer (or some other front-end component library)
1 participant