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

Build an output that is usable from local disk (file:// URL) #907

Open
jzillmann opened this issue Apr 6, 2021 · 20 comments
Open

Build an output that is usable from local disk (file:// URL) #907

jzillmann opened this issue Apr 6, 2021 · 20 comments
Milestone

Comments

@jzillmann
Copy link

jzillmann commented Apr 6, 2021

Is your feature request related to a problem? Please describe.
Quite often i code tools which take some input (like a JSON file) and generate a HTML report out of it. This HTML report might be served by a server (e.g. Github Pages) but often just sits somewhere on the disk and should be openable/consumable from there (e.g. open file:///Users/x/projects/y/build/test/index.html).

Describe the solution you'd like
From initial experiments (with adapter-static) I found 2 things I would need for the above to work which I failed to accomplish with svelte-kit so far:

  • Links/Includes (from index.html) need to be relative instead of absolute
    • paths/assets||base were quite resistant setting up anything relative
  • The JS field need to be in IIFE format (since module script imports will raise CORS issues)
    • vite.build: { lib: { name: "my-app", entry: "src/main.ts", formats: ["iife"] }} produced UMD and IIFE output formats are not supported for code-splitting builds

A solution would be to make the 2 things possible.
Perfect would be a simple way to achieve that. Like an specialized adapter.

Describe alternatives you've considered
Maybe what I'm trying to achieve is dump and using svelte-kit for such a thing doesn't make much sense? Just stick to Svelte Classic ?

With Svelte Classic and Vite I can accomplish the above by tweaking vite.config.js in the following way:

  • Set base to '' (makes the links relative)
  • Configure IIEF format:
build: {
  lib: { name: "my-app", entry: "src/main.ts", formats: ["iife"] },
}
  • Move the index.html to public/ and add appropriate script and css includes

How important is this feature to you?
This is the first thing I usually set up for the majority of apps I'm crafting.

@KonradHoeffner
Copy link

I understand your pain as I have the same problem. See also issues #1553 and #1154.

@benmccann benmccann mentioned this issue Jul 19, 2021
5 tasks
@btakita
Copy link

btakita commented Jul 20, 2021

@jzillmann Re your current Svelte Classic & Vite solution: could you go more into the routing?

@jzillmann
Copy link
Author

@btakita Not sure what you mean...

@btakita
Copy link

btakita commented Jul 22, 2021

@jzillmann How are you currently routing to the different "page" components in the SPA? I wonder if it's feasible to extract only the Sveltekit router to use with Classic Svelte & Vite.

--- Edit

I'm going to try to add use rollup & @sveltejs/kit as a git submodule to directly output all of the JS & CSS into index.html. Will expose some core functions such as create_manifest_data and whatever else is useful to handle the routing. Fortunately kit is well factored. Hopefully it will work out.

@jzillmann
Copy link
Author

Oh, I guess i just do customized routing, nothing special there!

@maximedupre
Copy link

This issue is essential for Electron apps, which use the filesystem.

All the links and scripts in the page are absolute, so it doesn't work.

@btakita
Copy link

btakita commented Jul 28, 2021

Just a heads-up. I'm working on a fork of Sapper to support file:// hash-based routing. My project needs to continue supporting sapper until some SSR issues are fixed (vitejs/vite#4306).

My current work in progress is at https://github.com/btakita/sapper/tree/hbr
I presume that SvelteKit & Sapper have similar routing. I'm using conditionals checking the window.location.origin === 'file://' to use the Hash Based Routing strategy.

I had to attend to some other priorities & will continue with the hbr branch over the next couple of days.

@benmccann benmccann changed the title Build an output that is usable from local disk Build an output that is usable from local disk (file:// URL) Jul 30, 2021
@btakita
Copy link

btakita commented Aug 2, 2021

@benmccann I was able to modify the routing to switch between hash-based routing when the origin is file:// & otherwise the default path-based-routing. https://github.com/btakita/sapper/tree/hbr

When the time comes to migrate my project over to Svelte Kit, I'll work on a PR. The conditionals are spread out in several places in https://github.com/btakita/sapper/blob/hbr/runtime/src/app/router/index.ts & https://github.com/btakita/sapper/blob/hbr/runtime/src/app/goto/index.ts.

I didn't want to do any major refactorings, lest the hbr branch diverge too far from the master branch.

@AlsDevShack

This comment has been minimized.

@TJKoury
Copy link

TJKoury commented Oct 8, 2021

I've tried installing the vite-plugin-singlefile and putting the default config in the svelte.config.js, but the resulting bundle never shows up. I am not familiar with vite.

@easyfrog

This comment has been minimized.

@mattiash
Copy link
Contributor

mattiash commented Feb 9, 2022

After a lot of tinkering I have managed to build a script that can take an html-file generated by adapter-static and inline all javascript in the file. It is very hacky and runs code in the browser to make the imports work, but it works for my use-case which is to build simple html-files with a bit of interactivity in them that I can send in an email without hosting them anywhere. Might be useful as inspiration for someone.

The trickiest part is that the only way I could use import was if the the module was added as a blob to the page. But adding it as a blob generates a new url for the module, which means that all import statements must be rewritten after the blob has been added.

https://github.com/mattiash/svelte-notebook/blob/master/util/inlinejs.cjs

@Rich-Harris Rich-Harris added this to the post-1.0 milestone Mar 4, 2022
@chadian
Copy link

chadian commented Sep 11, 2022

I also came up with a hacky workaround for a similar issue including hash routing, not sure if it's specific to file:/// but as an index.html being loaded from within an extension which I think is treated similarly.

  1. Create an index.html/+page.svelte route that is not prerendered, which is ran when the extension loads the index.html. This index.html route then redirects to the root route via goto('/');
  2. Hash routes are swapped in after route transitions (handleRouteChange with afterNavigate on root +layout.svelte)
  3. On app initialization any initial hash routes are navigated to the correct route (handleInitialHashRoute with onMount on root +layout.svelte) and subsequently replaced with the hash route again.

@MentalGear
Copy link

MentalGear commented Sep 18, 2022

This might what ya all are looking for:
https://github.com/richardtallent/vite-plugin-singlefile

from #2042 (comment) (has example)

@till
Copy link

till commented Jan 20, 2023

I hope this is the correct issue to comment on.

My use-case is similar, even though I don't need it to work standalone with file://.

I am trying to make a my application work within an electron app. For that, I found that if I was not using SvelteKit, I could configure vite with base: './' and it would work as expected. With SvelteKit this currently seems impossible as all paths have to empty or absolute.

When I leave kit.paths.base empty, it won't use what I put in vite either. Seems like the configuration for SvelteKit wins either way.

@benmccann
Copy link
Member

@till it would seem that SvelteKit always sets base to ./ when building the client:

base: ssr ? assets_base(kit) : './',

Is there anything you notice being different in the output between a normal Vite build with ./ and a SvelteKit build?

@till
Copy link

till commented Jan 22, 2023

@benmccann Maybe I am using it wrong, or using not the latest? I just upgraded to a 1.x.

When I set base in vite's config nothing happens, when I leave paths.base empty in SvelteKit's configuration, all paths in the build are / and then my app fails to run.

@till
Copy link

till commented Jan 22, 2023

Hmm, looking at the code, maybe paths.base vs paths.assets?

@benmccann
Copy link
Member

benmccann commented Jan 23, 2023

Links/Includes (from index.html) need to be relative instead of absolute

The file references are relative now:

Screenshot from 2023-01-23 15-36-27

The JS field need to be in IIFE format (since module script imports will raise CORS issues)

Yep. It looks like this is the main blocker:

Screenshot from 2023-01-23 15-36-43

IIFE requires that we have only a single input, so in IIFE mode we would need to tweak that:

manifest_data.nodes.forEach((node) => {

This is highly related to #3882. I'm not entirely sure what will be required to support IIFE beyond that. Probably we should try to use IIFE only on the client.

@till

This comment was marked as off-topic.

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

No branches or pull requests