summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/chatty-planes-bathe.md18
-rw-r--r--examples/framework-svelte/svelte.config.js5
-rw-r--r--packages/astro/src/core/add/index.ts102
-rw-r--r--packages/integrations/svelte/README.md46
-rw-r--r--packages/integrations/svelte/src/index.ts29
5 files changed, 153 insertions, 47 deletions
diff --git a/.changeset/chatty-planes-bathe.md b/.changeset/chatty-planes-bathe.md
new file mode 100644
index 000000000..726c6782f
--- /dev/null
+++ b/.changeset/chatty-planes-bathe.md
@@ -0,0 +1,18 @@
+---
+'@astrojs/svelte': major
+'astro': minor
+---
+
+The fallback Svelte preprocessor will only be applied if a custom `preprocess` option is not passed to the `svelte()` integration option, or in the `svelte.config.js` file.
+
+To support IDE autocompletion, or if you're migrating from `@astrojs/svelte` v1, you can create a `svelte.config.js` file with:
+
+```js
+import { vitePreprocess } from '@astrojs/svelte';
+
+export default {
+ preprocess: vitePreprocess(),
+};
+```
+
+This file will also be generated by `astro add svelte` by default.
diff --git a/examples/framework-svelte/svelte.config.js b/examples/framework-svelte/svelte.config.js
new file mode 100644
index 000000000..cbaee33df
--- /dev/null
+++ b/examples/framework-svelte/svelte.config.js
@@ -0,0 +1,5 @@
+import { vitePreprocess } from '@astrojs/svelte';
+
+export default {
+ preprocess: vitePreprocess(),
+};
diff --git a/packages/astro/src/core/add/index.ts b/packages/astro/src/core/add/index.ts
index fd7d66d15..02e49b754 100644
--- a/packages/astro/src/core/add/index.ts
+++ b/packages/astro/src/core/add/index.ts
@@ -53,6 +53,13 @@ module.exports = {
},
plugins: [],
}\n`;
+const SVELTE_CONFIG_STUB = `\
+import { vitePreprocess } from '@astrojs/svelte';
+
+export default {
+ preprocess: vitePreprocess(),
+};
+`;
const OFFICIAL_ADAPTER_TO_IMPORT_MAP: Record<string, string> = {
netlify: '@astrojs/netlify/functions',
@@ -114,37 +121,30 @@ export default async function add(names: string[], { cwd, flags, logging, teleme
switch (installResult) {
case UpdateResult.updated: {
if (integrations.find((integration) => integration.id === 'tailwind')) {
- const possibleConfigFiles = [
- './tailwind.config.cjs',
- './tailwind.config.mjs',
- './tailwind.config.js',
- ].map((p) => fileURLToPath(new URL(p, root)));
- let alreadyConfigured = false;
- for (const possibleConfigPath of possibleConfigFiles) {
- if (existsSync(possibleConfigPath)) {
- alreadyConfigured = true;
- break;
- }
- }
- if (!alreadyConfigured) {
- info(
- logging,
- null,
- `\n ${magenta(
- `Astro will generate a minimal ${bold('./tailwind.config.cjs')} file.`
- )}\n`
- );
- if (await askToContinue({ flags })) {
- await fs.writeFile(
- fileURLToPath(new URL('./tailwind.config.cjs', root)),
- TAILWIND_CONFIG_STUB,
- { encoding: 'utf-8' }
- );
- debug('add', `Generated default ./tailwind.config.cjs file`);
- }
- } else {
- debug('add', `Using existing Tailwind configuration`);
- }
+ await setupIntegrationConfig({
+ root,
+ logging,
+ flags,
+ integrationName: 'Tailwind',
+ possibleConfigFiles: [
+ './tailwind.config.cjs',
+ './tailwind.config.mjs',
+ './tailwind.config.js',
+ ],
+ defaultConfigFile: './tailwind.config.cjs',
+ defaultConfigContent: TAILWIND_CONFIG_STUB,
+ });
+ }
+ if (integrations.find((integration) => integration.id === 'svelte')) {
+ await setupIntegrationConfig({
+ root,
+ logging,
+ flags,
+ integrationName: 'Svelte',
+ possibleConfigFiles: ['./svelte.config.js', './svelte.config.cjs', './svelte.config.mjs'],
+ defaultConfigFile: './svelte.config.js',
+ defaultConfigContent: SVELTE_CONFIG_STUB,
+ });
}
break;
}
@@ -886,3 +886,43 @@ function getDiffContent(input: string, output: string): string | null {
return diffed;
}
+
+async function setupIntegrationConfig(opts: {
+ root: URL;
+ logging: LogOptions;
+ flags: yargs.Arguments;
+ integrationName: string;
+ possibleConfigFiles: string[];
+ defaultConfigFile: string;
+ defaultConfigContent: string;
+}) {
+ const possibleConfigFiles = opts.possibleConfigFiles.map((p) =>
+ fileURLToPath(new URL(p, opts.root))
+ );
+ let alreadyConfigured = false;
+ for (const possibleConfigPath of possibleConfigFiles) {
+ if (existsSync(possibleConfigPath)) {
+ alreadyConfigured = true;
+ break;
+ }
+ }
+ if (!alreadyConfigured) {
+ info(
+ opts.logging,
+ null,
+ `\n ${magenta(`Astro will generate a minimal ${bold(opts.defaultConfigFile)} file.`)}\n`
+ );
+ if (await askToContinue({ flags: opts.flags })) {
+ await fs.writeFile(
+ fileURLToPath(new URL(opts.defaultConfigFile, opts.root)),
+ opts.defaultConfigContent,
+ {
+ encoding: 'utf-8',
+ }
+ );
+ debug('add', `Generated default ${opts.defaultConfigFile} file`);
+ }
+ } else {
+ debug('add', `Using existing ${opts.integrationName} configuration`);
+ }
+}
diff --git a/packages/integrations/svelte/README.md b/packages/integrations/svelte/README.md
index ab6f5d856..854bded21 100644
--- a/packages/integrations/svelte/README.md
+++ b/packages/integrations/svelte/README.md
@@ -84,18 +84,44 @@ A few of the default options passed to the Svelte compiler are required to build
const defaultOptions = {
emitCss: true,
compilerOptions: { dev: isDev, hydratable: true },
- preprocess: [
- preprocess({
- less: true,
- sass: { renderSync: true },
- scss: { renderSync: true },
- stylus: true,
- typescript: true,
- }),
- ],
+ preprocess: vitePreprocess()
};
```
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.
+Providing your own `preprocess` options **will** override the defaults - make sure to enable the preprocessor flags needed for your project. For example,
+
+```js
+// astro.config.js
+import svelte from '@astrojs/svelte';
+
+export default {
+ integrations: [svelte({ preprocess: [] })],
+};
+```
+
+and
+
+```js
+// svelte.config.js
+export default {
+ preprocess: [],
+};
+```
+
+Will override the default `preprocess` option. You can read the [`vitePreprocess` docs](https://github.com/sveltejs/vite-plugin-svelte/blob/HEAD/docs/preprocess.md) for more information of how it works.
+
+## Intellisense for TypeScript
+
+If you're using a preprocessor like TypeScript or SCSS in your Svelte files, you can create a `svelte.config.js` file with:
+
+```js
+import { vitePreprocess } from '@astrojs/svelte';
+
+export default {
+ preprocess: vitePreprocess(),
+};
+```
+
+So the Svelte IDE extension can correctly parse the Svelte files. This config file is added by default when you run `astro add svelte`.
diff --git a/packages/integrations/svelte/src/index.ts b/packages/integrations/svelte/src/index.ts
index 6bf5bcc4e..7daa9bec5 100644
--- a/packages/integrations/svelte/src/index.ts
+++ b/packages/integrations/svelte/src/index.ts
@@ -2,6 +2,7 @@ import type { Options } from '@sveltejs/vite-plugin-svelte';
import { svelte, vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import type { AstroIntegration, AstroRenderer } from 'astro';
import type { UserConfig } from 'vite';
+import { fileURLToPath } from 'url';
function getRenderer(): AstroRenderer {
return {
@@ -11,16 +12,27 @@ function getRenderer(): AstroRenderer {
};
}
+async function svelteConfigHasPreprocess(root: URL) {
+ const svelteConfigFiles = ['./svelte.config.js', './svelte.config.cjs', './svelte.config.mjs'];
+ for (const file of svelteConfigFiles) {
+ const filePath = fileURLToPath(new URL(file, root));
+ try {
+ const config = (await import(filePath)).default;
+ return !!config.preprocess;
+ } catch {}
+ }
+}
+
type ViteConfigurationArgs = {
isDev: boolean;
options?: Options | OptionsCallback;
+ root: URL;
};
-function getViteConfiguration({ options, isDev }: ViteConfigurationArgs): UserConfig {
+async function getViteConfiguration({ options, isDev, root }: ViteConfigurationArgs): Promise<UserConfig> {
const defaultOptions: Partial<Options> = {
emitCss: true,
compilerOptions: { dev: isDev, hydratable: true },
- preprocess: [vitePreprocess()],
};
// Disable hot mode during the build
@@ -43,11 +55,13 @@ function getViteConfiguration({ options, isDev }: ViteConfigurationArgs): UserCo
// Always use dev and hydratable from defaults
...defaultOptions.compilerOptions,
},
- // Ignore default preprocessor if the user provided their own
- preprocess: options.preprocess ?? defaultOptions.preprocess,
};
}
+ if (!resolvedOptions.preprocess && !(await svelteConfigHasPreprocess(root))) {
+ resolvedOptions.preprocess = vitePreprocess();
+ }
+
return {
optimizeDeps: {
include: ['@astrojs/svelte/client.js'],
@@ -63,15 +77,18 @@ export default function (options?: Options | OptionsCallback): AstroIntegration
name: '@astrojs/svelte',
hooks: {
// Anything that gets returned here is merged into Astro Config
- 'astro:config:setup': ({ command, updateConfig, addRenderer }) => {
+ 'astro:config:setup': async ({ command, updateConfig, addRenderer, config }) => {
addRenderer(getRenderer());
updateConfig({
- vite: getViteConfiguration({
+ vite: await getViteConfiguration({
options,
isDev: command === 'dev',
+ root: config.root,
}),
});
},
},
};
}
+
+export { vitePreprocess };