Skip to content

refactor: move plugin options to "vitePlugin" in svelte.config.js #389

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

Merged
merged 7 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
19 changes: 19 additions & 0 deletions .changeset/healthy-worms-double.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@sveltejs/vite-plugin-svelte': major
---

move plugin options in svelte.config.js into "vitePlugin"

update your svelte.config.js and wrap [plugin options](https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#plugin-options) with `vitePlugin`

```diff
// svelte.config.js

compilerOptions:{...},
preprocess:{...},
extensions:[...],
kit:{},
+ vitePlugin: {
// include, exclude, emitCss, onwarn, hot, ignorePluginPreprocessors, disableDependencyReinclusion, experimental
+ }
```
33 changes: 29 additions & 4 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
`vite-plugin-svelte` accepts inline options that can be used to change its behaviour. An object can be passed to the first argument of the `svelte` plugin:

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand All @@ -18,7 +19,7 @@ Explore the various options below!

### Config file resolving

Besides inline options, `vite-plugin-svelte` will also automatically resolve options from a Svelte config file if one exists. The default search paths are:
Besides inline options in Vite config, `vite-plugin-svelte` will also automatically resolve options from a Svelte config file if one exists. The default search paths are:

- `svelte.config.js`
- `svelte.config.mjs`
Expand All @@ -27,6 +28,7 @@ Besides inline options, `vite-plugin-svelte` will also automatically resolve opt
To set a specific config file, use the `configFile` inline option. The path can be absolute or relative to the [Vite root](https://vitejs.dev/config/#root). For example:

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand All @@ -42,12 +44,15 @@ A basic Svelte config looks like this:
// svelte.config.js
export default {
// svelte options
extensions: ['.svelte'],
compilerOptions: {},
preprocess: [],
// plugin options
onwarn: (warning, handler) => handler(warning),
// experimental options
experimental: {}
vitePlugin: {
onwarn: (warning, handler) => handler(warning),
// experimental options
experimental: {}
}
};
```

Expand All @@ -65,6 +70,7 @@ Depending on Node's mode, make sure you're using the correct extension and synta
Use `configFile: false` to prevent `vite-plugin-svelte` from reading the config file or restarting the Vite dev server when it changes.

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand Down Expand Up @@ -98,6 +104,7 @@ These options are specific to the Svelte compiler and are generally shared acros
**Example:**

```js
// vite.config.js
import sveltePreprocess from 'svelte-preprocess';

export default defineConfig({
Expand Down Expand Up @@ -197,7 +204,10 @@ A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patt

These options are considered experimental and breaking changes to them can occur in any release! Specify them under the `experimental` option.

Either in Vite config

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand All @@ -209,6 +219,19 @@ export default defineConfig({
});
```

or in svelte config

```js
// svelte.config.js
export default {
vitePlugin: {
experimental: {
// experimental options
}
}
};
```

### useVitePreprocess

- **Type:** `boolean`
Expand Down Expand Up @@ -247,6 +270,7 @@ export default defineConfig({
**Example:**

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand Down Expand Up @@ -321,6 +345,7 @@ export default defineConfig({
**Example:**

```js
// vite.config.js
export default defineConfig({
plugins: [
svelte({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
console.log('custom svelte config loaded cjs')
module.exports = {
emitCss: false
vitePlugin:{
emitCss: false
}
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
console.log('custom svelte config loaded mjs')
export default {
emitCss: false
vitePlugin:{
emitCss: false
}
}
2 changes: 1 addition & 1 deletion packages/e2e-tests/hmr/__tests__/hmr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ if (!isBuild) {
});

test('should work with emitCss: false in svelte config', async () => {
addFile('svelte.config.cjs', `module.exports={emitCss:false}`);
addFile('svelte.config.cjs', `module.exports={vitePlugin:{emitCss:false}}`);
await sleep(isWin ? 1000 : 500); // adding config restarts server, give it some time
await page.goto(viteTestUrl, { waitUntil: 'networkidle' });
await sleep(50);
Expand Down
8 changes: 5 additions & 3 deletions packages/e2e-tests/inspector-kit/svelte.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {},
experimental: {
inspector: {
showToggleButton: 'always'
vitePlugin: {
experimental: {
inspector: {
showToggleButton: 'always'
}
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions packages/vite-plugin-svelte/src/utils/load-svelte-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import fs from 'fs';
import { pathToFileURL } from 'url';
import { log } from './log';
import { Options } from './options';
import { Options, SvelteOptions } from './options';
import { UserConfig } from 'vite';

// used to require cjs config in esm.
Expand All @@ -29,7 +29,7 @@ const dynamicImportDefault = new Function(
export async function loadSvelteConfig(
viteConfig?: UserConfig,
inlineOptions?: Partial<Options>
): Promise<Partial<Options> | undefined> {
): Promise<Partial<SvelteOptions> | undefined> {
if (inlineOptions?.configFile === false) {
return;
}
Expand Down
149 changes: 115 additions & 34 deletions packages/vite-plugin-svelte/src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,94 @@ import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild';
import { addExtraPreprocessors } from './preprocess';
import deepmerge from 'deepmerge';

const knownOptions = new Set([
'configFile',
const allowedPluginOptions = new Set([
'include',
'exclude',
'extensions',
'emitCss',
'compilerOptions',
'onwarn',
'preprocess',
'hot',
'ignorePluginPreprocessors',
'disableDependencyReinclusion',
'experimental',
'kit'
'experimental'
]);

const knownRootOptions = new Set(['extensions', 'compilerOptions', 'preprocess']);

const allowedInlineOptions = new Set([
'configFile',
'kit', // only for internal use by sveltekit
...allowedPluginOptions,
...knownRootOptions
]);

export function validateInlineOptions(inlineOptions?: Partial<Options>) {
const invalidKeys = Object.keys(inlineOptions || {}).filter((key) => !knownOptions.has(key));
const invalidKeys = Object.keys(inlineOptions || {}).filter(
(key) => !allowedInlineOptions.has(key)
);
if (invalidKeys.length) {
log.warn(`invalid plugin options "${invalidKeys.join(', ')}" in config`, inlineOptions);
log.warn(`invalid plugin options "${invalidKeys.join(', ')}" in inline config`, inlineOptions);
}
}

function convertPluginOptions(config?: Partial<SvelteOptions>): Partial<Options> | undefined {
if (!config) {
return;
}
const invalidRootOptions = Object.keys(config).filter((key) => allowedPluginOptions.has(key));
if (invalidRootOptions.length > 0) {
throw new Error(
`Invalid options in svelte config. Move the following options into 'vitePlugin:{...}': ${invalidRootOptions.join(
', '
)}`
);
}
if (!config.vitePlugin) {
return config;
}
const pluginOptions = config.vitePlugin;
const pluginOptionKeys = Object.keys(pluginOptions);

const rootOptionsInPluginOptions = pluginOptionKeys.filter((key) => knownRootOptions.has(key));
if (rootOptionsInPluginOptions.length > 0) {
throw new Error(
`Invalid options in svelte config under vitePlugin:{...}', move them to the config root : ${rootOptionsInPluginOptions.join(
', '
)}`
);
}
const duplicateOptions = pluginOptionKeys.filter((key) =>
Object.prototype.hasOwnProperty.call(config, key)
);
if (duplicateOptions.length > 0) {
throw new Error(
`Invalid duplicate options in svelte config under vitePlugin:{...}', they are defined in root too and must only exist once: ${duplicateOptions.join(
', '
)}`
);
}
const unknownPluginOptions = pluginOptionKeys.filter((key) => !allowedPluginOptions.has(key));
if (unknownPluginOptions.length > 0) {
log.warn(
`ignoring unknown plugin options in svelte config under vitePlugin:{...}: ${unknownPluginOptions.join(
', '
)}`
);
unknownPluginOptions.forEach((unkownOption) => {
// @ts-ignore
delete pluginOptions[unkownOption];
});
}

const result: Options = {
...config,
...pluginOptions
};
// @ts-expect-error it exists
delete result.vitePlugin;

return result;
}

// used in config phase, merges the default options, svelte config, and inline options
export async function preResolveOptions(
inlineOptions: Partial<Options> = {},
Expand All @@ -65,7 +130,10 @@ export async function preResolveOptions(
extensions: ['.svelte'],
emitCss: true
};
const svelteConfig = await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions);
const svelteConfig = convertPluginOptions(
await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)
);

const extraOptions: Partial<PreResolvedOptions> = {
root: viteConfigWithResolvedRoot.root!,
isBuild: viteEnv.command === 'build',
Expand Down Expand Up @@ -390,7 +458,10 @@ export function patchResolvedViteConfig(viteConfig: ResolvedConfig, options: Res
Object.assign(facadeEsbuildSveltePlugin, esbuildSveltePlugin(options));
}
}
export interface Options {

export type Options = Omit<SvelteOptions & PluginOptions, 'vitePlugin'>;

export interface PluginOptions {
/**
* Path to a svelte config file, either absolute or relative to Vite root
*
Expand All @@ -416,36 +487,13 @@ export interface Options {
*/
exclude?: Arrayable<string>;

/**
* A list of file extensions to be compiled by Svelte
*
* @default ['.svelte']
*/
extensions?: string[];

/**
* An array of preprocessors to transform the Svelte source code before compilation
*
* @see https://svelte.dev/docs#svelte_preprocess
*/
preprocess?: Arrayable<PreprocessorGroup>;

/**
* Emit Svelte styles as virtual CSS files for Vite and other plugins to process
*
* @default true
*/
emitCss?: boolean;

/**
* The options to be passed to the Svelte compiler. A few options are set by default,
* including `dev` and `css`. However, some options are non-configurable, like
* `filename`, `format`, `generate`, and `cssHash` (in dev).
*
* @see https://svelte.dev/docs#svelte_compile
*/
compilerOptions?: Omit<CompileOptions, 'filename' | 'format' | 'generate'>;

/**
* Handles warning emitted from the Svelte compiler
*/
Expand Down Expand Up @@ -495,11 +543,44 @@ export interface Options {
* These options are considered experimental and breaking changes to them can occur in any release
*/
experimental?: ExperimentalOptions;
}

export interface SvelteOptions {
/**
* A list of file extensions to be compiled by Svelte
*
* @default ['.svelte']
*/
extensions?: string[];

/**
* An array of preprocessors to transform the Svelte source code before compilation
*
* @see https://svelte.dev/docs#svelte_preprocess
*/
preprocess?: Arrayable<PreprocessorGroup>;

/**
* The options to be passed to the Svelte compiler. A few options are set by default,
* including `dev` and `css`. However, some options are non-configurable, like
* `filename`, `format`, `generate`, and `cssHash` (in dev).
*
* @see https://svelte.dev/docs#svelte_compile
*/
compilerOptions?: Omit<CompileOptions, 'filename' | 'format' | 'generate'>;

/**
* Options for SvelteKit
* @internal
*
* users should always use svelte.config.js or kit() in vite.config.js to set this
*/
kit?: KitConfig;

/**
* Options for vite-plugin-svelte
*/
vitePlugin?: Options;
}

/**
Expand Down