Behind-the-curtains: how do I "manually compile" *.svelte
files directly without any "vite / rollup / webpack / other-bundler"?
#11830
-
More of a backend dev, frontend isn't my daily bread+butter.. but I do know my vanilla (ie. non-frameworked) html/js/ts/css! =) Well I'm looking to transition to Svelte my (thankfully still tiny) static-HTML + TypeScript-only, node/npm-free frontend code-base (which currently compiles TS to JS not via This custom finetuned handcrafted build-time code does various other things too and is not getting scrapped. Instead I want to add Svelte compilation to it. (Without further npm deps even if an npm call for the svelte compiler is probably necessary.) So really I want to learn how to call the Svelte compiler (from terminal, shell script, or any custom code) against my Is there some detail documentation on the actual steps of compilation-to-(JS+CSS) that is not just the advice to a "use any one of these bundlers" (vite / webpack / rollup / SvelteKit etc), and where? Because under https://svelte.dev/docs/ I could not find any. I mean I did find this (which starts out with "Typically, you won't interact with the Svelte compiler directly" — oh yes, I fully intend to!), which kind of describes its own top-level exports / funcs or some such — but what's the real-world invocation, is it (And then, with that covered, I'll be needing to also cover |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
You are about to embark in a very painful travel because you will basically need to re-invent the whole As you mentioned there's some documentation about the compiler: import { compile } from 'svelte/compiler';
const result = compile(source, {
// options
}); this is technically all you need to compile a svelte component to JS. Here i have a small compiler playground...if you write your svelte component in the textarea you can see the result of the compilation in the object below. As you can see is as simple as calling Now you can take the js code, import it in your code and use it. To actually mount that component you want to use the client side component api which in svelte 4 looks something like this import App from './App.svelte';
const app = new App({
target: document.body,
props: {
// assuming App.svelte contains something like
// `export let answer`:
answer: 42
}
}); note that both the playground and the documentation i'm linking refers to svelte 4 since svelte 5 is still in release candidate and there's not much docs on it. However the compiler is likely to stay the same and the client side component api can be seen here If you want to do server side rendering the things get's more complicated. You can use the server side component api (basically every class has a render method on the server that returns an object with html, css and the head. Here's the changes for svelte 5. Now the difficult part: if you look at a simple generated code where you import another svelte component you can see this /* generated by Svelte v4.2.17 */
import {
SvelteComponent,
create_component,
destroy_component,
init,
mount_component,
noop,
safe_not_equal,
transition_in,
transition_out
} from "svelte/internal";
import "svelte/internal/disclose-version";
import Some from "./Some.svelte";
function create_fragment(ctx) {
let some;
let current;
some = new Some({});
return {
c() {
create_component(some.$$.fragment);
},
m(target, anchor) {
mount_component(some, target, anchor);
current = true;
},
p: noop,
i(local) {
if (current) return;
transition_in(some.$$.fragment, local);
current = true;
},
o(local) {
transition_out(some.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(some, detaching);
}
};
}
class Component extends SvelteComponent {
constructor(options) {
super();
init(this, options, null, create_fragment, safe_not_equal, {});
}
}
export default Component; as you can see the import for the other svelte component is untouched. This means that you will have to rewrite those imports to correctly point to the generated js file (there are ways to instruct the runtime to do an on the fly conversion from svelte to js but that's another story). This is a lot and it's just scratching the surface of all the weird quirk that you may face to bundle your own svelte components but if this is enough for you it might still be good. |
Beta Was this translation helpful? Give feedback.
-
Nowadays, there are so many bundlers that perhaps it would be best to write a bundler adapter instead of having a plugin for vite. In this way, anyone who wants to adopt a bundler should only import one adapter and would be working (with minimal effort) with that bundler. There could even be an adapter to output the code without a bundler, as requested by @metaleap. Will it be possible? |
Beta Was this translation helpful? Give feedback.
You are about to embark in a very painful travel because you will basically need to re-invent the whole
vite-plugin-svelte
(which btw could serve you as a starting point) 😄As you mentioned there's some documentation about the compiler:
this is technically all you need to compile a svelte component to JS.
Here i have a small compiler playground...if you write your svelte component in the textarea you can see the result of the compilation in the object below.
As you can see is as simple as calling
compile
with the string of your component and you get back an object with a bunch of properties:js
whi…