Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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/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
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 })]
};
6 changes: 2 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,8 @@ 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;
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
3 changes: 3 additions & 0 deletions packages/vite-plugin-svelte/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,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 +196,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