Skip to content

feat: support Rolldown #13747

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

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
},
"devDependencies": {
"@changesets/cli": "^2.27.11",
"@playwright/test": "catalog:",
"@sveltejs/eslint-config": "^8.1.0",
"@svitejs/changesets-changelog-github-compact": "^1.1.0",
"eslint": "^9.6.0",
"@playwright/test": "catalog:",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"typescript-eslint": "^8.24.0"
Expand All @@ -36,8 +36,12 @@
"pnpm": ">=9.0.0"
},
"pnpm": {
"overrides": {
"vite": "npm:rolldown-vite@latest"
},
"onlyBuiltDependencies": [
"esbuild",
"rolldown",
"sharp",
"svelte-preprocess",
"workerd"
Expand Down
2 changes: 1 addition & 1 deletion packages/enhanced-img/src/vite-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export function image_plugin(imagetools_plugin) {

/**
* @param {string} resolved_id
* @param {import('vite').Rollup.PluginContext} plugin_context
* @param {import('vite').Rolldown.PluginContext} plugin_context
* @param {import('vite').Plugin} imagetools_plugin
* @returns {Promise<import('vite-imagetools').Picture>}
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/enhanced-img/test/markup-plugin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ it('Image preprocess snapshot test', async () => {
throw new Error(`unrecognized id ${id}`);
}
});
const plugin_context = /** @type {import('rollup').TransformPluginContext} */ (
const plugin_context = /** @type {import('vite').Rolldown.TransformPluginContext} */ (
/** @type {unknown} */ ({
// @ts-ignore
resolve(url) {
Expand All @@ -27,7 +27,7 @@ it('Image preprocess snapshot test', async () => {
})
);
const transform =
/** @type {(this: import('rollup').TransformPluginContext, code: string, id: string, options?: {ssr?: boolean;}) => Promise<import('rollup').TransformResult>} */ (
/** @type {(this: import('vite').Rolldown.TransformPluginContext, code: string, id: string, options?: {ssr?: boolean;}) => Promise<import('rollup').TransformResult>} */ (
vite_plugin.transform
);
const transformed = await transform.call(
Expand Down
6 changes: 4 additions & 2 deletions packages/kit/src/exports/vite/build/build_service_worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export async function build_service_worker(
},
output: {
// .mjs so that esbuild doesn't incorrectly inject `export` https://github.com/vitejs/vite/issues/15379
entryFileNames: 'service-worker.mjs',
entryFileNames: `service-worker.${vite.rolldownVersion ? 'js' : 'mjs'}`,
assetFileNames: `${kit.appDir}/immutable/assets/[name].[hash][extname]`,
inlineDynamicImports: true
}
Expand All @@ -129,5 +129,7 @@ export async function build_service_worker(
});

// rename .mjs to .js to avoid incorrect MIME types with ancient webservers
fs.renameSync(`${out}/client/service-worker.mjs`, `${out}/client/service-worker.js`);
if (!vite.rolldownVersion) {
fs.renameSync(`${out}/client/service-worker.mjs`, `${out}/client/service-worker.js`);
}
}
1 change: 0 additions & 1 deletion packages/kit/src/exports/vite/graph_analysis/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import * as module_ids from '../module_ids.js';
* @param {string} [expected_error]
*/
function check(graph, expected_error) {
// @ts-expect-error
const context = /** @type {import('vite').Rollup.PluginContext} */ ({
/** @param {string} id */
getModuleInfo(id) {
Expand Down
42 changes: 34 additions & 8 deletions packages/kit/src/exports/vite/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ let manifest_data;
* @return {Promise<import('vite').Plugin[]>}
*/
async function kit({ svelte_config }) {
/** @type {import('vite')} */
const vite = await resolve_peer_dependency('vite');

const { kit } = svelte_config;
Expand Down Expand Up @@ -675,13 +676,12 @@ Tips:
assetFileNames: `${prefix}/assets/[name].[hash][extname]`,
hoistTransitiveImports: false,
sourcemapIgnoreList,
manualChunks: split ? undefined : () => 'bundle',
inlineDynamicImports: false
},
preserveEntrySignatures: 'strict',
onwarn(warning, handler) {
if (
warning.code === 'MISSING_EXPORT' &&
warning.code === 'IMPORT_IS_UNDEFINED' &&
// TODO: rolldown doesn't seem to provide `warning.id` so this condition is never true https://github.com/rolldown/rolldown/issues/4427
warning.id === `${kit.outDir}/generated/client-optimized/app.js`
) {
// ignore e.g. undefined `handleError` hook when
Expand All @@ -706,7 +706,32 @@ Tips:
}
}
}
// TODO: enabling `experimental.enableNativePlugin` causes styles to not be applied
// see https://vite.dev/guide/rolldown#enabling-native-plugins
// experimental: {
// enableNativePlugin: true
// }
};

if (!vite.rolldownVersion) {
// TODO: always set this once `preserveEntrySignatures` is implemented in rolldown
// https://github.com/rolldown/rolldown/issues/3500
// rolldown always does 'strict' in the meantime, so it's fine to only set this in non-rolldown mode
// @ts-ignore
new_config.build.rollupOptions.preserveEntrySignatures = 'strict';
}

if (!split && new_config.build?.rollupOptions?.output) {
const output_options = /** @type {import('vite').Rolldown.OutputOptions} */ (
new_config.build.rollupOptions.output
);
if (vite.rolldownVersion) {
output_options.inlineDynamicImports = true;
} else {
/** @type {import('rollup').OutputOptions} */ (output_options).manualChunks = () =>
'bundle';
}
}
} else {
new_config = {
appType: 'custom',
Expand Down Expand Up @@ -760,7 +785,8 @@ Tips:
renderChunk(code, chunk) {
if (code.includes('__SVELTEKIT_TRACK__')) {
return {
code: code.replace(/__SVELTEKIT_TRACK__\('(.+?)'\)/g, (_, label) => {
// Rolldown changes our single quotes to double quotes so we need it in the regex too
code: code.replace(/__SVELTEKIT_TRACK__\(['"](.+?)['"]\)/g, (_, label) => {
(tracked_features[chunk.name + '.js'] ??= []).push(label);
// put extra whitespace at the end of the comment to preserve the source size and avoid interfering with source maps
return `/* track ${label} */`;
Expand Down Expand Up @@ -852,7 +878,7 @@ Tips:

secondary_build_started = true;

const { output } = /** @type {import('vite').Rollup.RollupOutput} */ (
const { output } = /** @type {import('vite').Rolldown.RolldownOutput} */ (
await vite.build({
configFile: vite_config.configFile,
// CLI args
Expand Down Expand Up @@ -950,7 +976,7 @@ Tips:
};

if (svelte_config.kit.output.bundleStrategy === 'inline') {
const style = /** @type {import('rollup').OutputAsset} */ (
const style = /** @type {import('vite').Rolldown.OutputAsset} */ (
output.find(
(chunk) =>
chunk.type === 'asset' &&
Expand All @@ -967,7 +993,7 @@ Tips:
}

const css = output.filter(
/** @type {(value: any) => value is import('vite').Rollup.OutputAsset} */
/** @type {(value: any) => value is import('vite').Rolldown.OutputAsset} */
(value) => value.type === 'asset' && value.fileName.endsWith('.css')
);

Expand Down Expand Up @@ -1028,7 +1054,7 @@ Tips:
...vite_config,
build: {
...vite_config.build,
minify: initial_config.build?.minify ?? 'esbuild'
minify: initial_config.build?.minify ?? 'oxc'
}
},
manifest_data,
Expand Down
9 changes: 6 additions & 3 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -706,9 +706,12 @@ async function load_node({ loader, parent, url, params, route, server_data_node
: await resource.blob(),
cache: resource.cache,
credentials: resource.credentials,
// the headers are undefined on the server if the Headers object is empty
// so we need to make sure they are also undefined here if there are no headers
headers: [...resource.headers].length ? resource.headers : undefined,
// the server sets headers to `undefined` if there are no headers but
// the client defaults to an empty Headers object in the Request object.
// To keep the two values in sync, we explicitly set the headers to `undefined`.
// Also, not sure why, but sometimes 0 is evaluated as truthy so we need to
// explicitly compare the headers length to a number here
headers: [...resource.headers].length > 0 ? resource?.headers : undefined,
integrity: resource.integrity,
keepalive: resource.keepalive,
method: resource.method,
Expand Down
4 changes: 2 additions & 2 deletions packages/kit/test/apps/basics/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1494,10 +1494,10 @@ test.describe('reroute', () => {
await page.goto('/reroute/external');
const current_url = new URL(page.url());

//click the link with the text External URL
// click the link with the text External URL
await page.click("a[data-test='external-url']");

//The URl should not have the same origin as the current URL
// The URl should not have the same origin as the current URL
const new_url = new URL(page.url());
expect(current_url.origin).not.toEqual(new_url.origin);
});
Expand Down
Loading
Loading