sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.11k stars 1.84k forks source link

adapter-static SPA build output includes server / ssr css files #9161

Open alcroito opened 1 year ago

alcroito commented 1 year ago

Describe the bug

Hi,

Building an SPA using svelte kit, adapter-static, ssr = false, csr = true, prerender == false, results in both the server / ssr .css and client-side .css files to be written to build/_app/immutable/assets/.

I would expect the server css not to be there, given the intention of creating an SPA.

This effectively doubles the amount of CSS that will be embedded into the resources of a non-nodejs binary (e.g golang/rust binary) that serves the SPA files.

It would be great if the server files are not written to the build folder, to avoid removing them after each build either manually or with some post-processing step.

Reproduction

Create skeleton project using npm create svelte@latest demo

Modify svelte.config.js

const config = {
    preprocess: vitePreprocess(),

    kit: {
        adapter: adapter({
            fallback: 'index.html',
        }),
        prerender: { entries: [] }
    },
};

Create +layout.ts with contents

export const csr = true;
export const prerender = false;
export const ssr = false;

+layout.svelte contents

<script>
    import './styles.css';
</script>

<div class="app">
    <main>
        <slot />
    </main>
</div>

styles.css

.big {
    background: red;
}

run npm run build

Logs

$ npm run build

> demo@0.0.1 build
> vite build

vite v4.1.4 building SSR bundle for production...
✓ 49 modules transformed.
1:20:45 AM [vite-plugin-svelte] ssr compile done.
package files     time     avg
demo        4   59.0ms  14.7ms

vite v4.1.4 building for production...
✓ 41 modules transformed.
1:20:47 AM [vite-plugin-svelte] dom compile done.
package files     time     avg
demo        4   89.2ms  22.3ms
.svelte-kit/output/client/_app/version.json                                  0.03 kB
.svelte-kit/output/client/vite-manifest.json                                 3.08 kB
.svelte-kit/output/client/_app/immutable/assets/_layout.8fefa65b.css         0.02 kB │ gzip: 0.04 kB
.svelte-kit/output/client/_app/immutable/chunks/2.660d8454.mjs               0.09 kB │ gzip: 0.10 kB
.svelte-kit/output/client/_app/immutable/chunks/1.bbc01385.mjs               0.09 kB │ gzip: 0.10 kB
.svelte-kit/output/client/_app/immutable/entry/_layout.ts.6744c59a.mjs       0.11 kB │ gzip: 0.11 kB
.svelte-kit/output/client/_app/immutable/chunks/0.8c22fd86.mjs               0.15 kB │ gzip: 0.13 kB
.svelte-kit/output/client/_app/immutable/chunks/_layout.ddbe664b.mjs         0.17 kB │ gzip: 0.16 kB
.svelte-kit/output/client/_app/immutable/entry/_layout.svelte.7505ed48.mjs   0.78 kB │ gzip: 0.51 kB
.svelte-kit/output/client/_app/immutable/entry/_page.svelte.04349828.mjs     0.83 kB │ gzip: 0.48 kB
.svelte-kit/output/client/_app/immutable/entry/error.svelte.300f37cf.mjs     0.98 kB │ gzip: 0.57 kB
.svelte-kit/output/client/_app/immutable/chunks/singletons.06d5b64e.mjs      2.54 kB │ gzip: 1.34 kB
.svelte-kit/output/client/_app/immutable/entry/app.e0181355.mjs              5.65 kB │ gzip: 2.26 kB
.svelte-kit/output/client/_app/immutable/chunks/index.415c7875.mjs           6.93 kB │ gzip: 2.81 kB
.svelte-kit/output/client/_app/immutable/entry/start.a6273241.mjs           23.11 kB │ gzip: 9.19 kB
.svelte-kit/output/server/vite-manifest.json                           1.56 kB
.svelte-kit/output/server/_app/immutable/assets/_layout.ef83e8df.css   0.03 kB
.svelte-kit/output/server/entries/pages/_layout.ts.js                  0.10 kB
.svelte-kit/output/server/internal.js                                  0.19 kB
.svelte-kit/output/server/entries/pages/_layout.svelte.js              0.30 kB
.svelte-kit/output/server/entries/pages/_page.svelte.js                0.32 kB
.svelte-kit/output/server/entries/fallbacks/error.svelte.js            0.83 kB
.svelte-kit/output/server/chunks/index.js                              3.29 kB
.svelte-kit/output/server/chunks/internal.js                           4.92 kB
.svelte-kit/output/server/index.js                                    83.91 kB

