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: Minimalest upgrade #1872

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,201 changes: 2,602 additions & 599 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"!dist/**/*.spec.*"
],
"peerDependencies": {
"svelte": "^3.20.0 || ^4.0.0"
"svelte": "^3.20.0 || ^4.0.0 || ^5.0.0 || 5.0.0-next.1"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.2.0",
Expand Down
12 changes: 9 additions & 3 deletions packages/svelte/src/lib/components/SSR.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<script lang="ts">
<script context="module" lang="ts">
import type { Page } from '@inertiajs/core'
export type SSRProps = { id: string; initialPage: Page }
</script>

<script lang="ts">
import App from './App.svelte'

export let id: string
export let initialPage: Page
interface $$Props extends SSRProps {}

export let id: $$Props['id']
export let initialPage: $$Props['initialPage']
</script>

<div data-server-rendered="true" {id} data-page={JSON.stringify(initialPage)}>
Expand Down
55 changes: 35 additions & 20 deletions packages/svelte/src/lib/createInertiaApp.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { router, setupProgress, type InertiaAppResponse, type Page } from '@inertiajs/core'
import type { ComponentType } from 'svelte'
import SvelteApp from './components/App.svelte'
import SSR from './components/SSR.svelte'
import App from './components/App.svelte'
import SSR, { type SSRProps } from './components/SSR.svelte'
import store from './store'
import type { ComponentResolver, InertiaComponentType } from './types'

type SSRRenderResult = { html: string; head: string; css?: { code: string } }
type SSRComponentType = ComponentType<SSR> & { render?: (props: SSRProps) => SSRRenderResult }

interface CreateInertiaAppProps {
id?: string
resolve: ComponentResolver
setup: (props: {
el: Element
// @ts-ignore
App: ComponentType<SvelteApp>
App: ComponentType<App> | SSRComponentType
props: {
initialPage: Page
resolveComponent: ComponentResolver
}
}) => void | SvelteApp
}) => void | SSRRenderResult
progress?:
| false
| {
Expand Down Expand Up @@ -67,24 +69,37 @@ export default async function createInertiaApp({
if (progress) {
setupProgress(progress)
}
}

setup({
el,
App: SvelteApp,
props: {
initialPage,
resolveComponent,
},
})
let result = setup({
// @ts-expect-error
el,
App: !isServer ? App : SSR,
props: {
id,
initialPage,
resolveComponent,
},
})

return
}
if (isServer) {
if (!result && typeof (SSR as SSRComponentType).render !== 'function') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can make a cleaner check using import { VERSION } from 'svelte/compiler'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the follow up, I will need to double check that but I believe I had tried and this import is either not available il all svelte major versions or only available in the NodeJS context while compiling/transpiling with Vite. Also the import is going to fetch for Inertia's version and not the user specified version in his project.

At first I wanted to make this "transparent" to the user and dynamically render the proper way a component based on that version but I was unsuccessful

https://stackoverflow.com/questions/78470116/are-dynamic-imports-at-runtime-in-the-browser-esm-possible-with-svelte

throw new Error(`setup(...) must return rendered result when in SSR mode.`)
} else if (!result) {
console.warn('Deprecated: setup(...) must be defined and must return rendered result in SSR mode.')
console.warn('For Svelte 5: `return render(App, { props })` or for Svelte 4: `return App.render(props)`')
result = (SSR as SSRComponentType).render!({ id, initialPage })
}

// Svelte types are written for the DOM API and not the SSR API.
const { html, head, css } = (SSR as any).render({ id, initialPage })
const { html, head, css } = result

return {
body: html,
head: [head, `<style data-vite-css>${css.code}</style>`],
return {
body: html,
head: [
head,
// Note: Svelte 5 no longer output CSS
...(css?.code ? [`<style data-vite-css>${css?.code}</style>`] : []),
],
}
}
}
6 changes: 3 additions & 3 deletions playgrounds/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
},
"devDependencies": {
"@inertiajs/svelte": "^1.0.0",
"@sveltejs/vite-plugin-svelte": "^2.4.2",
"@sveltejs/vite-plugin-svelte": "^3.1.0",
"autoprefixer": "^10.4.13",
"axios": "^1.6.0",
"laravel-vite-plugin": "^0.7.2",
"lodash": "^4.17.19",
"postcss": "^8.4.31",
"svelte": "^4.2.14",
"svelte": "^5.0.0-next.126",
"tailwindcss": "^3.2.4",
"vite": "^4.5.3"
"vite": "^5.2.11"
}
}
10 changes: 9 additions & 1 deletion playgrounds/svelte/resources/js/app.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import { createInertiaApp } from '@inertiajs/svelte'
import { hydrate, mount } from 'svelte'

createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true })
return pages[`./Pages/${name}.svelte`]
},
setup({ el, App }) {
new App({ target: el, hydrate: true })
// Svelte 4: new App({ target: el, hydrate: true })

// Svelte 5
if (el.dataset.serverRendered === 'true') {
hydrate(App, { target: el })
} else {
mount(App, { target: el })
}
},
})
7 changes: 6 additions & 1 deletion playgrounds/svelte/resources/js/ssr.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { createInertiaApp } from '@inertiajs/svelte'
import createServer from '@inertiajs/svelte/server'

import { render } from 'svelte/server'
createServer((page) =>
createInertiaApp({
page,
resolve: (name) => {
const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true })
return pages[`./Pages/${name}.svelte`]
},
setup({ App, props }) {
// Svelte 4: return App.render(props)
// Svelte 5:
return render(App, { props })
},
}),
)
5 changes: 3 additions & 2 deletions playgrounds/svelte/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ export default defineConfig({
}),
svelte({
compilerOptions: {
hydratable: true,
},
// Svelte 4 only
// hydratable: true
}
}),
],
})