Skip to content
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

Support custom svelte compiler options in @astrojs/svelte #3181

Merged
merged 6 commits into from
Apr 22, 2022
Merged
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
5 changes: 5 additions & 0 deletions .changeset/strong-dogs-boil.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/svelte': patch
---

`@astrojs/svelte` integration supports custom svelte compiler options
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ import svelte from '@astrojs/svelte';

// https://astro.build/config
export default defineConfig({
integrations: [svelte()],
integrations: [svelte({
extensions: ['.svelte', '.sve']
})],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
export let message: string;
</script>

<div id="svelte-custom-ext">{ message }</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
---
import TypeScript from '../components/TypeScript.svelte'
// Using a custom extension to verify svelte options
// in astro.config.mjs are passed properly to the svelte integration
import Custom from '../components/Custom.sve'
---
<html lang="en">
<head>
Expand All @@ -20,6 +24,7 @@ import TypeScript from '../components/TypeScript.svelte'
<body>
<main>
<TypeScript message="Hello, TypeScript" client:load />
<Custom message="Hello, Custom Extensions" client:idle />
</main>
</body>
</html>
7 changes: 7 additions & 0 deletions packages/astro/test/svelte-component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ describe('Svelte component', () => {

expect($('#svelte-ts').text()).to.equal('Hello, TypeScript');
});

it('Works with custom Svelte config', async () => {
const html = await fixture.readFile('/typescript/index.html');
const $ = cheerio.load(html);

expect($('#svelte-custom-ext').text()).to.equal('Hello, Custom Extensions');
});
});

if (isWindows) return;
Expand Down
28 changes: 28 additions & 0 deletions packages/integrations/svelte/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,31 @@ Also check our [Astro Integration Documentation][astro-integration] for more on

[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/
[astro-ui-frameworks]: https://docs.astro.build/en/core-concepts/framework-components/#using-framework-components

## Options

This integration is powered by `@sveltejs/vite-plugin-svelte`. To customize the Svelte compiler, options can be provided to the integration. See the `@sveltejs/vite-plugin-svelte` [docs](https://github.com/sveltejs/vite-plugin-svelte/blob/HEAD/docs/config.md) for more details.

### Default options

A few of the default options passed to the Svelte compiler are required to build properly for Astro and cannot be overridden.

```js
const defaultOptions = {
emitCss: true,
compilerOptions: { dev: isDev, hydratable: true },
preprocess: [
preprocess({
less: true,
sass: { renderSync: true },
scss: { renderSync: true },
stylus: true,
typescript: true,
}),
],
};
```

The `emitCss`, `compilerOptions.dev`, and `compilerOptions.hydratable` cannot be overridden.

Providing your own `preprocess` options **will** override the defaults - make sure to enable the preprocessor flags needed for your project.
56 changes: 40 additions & 16 deletions packages/integrations/svelte/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { AstroIntegration, AstroRenderer } from 'astro';
import { svelte } from '@sveltejs/vite-plugin-svelte';
import preprocess from 'svelte-preprocess';
import type { Options } from '@sveltejs/vite-plugin-svelte';

function getRenderer(): AstroRenderer {
return {
Expand All @@ -10,38 +11,61 @@ function getRenderer(): AstroRenderer {
};
}

function getViteConfiguration(isDev: boolean) {
function getViteConfiguration(isDev: boolean, options?: Options | OptionsCallback) {
const defaultOptions = {
emitCss: true,
compilerOptions: { dev: isDev, hydratable: true },
preprocess: [
preprocess({
less: true,
sass: { renderSync: true },
scss: { renderSync: true },
stylus: true,
typescript: true,
}),
],
};

let resolvedOptions: Partial<Options>;

if (!options) {
resolvedOptions = defaultOptions;
} else if (typeof options === 'function') {
resolvedOptions = options(defaultOptions);
} else {
resolvedOptions = {
...options,
...defaultOptions,
compilerOptions: {
...options.compilerOptions,
// Always use dev and hydratable from defaults
...defaultOptions.compilerOptions,
},
// Ignore default preprocessor if the user provided their own
preprocess: options.preprocess ?? defaultOptions.preprocess,
};
}

return {
optimizeDeps: {
include: ['@astrojs/svelte/client.js', 'svelte', 'svelte/internal'],
exclude: ['@astrojs/svelte/server.js'],
},
plugins: [
svelte({
emitCss: true,
compilerOptions: { dev: isDev, hydratable: true },
preprocess: [
preprocess({
less: true,
sass: { renderSync: true },
scss: { renderSync: true },
stylus: true,
typescript: true,
}),
],
}),
svelte(resolvedOptions),
],
};
}

export default function (): AstroIntegration {
type OptionsCallback = (defaultOptions: Options) => Options;
export default function (options?: Options | OptionsCallback): AstroIntegration {
return {
name: '@astrojs/svelte',
hooks: {
// Anything that gets returned here is merged into Astro Config
'astro:config:setup': ({ command, updateConfig, addRenderer }) => {
addRenderer(getRenderer());
updateConfig({ vite: getViteConfiguration(command === 'dev') });
updateConfig({ vite: getViteConfiguration(command === 'dev', options) });
},
},
};
Expand Down