Run npm run preview to preview your production build locally.

> Using @sveltejs/adapter-static
  Wrote site to "build"
  ✔ done

$ ls build/_app/immutable/assets/
_layout.8fefa65b.css _layout.ef83e8df.css

System Info

Binaries:
    Node: 18.14.1 - /usr/local/bin/node
    npm: 9.3.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 107.0.5304.87
  npmPackages:
    @sveltejs/adapter-auto: ^2.0.0 => 2.0.0
    @sveltejs/adapter-static: next => 1.0.0-next.50
    @sveltejs/kit: ^1.5.0 => 1.8.3
    svelte: ^3.54.0 => 3.55.1
    vite: ^4.0.0 => 4.1.4

Severity

annoyance

Additional Information

No response

eltigerchino commented 1 year ago

Related to https://github.com/sveltejs/kit/pull/9073 . Perhaps we need some way to tell the builder to only copy client assets, rather than copying both over. In some cases the double CSS output is also caused by Vite not minifying the server CSS, using a different hash name for the same file, creating a duplicate. But sometimes, the CSS content really is different and will result in two files being copied over (with the server one unused).

kindoflew commented 1 year ago

i'm currently running into the same issue.

is the only current workaround to manually remove the SSR files? and if that's the case, how can I tell which output is SSR and which is client? at first, i thought there was probably no difference, but @s3812497 's comment seems to suggest there are cases where there are actually two different CSS files generated?

the only difference in my case is that mine isn't a SPA -- i'm just trying to build a single, static page (so i'm exporting prerender = true and ssr = false from +layout.ts)

it also seems like there are two layout files generated in build/_app/immutable/entry -- one has minified code and the other just exports stuff from ../chunks/_layout.{HASH}.js. That might be normal though -- not exactly sure what the build directory is supposed to look like with adapter-static.

eltigerchino commented 1 year ago

You can try adding the config option below and see if it helps. This should reduce the duplicate CSS files until #9382 or otherwise is merged

// svelte.config.js
export const config = {
  kit: {
    build: {
      minify: 'esbuild'
    }
  }
}
eltigerchino commented 1 year ago

With the duplicate CSS issue fixed in https://github.com/sveltejs/kit/pull/9382 Should we have an adapter level option to include/exclude server/client assets? Instead of bundling both together where the server ones aren't used(?) by the static adapter. https://github.com/sveltejs/kit/blob/9aded818a33b42ce7f10fac48db00950d3e02928/packages/kit/src/core/adapt/builder.js#L185-L192

benmccann commented 1 year ago

How do we end up with different server/client CSS now that https://github.com/sveltejs/kit/pull/9382 has been merged?

eltigerchino commented 1 year ago

How do we end up with different server/client CSS now that #9382 has been merged?

The URL paths in the CSS are resolved differently for server and client (absolute vs relative).

This can be reproduced by building the demo app. https://stackblitz.com/edit/sveltejs-kit-template-default-zahkqv?file=build/_app/immutable/assets/_layout.fa9427ff.css In the resulting build/_app/immutable/assets folder, there will be two different layout CSS assets because of their URL path differences.

niemyjski commented 10 months ago

I'm also wondering this. I just want client files created.

skiv71 commented 10 months ago

So, this is closed (and I found the same problem, so posted a duplicate bug, with quite some effort put into it).

Is this not gonna be fixed? I mean, I'm singing svelte praises compared to other UI systems, but other devs are bound to call this out

Sofahamster commented 1 month ago

I just stumbled upon this issue. Any update on when this will be fixed? Is there any known workaround? (I tried upgrading to svelte 5 preview, but the issue persists.)