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

Svelte 5 support #124

Open
thiagomagro opened this issue Apr 14, 2024 · 25 comments
Open

Svelte 5 support #124

thiagomagro opened this issue Apr 14, 2024 · 25 comments
Labels

Comments

@thiagomagro
Copy link

Wondering how difficult would it be to migrate to Svelte 5.
Loving the idea here so far, keep improving!

@woutdp
Copy link
Owner

woutdp commented Apr 14, 2024

Should be straightforward, just waiting on a stable 5.0.0 release as it's still in beta :)

@directormac
Copy link

@woutdp what about now its on rc? i'm trying to explore the phoenix ecosystem with livesvelte.

@woutdp
Copy link
Owner

woutdp commented Apr 28, 2024

I'd rather wait a bit until it's officially released. It seems there's some breaking changes and not a straightforward upgrade and I want to avoid having to fix them twice if anything changes again in the stable version.

I will accept PR's that implement the RC though, if anyone is up for it. I'd be happy to merge and push a new version.

@chrisnaadhi
Copy link

chrisnaadhi commented May 1, 2024

i think it should be updated to v4 first if the dependencies was still v3.56, as in the blog said :

Components written for Svelte 4 will continue to work with Svelte 5, with a handful of exceptions. If you install Svelte 5 in an existing app, the only real change should be that things get faster. If you maintain a Svelte app, we recommend updating to Svelte 5 as soon as it's stable. (In the meantime, if you're currently on Svelte 3 then you should update to Svelte 4.)

@woutdp
Copy link
Owner

woutdp commented May 1, 2024

We're already on v4.

If you maintain a Svelte app, we recommend updating to Svelte 5 as soon as it's stable.

I'd like to follow Svelte's official recommendation, as soon as v5 is stable, I'll make the change. And like mentioned if there's interest in getting this out sooner, I'm accepting PR's!

@rsousacode
Copy link

rsousacode commented Aug 14, 2024

I managed to have it running without SSR, which for me is fine and unlocks development until we've stable support. :D

Here's the steps I took:

