kit
kit copied to clipboard
build single js file and single css file like Svelte does.
Describe the problem
Is there an option or an adaptor that will build the app as svelte does - with a single js file and single css file?
Describe the proposed solution
This makes embedding into wordpress much simpler.
Alternatives considered
I am using the adapter from '@sveltejs/adapter-static'
but this builds each component into many individual js and css files.
Also tried the wordpress adapter. It is not compatible with the latest version of Svelte Kit. And I do not believe it will create a single js file and single css file.
Importance
i cannot use SvelteKit without it
Additional Information
No response
I see that using adapter( { fallback: 'index.html' })
get's me most the way there - 2 js file and 1 css file. But the file names change after each compilation (/_app/assets/vendor-4ff902fe.css"
) which makes linking to these files impossible without another build step. Is there a way to set the file name much like we can set the pages
and assets
directory names?
<link rel="stylesheet" href="/_app/assets/vendor-4ff902fe.css">
<link rel="modulepreload" href="/_app/start-7cbc46f1.js">
<link rel="modulepreload" href="/_app/chunks/vendor-878788bc.js">
You may be interested in the inlineStyleThreshold
option: https://kit.svelte.dev/docs/configuration#inlinestylethreshold
The name is based on the file contents. This allows the file to be cached. Can you explain more about why you would want to link to these files?
@benblazak , thanks for the idea but I don't think it will work in this case.
I have several svelte apps which I am dynamically inserting into wordpress content via shortcodes. In wordpress/php I wp_register_script()
and wp_enqueue_script()
to add the css and js assets to the wordpress page render process. These filenames can not change. I then insert the svelte startup markup into the content. e.g. svelte: <div id="app"></div>
, or sveltekit: start({...})
I was hoping to use sveltekit moving forward but I may have to go back to svelte for these embedded apps.
Wondering if I should be looking at component packaging instead https://github.com/sveltejs/kit/issues/518 https://github.com/sveltejs/kit/pull/1499
Encountered same need, we are transitioning from a React SPA. Hopefully this will get some love
@gevera looks like you can use vite config to influence file names: https://github.com/sveltejs/vite-plugin-svelte/issues/375#issuecomment-1156609925
@cubic3d
I tried and doesn't work.
The following Vite config options will be overridden by SvelteKit:
- build.rollupOptions.output.entryFileNames
- build.rollupOptions.output.chunkFileNames
- build.rollupOptions.output.assetFileNames
I have the same problem with the latest version of Svelte.
While there's no solution or adapter itself hasn't been improved, I've created the "hacky" way of re-wrapping the project files to the bundle.js: https://github.com/d-velopment/SvelteKit-One-Bundle
It's not solving the problem of thousand chunks but gives the bundle.js to be loaded from a custom index.html or another project to render the application.
Can folks share their use cases for this? If we implement it, I'd like to ensure that we document when to use it vs when not to. I believe users should mostly avoid this option, but I'd like to hear about valid use cases so that we can guide users appropriately.
My use case is for an enterprise platform. In truth I don't need all the JS to be in a single file. Rather I need all the JS to be built to the /dist folder, no JS or CSS in subfolders.
So the enterprise platform I use allows me to serve a single html page at an endpoint with all JS & CSS file requests coming from that endpoint e.g.
Index html: platform.com/webapp/my_app All JS/CSS files: platform.com/webapp/my_app/{filename}
Although that forces me to use hashed routing as well which I guess I'll have to implement myself unless Sveltekit has one I can turn on.
@benmccann I'm making a Capacitor application for iOS/Android. Capacitor works by starting a local web server and then serving your application like a static host on your phone. This local server does not have SSL or HTTP/2, so while some requests load in parallel, it takes quite a while to load 50+ resources over HTTP/1. It's hard to measure raw numbers but in our project it takes around ~1 second for loading up the app until interactable and about half that on our PWA version. So it takes twice as long to load a local application on your phone than going to servers in a different country.
In my case I am using svelte to create a web interface inside an ESP32 (microcontroller), for the microcontroller, the fewer requests it has to attend to, the better, for this reason having everything in one file is ideal, or at least the html, js and css are each in a single file.
This is also a common problem highlighted by SEO tools. 'reduce number of css files'. Would be good to be able to combine them.
I have this need for importing components into other systems like wordpress or drupal.
In react, we've always handled this by reading the assets manifest.json file from webpack to figure out which file names we need to load, which vite DOES support under the options build.manifest, but when I try and enable that settings I get the error:
The following Vite config options will be overridden by SvelteKit:
- build.manifest
Like @wozzashek mentioned, I also work with an enterprise system, Microsoft Dynamics/Power Platform.
- In their case Microsoft prepends a cache busting version value (=hash/guid) in front of my web files in the url path. So a hash in the js/css filenames is unnecessary.
<Microsoft Dynamics URL>/%7B<version value>%7D/WebResources/index.html
- Those web resources are part of a solution zip file which is used to deploy and redeploy updates. So I want to have the same file names, otherwise my solution grows and grows with each build being added.
I tried all suggestions to disable the [hash] in the file names, but nothing works. Having multiple chunks is not a problem in my use case, as long as they have the same file names.
Any suggestions on how to disable the hash in the file names?
My use case is for packaging up an admin front-end UI within a back-end library. The devs consuming the library will ultimately choose which paths the UI will be served under, and it needs to be dynamic at runtime. eg. The Hangfire dashboard UI (not my project, but a close analogy to what I need to do): https://docs.hangfire.io/en/latest/configuration/using-dashboard.html Note the end of the article, I'd like to support things like this too:
Multiple DashboardsΒΆ You can also map multiple dashboards that show information about different storages.
var storage1 = new SqlServerStorage("Connection1"); var storage2 = new SqlServerStorage("Connection2");
app.UseHangfireDashboard("/hangfire1", new DashboardOptions(), storage1); app.UseHangfireDashboard("/hangfire2", new DashboardOptions(), storage2);
My most obvious usecase is developing a CSS framework and using SvelteKit as a wrapper for documentations and also partially custom implementation of the CSS style for one off svelte components.
So, such a feature would be extremely, extremely appreciated;
PS. Stuff like these seemed to be the focus/concern of the dev team at some point in time? see: Svelte.Dev Blog CSS-in-JS
@benmccann Any updates on this topic?
We need this solution in sveltelkit
as well, as we have a domain
issue restriction with the amount of Page Resources
loaded, and need to minimize the number of resources
Goolge-Bot needs to load.
The current solution, that we have identified that works as intended for CSS
, is to use the following setup, using
https://www.npmjs.com/package/vite-plugin-css-injected-by-js
π src/app.html
[...]
<link
rel="preload"
href="/all-css-chunk.css"
as="style"
/>
<link
rel="stylesheet"
type="text/css"
href="/all-css-chunk.css"
/>
[...]
π vite.config.ts
import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite';
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
import fs from 'fs';
[...]
plugins:
[
sveltekit(),
// ### WARNING:
// ### 'this' plugin removes all 'CSS' from standard
// ### importing by 'svelte/svelteki' and styles will be missing
// ### if not imported as a '<link ... >' in the 'src/app.html'
cssInjectedByJsPlugin
(
{
// ### NOTE:
// ### definitive 'hack' solution for 'single CSS file' output chunk.
injectCode:
(
cssCode,
options
) =>
{
// ### NOTE:
// ### the 'cssCode' generated contains some 'formatting' issues.
// ### 1. remove 1st and last speech marks.
// ### 2. remove cases of `\n` chars.
// ### 3. correct custom-cases of ids/classes using the 'forward-slash' in the html declaration.
let cssCodeMod: string = cssCode.slice(1, -1);
cssCodeMod = cssCodeMod.replace(/\\n/g, "");
cssCodeMod = cssCodeMod.replace(/\\\\/g,"\\")
// ### WARNING:
// ### 'all-css-chunk.css' must exist inside '/static'
fs.writeFile
(
'./static/all-css-chunk.css',
cssCodeMod,
err =>
{
if (err) console.error(err);
}
);
return '';
}
}
),
[...]
Warning The only issue with this that has been detected, is that the
<style>
from thesrc/routes/+layout.svelte
file are not present in theall-css-chunk.css
output, but every other<style>
is present in thefinal
chunk.
No single js files? This destroys user-experience. The latency between requests is just too much for any clients running below 3G. Be it microcontrollers like already mentioned or just generally bad connections which happen to everyone at some point. I think I'd just use Svelte for now.
No single js files? This destroys SEO. The latency between requests is just too much for any clients running below 3G. Be it microcontrollers like already mentioned or just generally bad connections which happen to everyone at some point. I think I'd just use Svelte for now.
I disagree with what you expose, I have been working with microcontrollers for a long time, where the number of concurrent connections is very limited and saturates the memory to the point of restarting the device. However, when I have a single file, the operation is the most optimal.
No single js files? This destroys SEO. The latency between requests is just too much for any clients running below 3G. Be it microcontrollers like already mentioned or just generally bad connections which happen to everyone at some point. I think I'd just use Svelte for now.
I disagree with what you expose, I have been working with microcontrollers for a long time, where the number of concurrent connections is very limited and saturates the memory to the point of restarting the device. However, when I have a single file, the operation is the most optimal.
Did you even read my comment properly? That's literally what I said. SvelteKit is bad for this kind of stuff. And you are not the only one working with microcontrollers as I've been running my own camera surveillance for years.
@Beyondo
No single js files? This destroys SEO.
This is false. In fact multiple JS files make the page appear faster because the browser has time to render things between JS files instead of rendering one huge blocking JS chunk.
The latency between requests is just too much for any clients running below 3G.
This is debatable. If you analyze a waterfall diagram you'll see that most requests load in parallel, it's not a chain of 30 requests one after another. When testing my latest project on https://web.dev/measure/ it got 99/100 in performance, when using simulated 4G slowdown. So Google does not seem to think there is any issue with the current approach.
@Beyondo
No single js files? This destroys SEO.
This is false. In fact multiple JS files make the page appear faster because the browser has time to render things between JS files instead of rendering one huge blocking JS chunk.
The latency between requests is just too much for any clients running below 3G.
This is debatable. If you analyze a waterfall diagram you'll see that most requests load in parallel, it's not a chain of 30 requests one after another. When testing my latest project on https://web.dev/measure/ it got 99/100 in performance, when using simulated 4G slowdown. So Google does not seem to think there is any issue with the current approach.
I disagree. This is not "false". You are saying that because some clients load the files in parallel or have a guaranteed connection, it is justifiable to literally divide the website into these horrible chunks? Your simulated slowdown is different from real-world slowdown. And I realized this is the hard way.
In an actual slow network scenario, it is not merely a matter of "bandwidth throttling" as commonly emulated in our development tools and all requests just 100% succeed after only a longer time like in your Google tests. No. In the real world, a sluggish network means any request could be dropped at any time.
Division of our SvelteKit website into numerous requests is nightmarish, as it poses the risk of any of these requests being dropped, which causes the site to cease functioning correctly or rendering appropriately. In my humble opinion, SvelteKit remains unsuitable for many projects (or at least not favorable).
I disagree. This is not "false".
The "This destroys SEO." part is false. I said that the latency part (which is what your post is about) is debatable.
If you are worried about poor connectivity, you can implement a service worker. Requests can always be dropped, but with HTTP/2 multiplexing, multiple requests are handled in the same stream, so the chances are reduces since you are not creating one connection per request.
I think the problem from your argument comes from your spreading FUD ("learned the hard way", "nightmarish") as opposed to trying to have a fact-based discussion. I am in favor of being able to build just one output file, but it's not for the reasons you suggested.
I disagree. This is not "false".
The "This destroys SEO." part is false. I said that the latency part (which is what your post is about) is debatable.
If you are worried about poor connectivity, you can implement a service worker. Requests can always be dropped, but with HTTP/2 multiplexing, multiple requests are handled in the same stream, so the chances are reduces since you are not creating one connection per request.
I think the problem from your argument comes from your spreading FUD ("learned the hard way", "nightmarish") as opposed to trying to have a fact-based discussion. I am in favor of being able to build just one output file, but it's not for the reasons you suggested.
Wow I'm sorry this is my typo. I meant user-experience and was talking about user-experience for the entirety of my two comments if you noticed. I didn't mean to say 'SEO' in my first comment and didn't even see it at all till you just mentioned it now. I edited it, you can check it again.
I'm honestly deeply sorry for this confusion. I never claimed my opinion as a "fact-based" either but actually said it is in my humble opinion to have one output file just like you said you favor them too.
In any case, I'd like to politely note that your premise that "chunky js files" are slower is not true but is that they actually they load faster (if not the same) since not only are they streamed straightforwardly in a single request, but you can always load them asynchronously (without waiting) while showing any pretty splash-screen for a few milliseconds before your layout loads to not have any layout shift. Of course this is just a design choice, like maybe splash screens aren't you thing, but again IMHO, they're much better than plain white backgrounds waiting for tens of preloaded scripts, and it gives the illusion that your app instantly loaded. Paired with a service worker for caching & some versioning, and any new updates would force the user to redownload the scripts making your app instant and versatile.
But it's not like this is new knowledge, single output files have always been favored by almost everyone. So although we both have might have different (or maybe overlapping) uses for a single chunky output, we both give legitimate reasons nonetheless or edge cases for own specific apps; it is not like Svelte is built only for a specific set of websites, but for all kind of web apps. So I might be wrong, but do we really disagree on anything here?
Sharing my use case for this feature. I'm in the process of building a Google Sheets add-on, and Google mandates that the HTML must be served from a single file with no local imports. Right now I'm using Svelte + Vite with vite-plugin-singlefile.
We use kit to build the frontend for a major tv manufacturer. Many of our SOCs have underwhelming performance and seem to struggle to efficiently download the 200+ JS files needed to load any given endpoint.
We use the static adapter currently as much of our content is very difficult to cache and SSR at this scale (tens of millions of active devices), without caching, becomes very "expensive" in many ways.
It would be great if we could experiment-with/optimize the build output for this use case (fewer files). If we could get help/advice with this (even in the form of some workaround/hack) I'd be more than happy to share some of the the real world results if it can help when deciding on the importance of this type of functionality in kit.
My use-case is like OP: I'm building both a full-page application, deployed on a separate server, and an embedded version that is inserted into Wordpress articles via shortcode. I have gotten this to work using Svelte but can't seem to figure out how to do it with Sveltekit.