Skip to content

Commit

Permalink
fix: inline server stylesheets instead of client stylesheets (#13068)
Browse files Browse the repository at this point in the history
fixes #6720

This PR changes the inlined stylesheet from client to server so that the paths for imported assets in the CSS such as fonts are correct when the document first loads. In comparison, the client stylesheet links are relative by default, so they always link to the wrong place
  • Loading branch information
eltigerchino authored Jan 17, 2025
1 parent e541a40 commit 37f72fb
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-days-think.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/kit': patch
---

fix: correctly link to assets inlined by the `inlineStyleThreshold` option
42 changes: 36 additions & 6 deletions packages/kit/src/exports/vite/build/build_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { mkdirp } from '../../../utils/filesystem.js';
import { find_deps, resolve_symlinks } from './utils.js';
import { s } from '../../../utils/misc.js';
import { normalizePath } from 'vite';
import { basename } from 'node:path';

/**
* @param {string} out
Expand All @@ -17,18 +18,47 @@ export function build_server_nodes(out, kit, manifest_data, server_manifest, cli
mkdirp(`${out}/server/nodes`);
mkdirp(`${out}/server/stylesheets`);

/** @type {Map<string, string>} */
const stylesheet_lookup = new Map();

if (css) {
css.forEach((asset) => {
if (asset.source.length < kit.inlineStyleThreshold) {
const index = stylesheet_lookup.size;
const file = `${out}/server/stylesheets/${index}.js`;
/** @type {Set<string>} */
const client_stylesheets = new Set();
for (const key in client_manifest) {
const file = client_manifest[key];
if (file.css?.[0]) {
client_stylesheets.add(file.css[0]);
}
}

/** @type {Map<number, string>} */
const server_stylesheets = new Map();

fs.writeFileSync(file, `// ${asset.fileName}\nexport default ${s(asset.source)};`);
stylesheet_lookup.set(asset.fileName, index);
const component_stylesheet_map = new Map(Object.values(server_manifest).map((file) => [file.src, file.css?.[0]]));

manifest_data.nodes.forEach((node, i) => {
const server_stylesheet = component_stylesheet_map.get(node.component);
if (node.component && server_stylesheet) {
server_stylesheets.set(i, server_stylesheet);
}
});

// ignore dynamically imported stylesheets since we can't inline those
css.filter(asset => client_stylesheets.has(asset.fileName))
.forEach((asset) => {
if (asset.source.length < kit.inlineStyleThreshold) {
const [index] = basename(asset.fileName).split('.');
const server_stylesheet = server_stylesheets.get(+index);
const file = `${out}/server/stylesheets/${index}.js`;

// we need to inline the server stylesheet instead of the client one
// so that asset paths are correct on document load
const source = fs.readFileSync(`${out}/server/${server_stylesheet}`, 'utf-8');

fs.writeFileSync(file, `// ${server_stylesheet}\nexport default ${s(source)};`);
stylesheet_lookup.set(asset.fileName, index);
}
});
}

manifest_data.nodes.forEach((node, i) => {
Expand Down
1 change: 1 addition & 0 deletions packages/kit/test/apps/options/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"test:build": "playwright test"
},
"devDependencies": {
"@fontsource/libre-barcode-128-text": "^5.1.0",
"@sveltejs/kit": "workspace:^",
"@sveltejs/vite-plugin-svelte": "^5.0.1",
"cross-env": "^7.0.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
import '@fontsource/libre-barcode-128-text';
</script>

<p>Hello world!</p>

<style>
p {
font-family: 'Libre Barcode 128 Text', sans-serif;
}
</style>
16 changes: 16 additions & 0 deletions packages/kit/test/apps/options/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,22 @@ if (!process.env.DEV) {
expect(await page.content()).not.toMatch('navigator.serviceWorker');
});
});

test.describe('inlineStyleThreshold', () => {
test('loads asset', async ({ page }) => {
let fontLoaded = false;

page.on('response', (response) => {
if (response.url().endsWith('.woff2') || response.url().endsWith('.woff')) {
fontLoaded = response.ok();
}
});

await page.goto('/path-base/inline-assets');

expect(fontLoaded).toBeTruthy();
});
});
}

test.describe('Vite options', () => {
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 37f72fb

Please sign in to comment.