Disable SSR, as in the README (https://github.com/woutdp/live_svelte/blob/master/README.md#requirements). I just commented out the Node SuperVisor line.

In build.js add the compatibility level to 4 as suggested in the docs.

plugins: [
    importGlobPlugin(),
    sveltePlugin({
        preprocess: sveltePreprocess(),
        compilerOptions: {dev: !deploy, hydratable: true, css: "injected", compatibility: {componentApi: 4}},
    }),
],

Tweak assets/package.json to use svelte 5 (you may need to run npm install --force)

For example my devDependencies look like this:

 "devDependencies": {
    "esbuild": "^0.16.17",
    "esbuild-plugin-import-glob": "^0.1.1",
    "esbuild-svelte": "^0.8.1",
    "svelte": "5.0.0-next.220",
    "svelte-preprocess": "^6.0.2"
  },

@woutdp
Copy link
Owner

woutdp commented Oct 19, 2024

I've been looking at this today since Svelte 5 was just released officially.

We'll need to wait until it's supported by esbuild-svelte too: EMH333/esbuild-svelte#234

@woutdp woutdp changed the title Thoughts about Svelte 5? Svelte 5 support Oct 19, 2024
@ravides19
Copy link

Hi @woutdp eagerly waiting for default svelte5 support 💯

@kigila
Copy link

kigila commented Oct 27, 2024

Waiting for new update

@zazer1
Copy link

zazer1 commented Nov 1, 2024

Hi @woutdp , just got confirmation that esbuild-svelte supports Svelte 5. What needs to be done for live_svelte support, is there any issues or tickets that you could use a hand resolving/implementing?

@woutdp
Copy link
Owner

woutdp commented Nov 1, 2024

It says:

minus support for .svelte.(js|ts)

I think we do need support for .svelte.js files as the hooks file will make use of that. I might be wrong though, if you want to take a shot at it you can check out the svelte-5 branch where some of the progress was already made towards Svelte 5 support.

@AlexKovynev
Copy link

@woutdp if so look like it ready https://github.com/EMH333/esbuild-svelte/releases/tag/v0.9.0

@woutdp
Copy link
Owner

woutdp commented Nov 9, 2024

Just leaving an update here because people are eager for this. Just looked at it again and didn't get it to work yet, will work on it some more tomorrow. Progress can be tracked on the svelte-5 branch, help is appreciated too!

@woutdp
Copy link
Owner

woutdp commented Nov 11, 2024

Another try today. Made some progress on converting the hook.js file into hook.svelte.js and compiling it with esbuild-svelte. Seems to work. Still hitting the following issues, if anyone has any idea of what's going on with this help is appreciated:

template.js:15 Uncaught TypeError: Cannot read properties of null (reading 'nodes_start')
This happens when the element doesn't have a root div. For example:

Hello world

Will trigger this error message.

But:

<div>Hello world</div

won't trigger this.

That triggers the following error:

operations.js:77 Uncaught TypeError: Cannot read properties of undefined (reading 'call')

And then in some cases I get:

errors.js:177 Uncaught Error: effect_orphan

For example on the breaking news component.

So not sure what's going on with this. I've tried using mount for non-ssr'ed components and hydrate for ssr'ed components, but none of them work. hydrate does remove the ssr'ed HTML markup so that's in line with what's expected.

Progress can be tracked on a very dirty branch svelte-5

@ElijahJohnson5
Copy link

ElijahJohnson5 commented Nov 11, 2024

Hey I managed to get most everything working. The errors with the operations and others you are seeing seems to be because of multiple svelte runtimes being bundled. At least that is the conclusion I came to. I have a branch here https://github.com/ElijahJohnson5/live_svelte/tree/svelte-5 where I think all of the examples are working but I can't seem to get the props updating to work nicely (without looping through the props every time)

The change that fixed the operations.js:77 Uncaught TypeError: Cannot read properties of undefined (reading 'call') error for me along with the other ones you listed was to make sure to mark svelte as external external: ["svelte"], when building the live_svelte library. And then just for dev I had to add alias: { svelte: "svelte", }, to the build.js in the example project to make sure to only bring in the copy of svelte in the example_project/assets/node_modules folder.

Let me know if this is makes any sense. I am happy to help with this more! (I helped get the svelte 5 support for esbuild-svelte across the line)

@woutdp
Copy link
Owner

woutdp commented Nov 11, 2024

@ElijahJohnson5
Thank you, absolutely fantastic work, I was blocked hard on this issue. I've managed to get it working with your changes!

I'm not too woried about looping through the props as I expect people to not have too many props, and if they do have them they would probably put them in a map, and a map gets updated properly it seems :)

@ElijahJohnson5
Copy link

That's awesome to hear! Happy to help with anything else you may run into

@woutdp
Copy link
Owner

woutdp commented Nov 11, 2024

I've just released a release candidate version for Svelte 5 support. This is what's on the current svelte-5 branch

Test guide for 0.15.0-rc.1

To test it out do the following 3 steps:

  1. Update mix.exs and run mix deps.get
# `mix.exs`
{:live_svelte, "0.15.0-rc.1"}
  1. Update to the latest Svelte 5 version in your package.json
    Update your package.json with the latest esbuild-svelte and svelte version:
 "esbuild-svelte": "^0.9.0",
 "svelte": "^5.1.13",
  1. Update your build.js file
    Which you can find here: https://github.com/woutdp/live_svelte/blob/svelte-5/assets/copy/build.js

Feedback

Please let me know how it goes. Note you might get some warnings in your code, this is because Svelte is a little bit more strict in how it parses your HTML in your Svelte files.

If everything is working for people I'll make an official 0.15.0 version.

Still in progress

  • Slot support
  • LiveJson support (might deprecate in favor of something built in, not sure yet)
  • Making sure mount/hydrate is called correctly dependant on if the component is SSR'ed, current value we're looking at is incorrect I believe.

@ElijahJohnson5
Copy link

Looks like some of the props are messed up from my testing. Same with on the LiveJson page. I am pretty sure the $state needs to have some identifier. I think think the reason the LiveJson isn't working is because we are only keep one set of props, since the SvleteHook only ever gets created once for all components

@woutdp
Copy link
Owner

woutdp commented Nov 12, 2024

For the props that don't work, would it be possible to make a specific component in the example_project so I can test it?

@ElijahJohnson5
Copy link

ElijahJohnson5 commented Nov 12, 2024

Sure I will try making one. An easy example is in any of the counter pages if you just duplicate the component you will see weird stuff with the values changing only for the second component.

The component I was playing around with in my own code was something like

    <div class="w-full flex h-full">
      <div class="h-full flex-[0.3]">
        <.RoomSidebar rooms={@rooms} />
      </div>
      <div class="flex-1 max-h-80">
        <div :if={@live_action == :show} class="h-full">
          <.Messages messages={@messages} class="h-full" roomId={@room.id} ssr={false} />
        </div>
        <.MessageForm />
      </div>
    </div>

Where the messages were not getting updated when switching rooms because the state in the SvelteHook was set to the last svelte component rendered (in this case the MessageForm)

@woutdp
Copy link
Owner

woutdp commented Nov 12, 2024

Thank you for the info, was able to reproduce and I think it's fixed now, please feel free to test again

New version available:
0.15.0-rc.2

@woutdp
Copy link
Owner

woutdp commented Nov 13, 2024

New version available:
0.15.0-rc.3

Some minor tweaks but mostly the same as previous version. This is hopefully the version that goes out as 0.15.0

@woutdp woutdp mentioned this issue Nov 13, 2024
@woutdp
Copy link
Owner

woutdp commented Nov 14, 2024

New version: 0.15.0-rc.4

Trying to integrate it with a project now, but hitting an issue when trying to import a component from a parent component. Not hitting this same issue in the example_project.

Uncaught ReferenceError: ChildComponent is not defined

Not sure what's going on here but will continue investigating

@hackemateninja
Copy link

hackemateninja commented Nov 16, 2024

I continue getting this error error with deadviews with the new update

if I do this

<script lang="ts">
	import {
		Header,
		HeaderNav,
		HeaderNavItem,
		HeaderNavMenu,
		SideNav,
		SideNavDivider,
		SideNavItems,
		SideNavLink,
		SideNavMenu,
		SideNavMenuItem,
		SkipToContent,
		Content
	} from "carbon-components-svelte";
	import Fade from "carbon-icons-svelte/lib/Fade.svelte";
	import type {Snippet} from "svelte";

	type Props = {
		children: Snippet;
	};

	let {children}: Props = $props();

	let isSideNavOpen = $state(false);
</script>

<Header company="IBM" platformName="Carbon Svelte" bind:isSideNavOpen>
	<svelte:fragment slot="skip-to-content">
		<SkipToContent />
	</svelte:fragment>
	<HeaderNav>
		<HeaderNavItem href="/" text="Link 1" />
		<HeaderNavItem href="/" text="Link 2" />
		<HeaderNavItem href="/" text="Link 3" />
		<HeaderNavMenu text="Menu">
			<HeaderNavItem href="/" text="Link 1" />
			<HeaderNavItem href="/" text="Link 2" />
			<HeaderNavItem href="/" text="Link 3" />
		</HeaderNavMenu>
		<HeaderNavItem href="/" text="Link 4" />
	</HeaderNav>
</Header>

<SideNav bind:isOpen={isSideNavOpen} rail>
	<SideNavItems>
		<SideNavLink icon={Fade} text="Link 1" href="/" isSelected />
		<SideNavLink icon={Fade} text="Link 2" href="/" />
		<SideNavLink icon={Fade} text="Link 3" href="/" />
		<SideNavMenu icon={Fade} text="Menu">
			<SideNavMenuItem href="/" text="Link 1" />
			<SideNavMenuItem href="/" text="Link 2" />
			<SideNavMenuItem href="/" text="Link 3" />
		</SideNavMenu>
		<SideNavDivider />
		<SideNavLink icon={Fade} text="Link 4" href="/" />
	</SideNavItems>
</SideNav>

<Content>
	{@render children()}
</Content>

and encapsule my layout with this

<.svelte name="Shell">
  <.flash_group flash={@flash} />
  <%= @inner_content %>
</.svelte>

and in a regular liveview do this

defmodule KarmamedicWeb.Dashboard.Welcome do
  use KarmamedicWeb, :live_view

  def mount(_params, _session, socket) do
    socket =
      assign(socket,
        age: 20
      )

    {:ok, socket}
  end

  def handle_event("update_age", _, socket) do
    {:noreply, assign(socket, age: socket.assigns.age + 1)}
  end

  def render(assigns) do
    ~H"""
    <.svelte name="DashboardWelcome" props={%{age: @age}} socket={@socket} />
    """
  end
end


my svelte view is this

<script>
	import {Button, Column, Grid, Row} from "carbon-components-svelte";

	let name = $state("Herman");

	let {age, live} = $props();

	let items = [
		{name: "hello", desc: "desc"},
		{name: "hello", desc: "desc"},
		{name: "hello", desc: "desc"},
		{name: "hello", desc: "desc"},
	];

	const handleUpdateAge = () => {
		live.pushEvent("update_age");
	};
</script>

<Grid class="mt-20">
	<Row>
		<Column>
			<h1>Hello dashboard welcome {name} {age}</h1>

			<Button onclick={handleUpdateAge}>Update age</Button>

			{#each items as item}
				<div class="flex flex-row items-center gap-4">
					<p>{item.name}</p>
					<p>{item.desc}</p>
				</div>
			{/each}
		</Column>
	</Row>
</Grid>

the age don't update till i do this

<.svelte name="Shell" />
<.flash_group flash={@flash} />
<%= @inner_content %>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests