Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
5 changes: 5 additions & 0 deletions .changeset/heavy-dots-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': major
---

add support for rolldown-vite in vitePreprocess. Using the typescript preprocessor requires a tsconfig.json with verbatimModuleSyntax enabled, eg @tsconfig/svelte
5 changes: 5 additions & 0 deletions .changeset/huge-lamps-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': minor
---

Add experimental support for rolldown-vite
5 changes: 5 additions & 0 deletions .changeset/hungry-phones-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': minor
---

replace esbuild optimizer with rolldown optimizer if rolldown-vite is used
19 changes: 15 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ jobs:
# baseline test lowest vite and node version
- node: 20.19
os: ubuntu-latest
vite: '6.3.0'
vite: 'baseline'
# future test with rolldown-vite
- node: 24
os: ubuntu-latest
vite: 'rolldown-vite'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -106,9 +110,16 @@ jobs:
cache-dependency-path: '**/pnpm-lock.yaml'
- name: install
run: pnpm install --frozen-lockfile --ignore-scripts
- name: update vite version
if: matrix.vite != 'current'
run: pnpm update -r --no-save vite@${{matrix.vite}}
- name: downgrade vite to baseline
if: matrix.vite == 'baseline'
run: |
pnpm update -r --no-save [email protected]
pnpm ls vite
- name: update vite to rolldown-vite
if: matrix.vite == 'rolldown-vite'
run: |
pnpm update -r --no-save vite@npm:rolldown-vite@latest
pnpm ls rolldown-vite
- name: install playwright chromium
run: pnpm playwright install chromium
- name: run tests
Expand Down
3 changes: 2 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export default [
'packages/playground/big/src/pages/**', // lots of generated files
'packages/*/types/index.d.ts',
'packages/*/types/index.d.ts.map',
'packages/*/CHANGELOG.md'
'packages/*/CHANGELOG.md',
'packages/e2e-tests/**/logs/**'
]
},
...svelteOrgEslintConfig, // contains setup for svelte and typescript
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function writeResolvedConfig() {
};
const dir = path.join(config.root, 'logs', 'resolved-configs');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
fs.mkdirSync(dir, { recursive: true });
}
const filename = path.join(dir, `vite.config.${cmd}${config.build.ssr ? '.ssr' : ''}.json`);
fs.writeFileSync(filename, JSON.stringify(serializableConfig, replacer, '\t'), 'utf-8');
Expand Down
1 change: 1 addition & 0 deletions packages/e2e-tests/kit-node/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
#.env
.env.*
!.env.example
logs
4 changes: 2 additions & 2 deletions packages/e2e-tests/prebundle-svelte-deps/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import preprocess from 'svelte-preprocess';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default {
preprocess: [preprocess()],
preprocess: [vitePreprocess()],
vitePlugin: {
prebundleSvelteLibraries: true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ test('should render App', async () => {
expect(await getText('#foo-title')).toBe('Styles with stylus blub');
expect(await getColor('#foo-title')).toBe('magenta');
expect(await getColor('p.note')).toBe('rgb(255, 62, 0)');
expect(await getText('#enum')).toBe('qoox');
});

test('should not mangle code from esbuild pure annotations', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/e2e-tests/preprocess-with-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "workspace:^",
"@tsconfig/svelte": "^5.0.4",
"sass": "^1.89.1",
"stylus": "^0.64.0",
"svelte": "^5.33.18",
Expand Down
5 changes: 5 additions & 0 deletions packages/e2e-tests/preprocess-with-vite/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import Bar from './Bar.svelte';
export let hello: string;
const world: string = 'world'; // edit world and save to see hmr update
enum Baz {
Qoox = 'qoox'
}
let qoox = Baz.Qoox;
</script>

<h1 class="foo">{hello} {world}</h1>
<p id="app-scss">This is styled with scss using darken fn</p>
<Foo />
<Bar />
<p id="enum">{qoox}</p>

<style lang="scss">
@use 'sass:color';
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-tests/preprocess-with-vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import App from './App.svelte';
import { Hello } from './types.js';
import { type Hello } from './types.ts';
import { mount } from 'svelte';

const hello: Hello = 'Hello';
Expand Down
3 changes: 3 additions & 0 deletions packages/e2e-tests/preprocess-with-vite/src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "@tsconfig/svelte"
}
2 changes: 1 addition & 1 deletion packages/e2e-tests/preprocess-with-vite/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

export default {
preprocess: [vitePreprocess()]
preprocess: [vitePreprocess({ script: true })]
};
8 changes: 4 additions & 4 deletions packages/e2e-tests/scan-deps/__tests__/scan-deps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { describe, expect, it } from 'vitest';
describe('vite import scan', () => {
it('should not fail to discover dependencies exported from script module', async () => {
// vite logs an error if scan fails but continues, so validate no errors logged
expect(
e2eServer.logs.server.err.length,
`unexpected errors:\n${e2eServer.logs.server.err.join('\n')}`
).toBe(0);
const errorLogs = e2eServer.logs.server.err.filter(
(line) => !line.includes('Support for rolldown-vite in vite-plugin-svelte is experimental')
);
expect(errorLogs.length, `unexpected errors:\n${errorLogs.join('\n')}`).toBe(0);
});
it('should work with exports from module context', async () => {
expect(await getText('#svelte5')).toBe('svelte5');
Expand Down
7 changes: 5 additions & 2 deletions packages/e2e-tests/vitestSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,11 @@ beforeAll(
if (fs.existsSync(tempViteCache)) {
await fs.rm(tempViteCache, { force: true, recursive: true });
}

await fs.mkdir(path.join(tempDir, 'logs'));
const logsDir = path.join(tempDir, 'logs');
if (fs.existsSync(logsDir)) {
fs.rmSync(logsDir, { recursive: true, force: true });
}
await fs.mkdir(logsDir);
const customServerScript = path.resolve(path.dirname(testPath), 'serve.js');
const defaultServerScript = path.resolve(e2eTestsRoot, 'e2e-server.js');
const hasCustomServer = fs.existsSync(customServerScript);
Expand Down
12 changes: 12 additions & 0 deletions packages/vite-plugin-svelte/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache.js';
import { loadRaw } from './utils/load-raw.js';
import * as svelteCompiler from 'svelte/compiler';
import { SVELTE_VIRTUAL_STYLE_ID_REGEX } from './utils/constants.js';
import * as vite from 'vite';
// @ts-expect-error rolldownVersion
const { version: viteVersion, rolldownVersion } = vite;

/**
* @param {Partial<import('./public.d.ts').Options>} [inlineOptions]
Expand All @@ -35,6 +38,12 @@ export function svelte(inlineOptions) {
if (process.env.DEBUG != null) {
log.setLevel('debug');
}
if (rolldownVersion) {
log.warn.once(
`!!! Support for rolldown-vite in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!`
);
}

validateInlineOptions(inlineOptions);
const cache = new VitePluginSvelteCache();
// updated in configResolved hook
Expand Down Expand Up @@ -140,6 +149,8 @@ export function svelte(inlineOptions) {
css.meta.vite ??= {};
css.meta.vite.cssScopeTo = [svelteRequest.filename, 'default'];
}
css.moduleType = 'css';

return css;
}
}
Expand Down Expand Up @@ -194,6 +205,7 @@ export function svelte(inlineOptions) {
}
return {
...compileData.compiled.js,
moduleType: 'js',
meta: {
vite: {
lang: compileData.lang
Expand Down
46 changes: 43 additions & 3 deletions packages/vite-plugin-svelte/src/preprocess.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import process from 'node:process';
import { isCSSRequest, preprocessCSS, resolveConfig, transformWithEsbuild } from 'vite';
import * as vite from 'vite';
import { mapToRelative, removeLangSuffix } from './utils/sourcemaps.js';

const {
isCSSRequest,
preprocessCSS,
resolveConfig,
transformWithEsbuild,
//@ts-expect-error rolldown types don't exist
rolldownVersion,
//@ts-expect-error rolldown types don't exist
transformWithOxc
} = vite;
/**
* @typedef {(code: string, filename: string) => Promise<{ code: string; map?: any; deps?: Set<string> }>} CssTransform
*/
Expand All @@ -18,7 +27,7 @@ export function vitePreprocess(opts) {
/** @type {import('svelte/compiler').PreprocessorGroup} */
const preprocessor = { name: 'vite-preprocess' };
if (opts?.script === true) {
preprocessor.script = viteScript().script;
preprocessor.script = rolldownVersion ? viteScriptOxc().script : viteScript().script;
}
if (opts?.style !== false) {
const styleOpts = typeof opts?.style == 'object' ? opts?.style : undefined;
Expand Down Expand Up @@ -57,6 +66,37 @@ function viteScript() {
};
}

/**
* @returns {{ script: import('svelte/compiler').Preprocessor }}
*/
function viteScriptOxc() {
return {
async script({ attributes, content, filename = '' }) {
const lang = /** @type {string} */ (attributes.lang);
if (!supportedScriptLangs.includes(lang)) return;
const { code, map } = await transformWithOxc(content, filename, {
lang,
target: 'esnext'
// TODO, how to pass tsconfig compilerOptions (or not needed as config is loaded for file
/*tsconfigRaw: {
compilerOptions: {
// svelte typescript needs this flag to work with type imports
importsNotUsedAsValues: 'preserve',
preserveValueImports: true
}
}*/
});

mapToRelative(map, filename);

return {
code,
map
};
}
};
}

/**
* @param {import('vite').ResolvedConfig | import('vite').InlineConfig} config
* @returns {{ style: import('svelte/compiler').Preprocessor }}
Expand Down
1 change: 1 addition & 0 deletions packages/vite-plugin-svelte/src/types/compile.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface Code {
map?: any;
dependencies?: any[];
hasGlobal?: boolean;
moduleType?: string; //rolldown-vite
meta?: {
vite?: CustomPluginOptionsVite;
};
Expand Down
Loading
Loading