From 3fcaac47e27e6e7aeff67f7cd69b4f49b88ed27c Mon Sep 17 00:00:00 2001 From: dominikg Date: Mon, 15 May 2023 21:47:25 +0200 Subject: [PATCH 01/10] refactor: move types to .d.ts files in preparation of ts-to-jsdoc --- .eslintrc.js | 6 + .../src/handle-hot-update.ts | 5 +- packages/vite-plugin-svelte/src/index.d.ts | 284 ++++++++++++++++++ packages/vite-plugin-svelte/src/index.ts | 34 +-- .../vite-plugin-svelte/src/plugin-api.d.ts | 11 + .../vite-plugin-svelte/src/preprocess.d.ts | 6 + packages/vite-plugin-svelte/src/preprocess.ts | 8 +- .../src/utils/__tests__/compile.spec.ts | 1 - .../vite-plugin-svelte/src/utils/compile.d.ts | 44 +++ .../vite-plugin-svelte/src/utils/compile.ts | 49 +-- .../src/utils/dependencies.d.ts | 4 + .../src/utils/dependencies.ts | 6 +- .../vite-plugin-svelte/src/utils/error.ts | 3 +- .../vite-plugin-svelte/src/utils/esbuild.ts | 6 +- packages/vite-plugin-svelte/src/utils/id.d.ts | 30 ++ packages/vite-plugin-svelte/src/utils/id.ts | 37 +-- .../vite-plugin-svelte/src/utils/load-raw.ts | 5 +- .../src/utils/load-svelte-config.ts | 5 +- .../vite-plugin-svelte/src/utils/log.d.ts | 18 ++ packages/vite-plugin-svelte/src/utils/log.ts | 22 +- .../vite-plugin-svelte/src/utils/optimizer.ts | 2 +- .../vite-plugin-svelte/src/utils/options.d.ts | 215 +++++++++++++ .../vite-plugin-svelte/src/utils/options.ts | 222 +------------- .../src/utils/preprocess.ts | 3 +- .../src/utils/sourcemaps.d.ts | 5 + .../src/utils/sourcemaps.ts | 6 +- .../src/utils/vite-plugin-svelte-cache.d.ts | 6 + .../src/utils/vite-plugin-svelte-cache.ts | 12 +- .../src/utils/vite-plugin-svelte-stats.d.ts | 36 +++ .../src/utils/vite-plugin-svelte-stats.ts | 39 +-- .../vite-plugin-svelte/src/utils/watch.ts | 3 +- 31 files changed, 710 insertions(+), 423 deletions(-) create mode 100644 packages/vite-plugin-svelte/src/index.d.ts create mode 100644 packages/vite-plugin-svelte/src/plugin-api.d.ts create mode 100644 packages/vite-plugin-svelte/src/preprocess.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/compile.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/dependencies.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/id.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/log.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/options.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/sourcemaps.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/vite-plugin-svelte-cache.d.ts create mode 100644 packages/vite-plugin-svelte/src/utils/vite-plugin-svelte-stats.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index 1f4d25288..2f9ddf025 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -159,6 +159,12 @@ module.exports = { /* required because URL wasn't in node8 */ 'node/no-unsupported-features/node-builtins': 'off' } + }, + { + files: ['**/*.d.ts'], + rules: { + 'no-unused-vars': 'off' + } } ] }; diff --git a/packages/vite-plugin-svelte/src/handle-hot-update.ts b/packages/vite-plugin-svelte/src/handle-hot-update.ts index 650378045..d466c0555 100644 --- a/packages/vite-plugin-svelte/src/handle-hot-update.ts +++ b/packages/vite-plugin-svelte/src/handle-hot-update.ts @@ -1,11 +1,10 @@ import { ModuleNode, HmrContext } from 'vite'; -import { Code, CompileData } from './utils/compile'; import { log, logCompilerWarnings } from './utils/log'; import { SvelteRequest } from './utils/id'; import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache'; -import { ResolvedOptions } from './utils/options'; import { toRollupError } from './utils/error'; - +import type { Code, CompileData } from './utils/compile.d'; +import type { ResolvedOptions } from './utils/options.d'; /** * Vite-specific HMR handling */ diff --git a/packages/vite-plugin-svelte/src/index.d.ts b/packages/vite-plugin-svelte/src/index.d.ts new file mode 100644 index 000000000..e245c06b6 --- /dev/null +++ b/packages/vite-plugin-svelte/src/index.d.ts @@ -0,0 +1,284 @@ +import { InlineConfig, ResolvedConfig, UserConfig, Plugin } from 'vite'; +// eslint-disable-next-line node/no-missing-import +import { CompileOptions, Warning } from 'svelte/types/compiler/interfaces'; +// eslint-disable-next-line node/no-missing-import +export { CompileOptions, Warning } from 'svelte/types/compiler/interfaces'; +// eslint-disable-next-line node/no-missing-import +import { PreprocessorGroup } from 'svelte/types/compiler/preprocess'; +// eslint-disable-next-line node/no-missing-import +export { + MarkupPreprocessor, + Preprocessor, + PreprocessorGroup, + Processed +} from 'svelte/types/compiler/preprocess'; + +interface InspectorOptions { + /** + * define a key combo to toggle inspector, + * @default 'meta-shift' on mac, 'control-shift' on other os + * + * any number of modifiers `control` `shift` `alt` `meta` followed by zero or one regular key, separated by - + * examples: control-shift, control-o, control-alt-s meta-x control-meta + * Some keys have native behavior (e.g. alt-s opens history menu on firefox). + * To avoid conflicts or accidentally typing into inputs, modifier only combinations are recommended. + */ + toggleKeyCombo?: string; + /** + * define keys to select elements with via keyboard + * @default {parent: 'ArrowUp', child: 'ArrowDown', next: 'ArrowRight', prev: 'ArrowLeft' } + * + * improves accessibility and also helps when you want to select elements that do not have a hoverable surface area + * due to tight wrapping + * + * A note for users of screen-readers: + * If you are using arrow keys to navigate the page itself, change the navKeys to avoid conflicts. + * e.g. navKeys: {parent: 'w', prev: 'a', child: 's', next: 'd'} + * + * + * parent: select closest parent + * child: select first child (or grandchild) + * next: next sibling (or parent if no next sibling exists) + * prev: previous sibling (or parent if no prev sibling exists) + */ + navKeys?: { + parent: string; + child: string; + next: string; + prev: string; + }; + /** + * define key to open the editor for the currently selected dom node + * + * @default 'Enter' + */ + openKey?: string; + /** + * inspector is automatically disabled when releasing toggleKeyCombo after holding it for a longpress + * @default true + */ + holdMode?: boolean; + /** + * when to show the toggle button + * @default 'active' + */ + showToggleButton?: 'always' | 'active' | 'never'; + /** + * where to display the toggle button + * @default top-right + */ + toggleButtonPos?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; + /** + * inject custom styles when inspector is active + */ + customStyles?: boolean; + /** + * internal options that are automatically set, not to be set or used by users + */ + __internal?: { + base: string; + }; +} + +type Options = Omit & PluginOptionsInline; +interface PluginOptionsInline extends PluginOptions { + /** + * Path to a svelte config file, either absolute or relative to Vite root + * + * set to `false` to ignore the svelte config file + * + * @see https://vitejs.dev/config/#root + */ + configFile?: string | false; +} +interface PluginOptions { + /** + * A `picomatch` pattern, or array of patterns, which specifies the files the plugin should + * operate on. By default, all svelte files are included. + * + * @see https://github.com/micromatch/picomatch + */ + include?: Arrayable; + /** + * A `picomatch` pattern, or array of patterns, which specifies the files to be ignored by the + * plugin. By default, no files are ignored. + * + * @see https://github.com/micromatch/picomatch + */ + exclude?: Arrayable; + /** + * Emit Svelte styles as virtual CSS files for Vite and other plugins to process + * + * @default true + */ + emitCss?: boolean; + /** + * Enable or disable Hot Module Replacement. + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * DO NOT CUSTOMIZE SVELTE-HMR OPTIONS UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING + * + * YOU HAVE BEEN WARNED + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * Set an object to pass custom options to svelte-hmr + * + * @see https://github.com/rixo/svelte-hmr#options + * @default true for development, always false for production + */ + hot?: + | boolean + | { + injectCss?: boolean; + partialAccept?: boolean; + [key: string]: any; + }; + /** + * Some Vite plugins can contribute additional preprocessors by defining `api.sveltePreprocess`. + * If you don't want to use them, set this to true to ignore them all or use an array of strings + * with plugin names to specify which. + * + * @default false + */ + ignorePluginPreprocessors?: boolean | string[]; + /** + * vite-plugin-svelte automatically handles excluding svelte libraries and reinclusion of their dependencies + * in vite.optimizeDeps. + * + * `disableDependencyReinclusion: true` disables all reinclusions + * `disableDependencyReinclusion: ['foo','bar']` disables reinclusions for dependencies of foo and bar + * + * This should be used for hybrid packages that contain both node and browser dependencies, eg Routify + * + * @default false + */ + disableDependencyReinclusion?: boolean | string[]; + /** + * Enable support for Vite's dependency optimization to prebundle Svelte libraries. + * + * To disable prebundling for a specific library, add it to `optimizeDeps.exclude`. + * + * @default true for dev, false for build + */ + prebundleSvelteLibraries?: boolean; + /** + * toggle/configure Svelte Inspector + * + * @default true + */ + inspector?: InspectorOptions | boolean; + /** + * These options are considered experimental and breaking changes to them can occur in any release + */ + experimental?: ExperimentalOptions; +} +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; + /** + * 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; + /** + * Handles warning emitted from the Svelte compiler + */ + onwarn?: (warning: Warning, defaultHandler?: (warning: Warning) => void) => void; + /** + * Options for vite-plugin-svelte + */ + vitePlugin?: PluginOptions; +} +/** + * These options are considered experimental and breaking changes to them can occur in any release + */ +interface ExperimentalOptions { + /** + * A function to update `compilerOptions` before compilation + * + * `data.filename` - The file to be compiled + * `data.code` - The preprocessed Svelte code + * `data.compileOptions` - The current compiler options + * + * To change part of the compiler options, return an object with the changes you need. + * + * @example + * ``` + * ({ filename, compileOptions }) => { + * // Dynamically set hydration per Svelte file + * if (compileWithHydratable(filename) && !compileOptions.hydratable) { + * return { hydratable: true }; + * } + * } + * ``` + */ + dynamicCompileOptions?: (data: { + filename: string; + code: string; + compileOptions: Partial; + }) => Promise | void> | Partial | void; + /** + * send a websocket message with svelte compiler warnings during dev + * + */ + sendWarningsToBrowser?: boolean; + /** + * disable svelte field resolve warnings + * + * @default false + */ + disableSvelteResolveWarnings?: boolean; +} +type ModuleFormat = NonNullable; +type CssHashGetter = NonNullable; +type Arrayable = T | T[]; + +declare function vitePreprocess(opts?: { + script?: boolean; + style?: boolean | InlineConfig | ResolvedConfig; +}): PreprocessorGroup; + +declare function loadSvelteConfig( + viteConfig?: UserConfig, + inlineOptions?: Partial +): Promise | undefined>; + +type SvelteWarningsMessage = { + id: string; + filename: string; + normalizedFilename: string; + timestamp: number; + warnings: Warning[]; + allWarnings: Warning[]; + rawWarnings: Warning[]; +}; + +declare function svelte(inlineOptions?: Partial): Plugin[]; + +export { + Arrayable, + CssHashGetter, + ModuleFormat, + Options, + PluginOptions, + SvelteOptions, + SvelteWarningsMessage, + loadSvelteConfig, + svelte, + vitePreprocess +}; diff --git a/packages/vite-plugin-svelte/src/index.ts b/packages/vite-plugin-svelte/src/index.ts index fe4e9b29b..5941a3910 100644 --- a/packages/vite-plugin-svelte/src/index.ts +++ b/packages/vite-plugin-svelte/src/index.ts @@ -12,13 +12,13 @@ import { import { isDepExcluded } from 'vitefu'; import { handleHotUpdate } from './handle-hot-update'; import { log, logCompilerWarnings } from './utils/log'; -import { type CompileSvelte, createCompileSvelte } from './utils/compile'; +import { createCompileSvelte } from './utils/compile'; +import { type CompileSvelte } from './utils/compile.d'; import { buildIdParser, IdParser } from './utils/id'; +import type { ResolvedOptions, Options } from './utils/options.d'; import { buildExtraViteConfig, validateInlineOptions, - Options, - ResolvedOptions, resolveOptions, patchResolvedViteConfig, preResolveOptions @@ -33,16 +33,7 @@ import { svelteInspector } from './ui/inspector/plugin'; import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache'; import { loadRaw } from './utils/load-raw'; import { FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE } from './utils/constants'; - -interface PluginAPI { - /** - * must not be modified, should not be used outside of vite-plugin-svelte repo - * @internal - * @experimental - */ - options?: ResolvedOptions; - // TODO expose compile cache here so other utility plugins can use it -} +import type { PluginAPI } from './plugin-api.d'; const isVite4_0 = viteVersion.startsWith('4.0'); const isSvelte3 = svelteVersion.startsWith('3'); @@ -281,20 +272,3 @@ export function svelte(inlineOptions?: Partial): Plugin[] { export { vitePreprocess } from './preprocess'; export { loadSvelteConfig } from './utils/load-svelte-config'; - -export { - Options, - PluginOptions, - SvelteOptions, - Preprocessor, - PreprocessorGroup, - CompileOptions, - CssHashGetter, - Arrayable, - MarkupPreprocessor, - ModuleFormat, - Processed, - Warning -} from './utils/options'; - -export { SvelteWarningsMessage } from './utils/log'; diff --git a/packages/vite-plugin-svelte/src/plugin-api.d.ts b/packages/vite-plugin-svelte/src/plugin-api.d.ts new file mode 100644 index 000000000..d490951da --- /dev/null +++ b/packages/vite-plugin-svelte/src/plugin-api.d.ts @@ -0,0 +1,11 @@ +import { ResolvedOptions } from './utils/options.d'; + +interface PluginAPI { + /** + * must not be modified, should not be used outside of vite-plugin-svelte repo + * @internal + * @experimental + */ + options?: ResolvedOptions; + // TODO expose compile cache here so other utility plugins can use it +} diff --git a/packages/vite-plugin-svelte/src/preprocess.d.ts b/packages/vite-plugin-svelte/src/preprocess.d.ts new file mode 100644 index 000000000..76d1a61fe --- /dev/null +++ b/packages/vite-plugin-svelte/src/preprocess.d.ts @@ -0,0 +1,6 @@ +export type CssTransform = ( + // eslint-disable-next-line no-unused-vars + code: string, + // eslint-disable-next-line no-unused-vars + filename: string +) => Promise<{ code: string; map?: any; deps?: Set }>; diff --git a/packages/vite-plugin-svelte/src/preprocess.ts b/packages/vite-plugin-svelte/src/preprocess.ts index 7beb1789b..4756d4432 100644 --- a/packages/vite-plugin-svelte/src/preprocess.ts +++ b/packages/vite-plugin-svelte/src/preprocess.ts @@ -3,6 +3,7 @@ import type { ESBuildOptions, InlineConfig, ResolvedConfig } from 'vite'; // eslint-disable-next-line node/no-missing-import import type { Preprocessor, PreprocessorGroup } from 'svelte/types/compiler/preprocess'; import { mapToRelative, removeLangSuffix } from './utils/sourcemaps'; +import type { CssTransform } from './preprocess.d'; const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss']; const supportedScriptLangs = ['ts']; @@ -91,13 +92,6 @@ function viteStyle(config: InlineConfig | ResolvedConfig = {}): { return { style }; } -type CssTransform = ( - // eslint-disable-next-line no-unused-vars - code: string, - // eslint-disable-next-line no-unused-vars - filename: string -) => Promise<{ code: string; map?: any; deps?: Set }>; - function getCssTransformFn(config: ResolvedConfig): CssTransform { return async (code, filename) => { return preprocessCSS(code, filename, config); diff --git a/packages/vite-plugin-svelte/src/utils/__tests__/compile.spec.ts b/packages/vite-plugin-svelte/src/utils/__tests__/compile.spec.ts index 13a145bce..dbceb548a 100644 --- a/packages/vite-plugin-svelte/src/utils/__tests__/compile.spec.ts +++ b/packages/vite-plugin-svelte/src/utils/__tests__/compile.spec.ts @@ -1,6 +1,5 @@ import { describe, it, expect } from 'vitest'; import { createCompileSvelte } from '../compile'; -import { ResolvedOptions } from '../options'; const options: ResolvedOptions = { compilerOptions: { dev: false, diff --git a/packages/vite-plugin-svelte/src/utils/compile.d.ts b/packages/vite-plugin-svelte/src/utils/compile.d.ts new file mode 100644 index 000000000..75a33f5f3 --- /dev/null +++ b/packages/vite-plugin-svelte/src/utils/compile.d.ts @@ -0,0 +1,44 @@ +// eslint-disable-next-line node/no-missing-import +import type { Processed } from 'svelte/types/compiler/preprocess'; +import { _createCompileSvelte } from './compile'; + +export type CompileSvelte = ReturnType; + +export interface Code { + code: string; + map?: any; + dependencies?: any[]; +} + +export interface Compiled { + js: Code; + css: Code; + ast: any; // TODO type + warnings: any[]; // TODO type + vars: { + name: string; + export_name: string; + injected: boolean; + module: boolean; + mutated: boolean; + reassigned: boolean; + referenced: boolean; + writable: boolean; + referenced_from_script: boolean; + }[]; + stats: { + timings: { + total: number; + }; + }; +} + +export interface CompileData { + filename: string; + normalizedFilename: string; + lang: string; + compiled: Compiled; + ssr: boolean | undefined; + dependencies: string[]; + preprocessed: Processed; +} diff --git a/packages/vite-plugin-svelte/src/utils/compile.ts b/packages/vite-plugin-svelte/src/utils/compile.ts index a094f18d1..ffaaa3dcb 100644 --- a/packages/vite-plugin-svelte/src/utils/compile.ts +++ b/packages/vite-plugin-svelte/src/utils/compile.ts @@ -1,21 +1,19 @@ -import { CompileOptions, ResolvedOptions } from './options'; +import { CompileOptions, ResolvedOptions } from './options.d'; import { compile, preprocess, walk } from 'svelte/compiler'; // @ts-ignore import { createMakeHot } from 'svelte-hmr'; import { SvelteRequest } from './id'; import { safeBase64Hash } from './hash'; import { log } from './log'; -import { StatCollection } from './vite-plugin-svelte-stats'; //eslint-disable-next-line node/no-missing-import -import type { Processed } from 'svelte/types/compiler/preprocess'; import { createInjectScopeEverythingRulePreprocessorGroup } from './preprocess'; import { mapToRelative } from './sourcemaps'; +import type { CompileData } from './compile.d'; +import type { StatCollection } from './vite-plugin-svelte-stats.d'; const scriptLangRE = /