feat: docker compose maybe
This commit is contained in:
21
node_modules/@sveltejs/vite-plugin-svelte/LICENSE
generated
vendored
Normal file
21
node_modules/@sveltejs/vite-plugin-svelte/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 [these people](https://github.com/sveltejs/vite-plugin-svelte/graphs/contributors)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
28
node_modules/@sveltejs/vite-plugin-svelte/README.md
generated
vendored
Normal file
28
node_modules/@sveltejs/vite-plugin-svelte/README.md
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
# @sveltejs/vite-plugin-svelte
|
||||
|
||||
The official [Svelte](https://svelte.dev) plugin for [Vite](https://vitejs.dev).
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
// vite.config.js
|
||||
import { defineConfig } from 'vite';
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
svelte({
|
||||
/* plugin options */
|
||||
})
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Plugin options](../../docs/config.md)
|
||||
- [FAQ](../../docs/faq.md)
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE)
|
59
node_modules/@sveltejs/vite-plugin-svelte/package.json
generated
vendored
Normal file
59
node_modules/@sveltejs/vite-plugin-svelte/package.json
generated
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@sveltejs/vite-plugin-svelte",
|
||||
"version": "2.5.2",
|
||||
"license": "MIT",
|
||||
"author": "dominikg",
|
||||
"files": [
|
||||
"src"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "src/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/index.d.ts",
|
||||
"import": "./src/index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >= 16"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sveltejs/vite-plugin-svelte.git",
|
||||
"directory": "packages/vite-plugin-svelte"
|
||||
},
|
||||
"keywords": [
|
||||
"vite-plugin",
|
||||
"vite plugin",
|
||||
"vite",
|
||||
"svelte"
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/sveltejs/vite-plugin-svelte/issues"
|
||||
},
|
||||
"homepage": "https://github.com/sveltejs/vite-plugin-svelte#readme",
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte-inspector": "^1.0.4",
|
||||
"debug": "^4.3.4",
|
||||
"deepmerge": "^4.3.1",
|
||||
"kleur": "^4.1.5",
|
||||
"magic-string": "^0.30.3",
|
||||
"svelte-hmr": "^0.15.3",
|
||||
"vitefu": "^0.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-next.0",
|
||||
"vite": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/debug": "^4.1.8",
|
||||
"esbuild": "^0.19.3",
|
||||
"svelte": "^4.2.0",
|
||||
"vite": "^4.4.9"
|
||||
},
|
||||
"scripts": {
|
||||
"check:publint": "publint --strict",
|
||||
"check:types": "tsc --noEmit"
|
||||
}
|
||||
}
|
133
node_modules/@sveltejs/vite-plugin-svelte/src/handle-hot-update.js
generated
vendored
Normal file
133
node_modules/@sveltejs/vite-plugin-svelte/src/handle-hot-update.js
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
import { log, logCompilerWarnings } from './utils/log.js';
|
||||
import { toRollupError } from './utils/error.js';
|
||||
|
||||
/**
|
||||
* Vite-specific HMR handling
|
||||
*
|
||||
* @param {Function} compileSvelte
|
||||
* @param {import('vite').HmrContext} ctx
|
||||
* @param {import('./types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @param {import('./utils/vite-plugin-svelte-cache').VitePluginSvelteCache} cache
|
||||
* @param {import('./types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {Promise<import('vite').ModuleNode[] | void>}
|
||||
*/
|
||||
export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options) {
|
||||
if (!cache.has(svelteRequest)) {
|
||||
// file hasn't been requested yet (e.g. async component)
|
||||
log.debug(`handleHotUpdate called before initial transform for ${svelteRequest.id}`);
|
||||
return;
|
||||
}
|
||||
const { read, server, modules } = ctx;
|
||||
|
||||
const cachedJS = cache.getJS(svelteRequest);
|
||||
const cachedCss = cache.getCSS(svelteRequest);
|
||||
|
||||
const content = await read();
|
||||
/** @type {import('./types/compile.d.ts').CompileData} */
|
||||
let compileData;
|
||||
try {
|
||||
compileData = await compileSvelte(svelteRequest, content, options);
|
||||
cache.update(compileData);
|
||||
} catch (e) {
|
||||
cache.setError(svelteRequest, e);
|
||||
throw toRollupError(e, options);
|
||||
}
|
||||
|
||||
const affectedModules = [...modules];
|
||||
|
||||
const cssIdx = modules.findIndex((m) => m.id === svelteRequest.cssId);
|
||||
if (cssIdx > -1) {
|
||||
const cssUpdated = cssChanged(cachedCss, compileData.compiled.css);
|
||||
if (!cssUpdated) {
|
||||
log.debug(`skipping unchanged css for ${svelteRequest.cssId}`);
|
||||
affectedModules.splice(cssIdx, 1);
|
||||
}
|
||||
}
|
||||
const jsIdx = modules.findIndex((m) => m.id === svelteRequest.id);
|
||||
if (jsIdx > -1) {
|
||||
const jsUpdated = jsChanged(cachedJS, compileData.compiled.js, svelteRequest.filename);
|
||||
if (!jsUpdated) {
|
||||
log.debug(`skipping unchanged js for ${svelteRequest.id}`);
|
||||
affectedModules.splice(jsIdx, 1);
|
||||
// transform won't be called, log warnings here
|
||||
logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO is this enough? see also: https://github.com/vitejs/vite/issues/2274
|
||||
const ssrModulesToInvalidate = affectedModules.filter((m) => !!m.ssrTransformResult);
|
||||
if (ssrModulesToInvalidate.length > 0) {
|
||||
log.debug(`invalidating modules ${ssrModulesToInvalidate.map((m) => m.id).join(', ')}`);
|
||||
ssrModulesToInvalidate.forEach((moduleNode) => server.moduleGraph.invalidateModule(moduleNode));
|
||||
}
|
||||
if (affectedModules.length > 0) {
|
||||
log.debug(
|
||||
`handleHotUpdate for ${svelteRequest.id} result: ${affectedModules
|
||||
.map((m) => m.id)
|
||||
.join(', ')}`
|
||||
);
|
||||
}
|
||||
return affectedModules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./types/compile.d.ts').Code} [prev]
|
||||
* @param {import('./types/compile.d.ts').Code} [next]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function cssChanged(prev, next) {
|
||||
return !isCodeEqual(prev?.code, next?.code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./types/compile.d.ts').Code} [prev]
|
||||
* @param {import('./types/compile.d.ts').Code} [next]
|
||||
* @param {string} [filename]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function jsChanged(prev, next, filename) {
|
||||
const prevJs = prev?.code;
|
||||
const nextJs = next?.code;
|
||||
const isStrictEqual = isCodeEqual(prevJs, nextJs);
|
||||
if (isStrictEqual) {
|
||||
return false;
|
||||
}
|
||||
const isLooseEqual = isCodeEqual(normalizeJsCode(prevJs), normalizeJsCode(nextJs));
|
||||
if (!isStrictEqual && isLooseEqual) {
|
||||
log.warn(
|
||||
`ignoring compiler output js change for ${filename} as it is equal to previous output after normalization`
|
||||
);
|
||||
}
|
||||
return !isLooseEqual;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} [prev]
|
||||
* @param {string} [next]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isCodeEqual(prev, next) {
|
||||
if (!prev && !next) {
|
||||
return true;
|
||||
}
|
||||
if ((!prev && next) || (prev && !next)) {
|
||||
return false;
|
||||
}
|
||||
return prev === next;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove code that only changes metadata and does not require a js update for the component to keep working
|
||||
*
|
||||
* 1) add_location() calls. These add location metadata to elements, only used by some dev tools
|
||||
* 2) ... maybe more (or less) in the future
|
||||
*
|
||||
* @param {string} [code]
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function normalizeJsCode(code) {
|
||||
if (!code) {
|
||||
return code;
|
||||
}
|
||||
return code.replace(/\s*\badd_location\s*\([^)]*\)\s*;?/g, '');
|
||||
}
|
225
node_modules/@sveltejs/vite-plugin-svelte/src/index.d.ts
generated
vendored
Normal file
225
node_modules/@sveltejs/vite-plugin-svelte/src/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
import type { InlineConfig, ResolvedConfig, UserConfig, Plugin } from 'vite';
|
||||
import type { CompileOptions, Warning } from 'svelte/types/compiler/interfaces';
|
||||
import type { PreprocessorGroup } from 'svelte/types/compiler/preprocess';
|
||||
import type { Options as InspectorOptions } from '@sveltejs/vite-plugin-svelte-inspector';
|
||||
|
||||
type Options = Omit<SvelteOptions, 'vitePlugin'> & 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<string>;
|
||||
/**
|
||||
* 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<string>;
|
||||
/**
|
||||
* 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 unset for dev, always false for build
|
||||
*/
|
||||
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<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'>;
|
||||
/**
|
||||
* 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<CompileOptions>;
|
||||
}) => Promise<Partial<CompileOptions> | void> | Partial<CompileOptions> | void;
|
||||
/**
|
||||
* send a websocket message with svelte compiler warnings during dev
|
||||
*
|
||||
*/
|
||||
sendWarningsToBrowser?: boolean;
|
||||
/**
|
||||
* disable svelte field resolve warnings
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
disableSvelteResolveWarnings?: boolean;
|
||||
/**
|
||||
* Options for compiling Svelte JS/TS modules
|
||||
*/
|
||||
compileModule?: CompileModuleOptions;
|
||||
}
|
||||
|
||||
interface CompileModuleOptions {
|
||||
extensions?: string[];
|
||||
include?: Arrayable<string>;
|
||||
exclude?: Arrayable<string>;
|
||||
}
|
||||
|
||||
type ModuleFormat = NonNullable<'esm'>;
|
||||
type CssHashGetter = NonNullable<CompileOptions['cssHash']>;
|
||||
type Arrayable<T> = T | T[];
|
||||
|
||||
interface VitePreprocessOptions {
|
||||
script?: boolean;
|
||||
style?: boolean | InlineConfig | ResolvedConfig;
|
||||
}
|
||||
|
||||
declare function vitePreprocess(opts?: VitePreprocessOptions): PreprocessorGroup;
|
||||
|
||||
declare function loadSvelteConfig(
|
||||
viteConfig?: UserConfig,
|
||||
inlineOptions?: Partial<Options>
|
||||
): Promise<Partial<SvelteOptions> | undefined>;
|
||||
|
||||
declare function svelte(inlineOptions?: Partial<Options>): Plugin[];
|
||||
|
||||
export {
|
||||
Arrayable,
|
||||
CssHashGetter,
|
||||
ModuleFormat,
|
||||
Options,
|
||||
PluginOptions,
|
||||
SvelteOptions,
|
||||
loadSvelteConfig,
|
||||
svelte,
|
||||
VitePreprocessOptions,
|
||||
vitePreprocess
|
||||
};
|
||||
|
||||
// reexported types
|
||||
|
||||
export { CompileOptions, Warning } from 'svelte/types/compiler/interfaces';
|
||||
|
||||
export {
|
||||
MarkupPreprocessor,
|
||||
Preprocessor,
|
||||
PreprocessorGroup,
|
||||
Processed
|
||||
} from 'svelte/types/compiler/preprocess';
|
317
node_modules/@sveltejs/vite-plugin-svelte/src/index.js
generated
vendored
Normal file
317
node_modules/@sveltejs/vite-plugin-svelte/src/index.js
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
||||
import fs from 'node:fs';
|
||||
import { version as viteVersion } from 'vite';
|
||||
import * as svelteCompiler from 'svelte/compiler';
|
||||
|
||||
import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
|
||||
|
||||
import { isDepExcluded } from 'vitefu';
|
||||
import { handleHotUpdate } from './handle-hot-update.js';
|
||||
import { log, logCompilerWarnings } from './utils/log.js';
|
||||
import { createCompileSvelte } from './utils/compile.js';
|
||||
import { buildIdParser, buildModuleIdParser } from './utils/id.js';
|
||||
import {
|
||||
buildExtraViteConfig,
|
||||
validateInlineOptions,
|
||||
resolveOptions,
|
||||
patchResolvedViteConfig,
|
||||
preResolveOptions
|
||||
} from './utils/options.js';
|
||||
|
||||
import { ensureWatchedFile, setupWatchers } from './utils/watch.js';
|
||||
import { resolveViaPackageJsonSvelte } from './utils/resolve.js';
|
||||
|
||||
import { toRollupError } from './utils/error.js';
|
||||
import { saveSvelteMetadata } from './utils/optimizer.js';
|
||||
import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache.js';
|
||||
import { loadRaw } from './utils/load-raw.js';
|
||||
import { FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE } from './utils/constants.js';
|
||||
import { isSvelte3, isSvelte5 } from './utils/svelte-version.js';
|
||||
|
||||
const isVite4_0 = viteVersion.startsWith('4.0');
|
||||
|
||||
/** @type {import('./index.d.ts').svelte} */
|
||||
export function svelte(inlineOptions) {
|
||||
if (process.env.DEBUG != null) {
|
||||
log.setLevel('debug');
|
||||
}
|
||||
validateInlineOptions(inlineOptions);
|
||||
const cache = new VitePluginSvelteCache();
|
||||
// updated in configResolved hook
|
||||
/** @type {import('./types/id.d.ts').IdParser} */
|
||||
let requestParser;
|
||||
/** @type {import('./types/id.d.ts').ModuleIdParser} */
|
||||
let moduleRequestParser;
|
||||
/** @type {import('./types/options.d.ts').ResolvedOptions} */
|
||||
let options;
|
||||
/** @type {import('vite').ResolvedConfig} */
|
||||
let viteConfig;
|
||||
|
||||
/** @type {import('./types/compile.d.ts').CompileSvelte} */
|
||||
let compileSvelte;
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
/** @type {Promise<import('vite').Rollup.PartialResolvedId | null>} */
|
||||
let resolvedSvelteSSR;
|
||||
/** @type {Set<string>} */
|
||||
let packagesWithResolveWarnings;
|
||||
/** @type {import('./types/plugin-api.d.ts').PluginAPI} */
|
||||
const api = {};
|
||||
/** @type {import('vite').Plugin[]} */
|
||||
const plugins = [
|
||||
{
|
||||
name: 'vite-plugin-svelte',
|
||||
// make sure our resolver runs before vite internal resolver to resolve svelte field correctly
|
||||
enforce: 'pre',
|
||||
api,
|
||||
async config(config, configEnv) {
|
||||
// setup logger
|
||||
if (process.env.DEBUG) {
|
||||
log.setLevel('debug');
|
||||
} else if (config.logLevel) {
|
||||
log.setLevel(config.logLevel);
|
||||
}
|
||||
// @ts-expect-error temporarily lend the options variable until fixed in configResolved
|
||||
options = await preResolveOptions(inlineOptions, config, configEnv);
|
||||
// extra vite config
|
||||
const extraViteConfig = await buildExtraViteConfig(options, config);
|
||||
log.debug('additional vite config', extraViteConfig);
|
||||
return extraViteConfig;
|
||||
},
|
||||
|
||||
async configResolved(config) {
|
||||
options = resolveOptions(options, config, cache);
|
||||
patchResolvedViteConfig(config, options);
|
||||
requestParser = buildIdParser(options);
|
||||
compileSvelte = createCompileSvelte(options);
|
||||
viteConfig = config;
|
||||
// TODO deep clone to avoid mutability from outside?
|
||||
api.options = options;
|
||||
log.debug('resolved options', options);
|
||||
},
|
||||
|
||||
async buildStart() {
|
||||
packagesWithResolveWarnings = new Set();
|
||||
if (!options.prebundleSvelteLibraries) return;
|
||||
const isSvelteMetadataChanged = await saveSvelteMetadata(viteConfig.cacheDir, options);
|
||||
if (isSvelteMetadataChanged) {
|
||||
// Force Vite to optimize again. Although we mutate the config here, it works because
|
||||
// Vite's optimizer runs after `buildStart()`.
|
||||
viteConfig.optimizeDeps.force = true;
|
||||
}
|
||||
},
|
||||
|
||||
configureServer(server) {
|
||||
options.server = server;
|
||||
setupWatchers(options, cache, requestParser);
|
||||
},
|
||||
|
||||
async load(id, opts) {
|
||||
const ssr = !!opts?.ssr;
|
||||
const svelteRequest = requestParser(id, !!ssr);
|
||||
if (svelteRequest) {
|
||||
const { filename, query, raw } = svelteRequest;
|
||||
if (raw) {
|
||||
return loadRaw(svelteRequest, compileSvelte, options);
|
||||
} else {
|
||||
if (query.svelte && query.type === 'style') {
|
||||
const css = cache.getCSS(svelteRequest);
|
||||
if (css) {
|
||||
log.debug(`load returns css for ${filename}`);
|
||||
return css;
|
||||
}
|
||||
}
|
||||
// prevent vite asset plugin from loading files as url that should be compiled in transform
|
||||
if (viteConfig.assetsInclude(filename)) {
|
||||
log.debug(`load returns raw content for ${filename}`);
|
||||
return fs.readFileSync(filename, 'utf-8');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async resolveId(importee, importer, opts) {
|
||||
const ssr = !!opts?.ssr;
|
||||
const svelteRequest = requestParser(importee, ssr);
|
||||
if (svelteRequest?.query.svelte) {
|
||||
if (svelteRequest.query.type === 'style' && !svelteRequest.raw) {
|
||||
// return cssId with root prefix so postcss pipeline of vite finds the directory correctly
|
||||
// see https://github.com/sveltejs/vite-plugin-svelte/issues/14
|
||||
log.debug(`resolveId resolved virtual css module ${svelteRequest.cssId}`);
|
||||
return svelteRequest.cssId;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove this after bumping peerDep on Vite to 4.1+ or Svelte to 4.0+
|
||||
if (isVite4_0 && isSvelte3 && ssr && importee === 'svelte') {
|
||||
if (!resolvedSvelteSSR) {
|
||||
resolvedSvelteSSR = this.resolve('svelte/ssr', undefined, { skipSelf: true }).then(
|
||||
(svelteSSR) => {
|
||||
log.debug('resolved svelte to svelte/ssr');
|
||||
return svelteSSR;
|
||||
},
|
||||
(err) => {
|
||||
log.debug(
|
||||
'failed to resolve svelte to svelte/ssr. Update svelte to a version that exports it',
|
||||
err
|
||||
);
|
||||
return null; // returning null here leads to svelte getting resolved regularly
|
||||
}
|
||||
);
|
||||
}
|
||||
return resolvedSvelteSSR;
|
||||
}
|
||||
//@ts-expect-error scan
|
||||
const scan = !!opts?.scan; // scanner phase of optimizeDeps
|
||||
const isPrebundled =
|
||||
options.prebundleSvelteLibraries &&
|
||||
viteConfig.optimizeDeps?.disabled !== true &&
|
||||
viteConfig.optimizeDeps?.disabled !== (options.isBuild ? 'build' : 'dev') &&
|
||||
!isDepExcluded(importee, viteConfig.optimizeDeps?.exclude ?? []);
|
||||
// for prebundled libraries we let vite resolve the prebundling result
|
||||
// for ssr, during scanning and non-prebundled, we do it
|
||||
if (ssr || scan || !isPrebundled) {
|
||||
try {
|
||||
const isFirstResolve = !cache.hasResolvedSvelteField(importee, importer);
|
||||
const resolved = await resolveViaPackageJsonSvelte(importee, importer, cache);
|
||||
if (isFirstResolve && resolved) {
|
||||
const packageInfo = await cache.getPackageInfo(resolved);
|
||||
const packageVersion = `${packageInfo.name}@${packageInfo.version}`;
|
||||
log.debug.once(
|
||||
`resolveId resolved ${importee} to ${resolved} via package.json svelte field of ${packageVersion}`
|
||||
);
|
||||
|
||||
try {
|
||||
const viteResolved = (
|
||||
await this.resolve(importee, importer, { ...opts, skipSelf: true })
|
||||
)?.id;
|
||||
if (resolved !== viteResolved) {
|
||||
packagesWithResolveWarnings.add(packageVersion);
|
||||
log.debug.enabled &&
|
||||
log.debug.once(
|
||||
`resolve difference for ${packageVersion} ${importee} - svelte: "${resolved}", vite: "${viteResolved}"`
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
packagesWithResolveWarnings.add(packageVersion);
|
||||
log.debug.enabled &&
|
||||
log.debug.once(
|
||||
`resolve error for ${packageVersion} ${importee} - svelte: "${resolved}", vite: ERROR`,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
return resolved;
|
||||
} catch (e) {
|
||||
log.debug.once(
|
||||
`error trying to resolve ${importee} from ${importer} via package.json svelte field `,
|
||||
e
|
||||
);
|
||||
// this error most likely happens due to non-svelte related importee/importers so swallow it here
|
||||
// in case it really way a svelte library, users will notice anyway. (lib not working due to failed resolve)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async transform(code, id, opts) {
|
||||
const ssr = !!opts?.ssr;
|
||||
const svelteRequest = requestParser(id, ssr);
|
||||
if (!svelteRequest || svelteRequest.query.type === 'style' || svelteRequest.raw) {
|
||||
return;
|
||||
}
|
||||
let compileData;
|
||||
try {
|
||||
compileData = await compileSvelte(svelteRequest, code, options);
|
||||
} catch (e) {
|
||||
cache.setError(svelteRequest, e);
|
||||
throw toRollupError(e, options);
|
||||
}
|
||||
logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
|
||||
cache.update(compileData);
|
||||
if (compileData.dependencies?.length) {
|
||||
if (options.server) {
|
||||
for (const dep of compileData.dependencies) {
|
||||
ensureWatchedFile(options.server.watcher, dep, options.root);
|
||||
}
|
||||
} else if (options.isBuild && viteConfig.build.watch) {
|
||||
for (const dep of compileData.dependencies) {
|
||||
this.addWatchFile(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
log.debug(`transform returns compiled js for ${svelteRequest.filename}`);
|
||||
return {
|
||||
...compileData.compiled.js,
|
||||
meta: {
|
||||
vite: {
|
||||
lang: compileData.lang
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
handleHotUpdate(ctx) {
|
||||
if (!options.hot || !options.emitCss) {
|
||||
return;
|
||||
}
|
||||
const svelteRequest = requestParser(ctx.file, false, ctx.timestamp);
|
||||
if (svelteRequest) {
|
||||
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
|
||||
}
|
||||
},
|
||||
async buildEnd() {
|
||||
await options.stats?.finishAll();
|
||||
if (
|
||||
!options.experimental?.disableSvelteResolveWarnings &&
|
||||
packagesWithResolveWarnings?.size > 0
|
||||
) {
|
||||
log.warn(
|
||||
`WARNING: The following packages use a svelte resolve configuration in package.json that has conflicting results and is going to cause problems future.\n\n${[
|
||||
...packagesWithResolveWarnings
|
||||
].join('\n')}\n\nPlease see ${FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE} for details.`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
if (!isSvelte5) {
|
||||
plugins.push(svelteInspector()); // TODO reenable once svelte5 has support
|
||||
}
|
||||
if (isSvelte5) {
|
||||
log.warn(
|
||||
'svelte 5 support in v-p-s is experimental, breaking changes can occur in any release until this notice is removed'
|
||||
);
|
||||
log.warn('svelte 5 does not support svelte-inspector yet, disabling it');
|
||||
// TODO move to separate file
|
||||
plugins.push({
|
||||
name: 'vite-plugin-svelte-module',
|
||||
enforce: 'post',
|
||||
async configResolved() {
|
||||
moduleRequestParser = buildModuleIdParser(options);
|
||||
},
|
||||
async transform(code, id, opts) {
|
||||
const ssr = !!opts?.ssr;
|
||||
const moduleRequest = moduleRequestParser(id, ssr);
|
||||
if (!moduleRequest) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// @ts-ignore doesn't exist in Svelte 4
|
||||
const compileResult = await svelteCompiler.compileModule(code, {
|
||||
generate: ssr ? 'server' : 'client',
|
||||
filename: moduleRequest.filename
|
||||
});
|
||||
logCompilerWarnings(moduleRequest, compileResult.warnings, options);
|
||||
return compileResult.js;
|
||||
} catch (e) {
|
||||
throw toRollupError(e, options);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
export { vitePreprocess } from './preprocess.js';
|
||||
export { loadSvelteConfig } from './utils/load-svelte-config.js';
|
118
node_modules/@sveltejs/vite-plugin-svelte/src/preprocess.js
generated
vendored
Normal file
118
node_modules/@sveltejs/vite-plugin-svelte/src/preprocess.js
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
import { preprocessCSS, resolveConfig, transformWithEsbuild } from 'vite';
|
||||
import { mapToRelative, removeLangSuffix } from './utils/sourcemaps.js';
|
||||
|
||||
/**
|
||||
* @typedef {(code: string, filename: string) => Promise<{ code: string; map?: any; deps?: Set<string> }>} CssTransform
|
||||
*/
|
||||
|
||||
const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss'];
|
||||
const supportedScriptLangs = ['ts'];
|
||||
|
||||
export const lang_sep = '.vite-preprocess.';
|
||||
|
||||
/** @type {import('./index.d.ts').vitePreprocess} */
|
||||
export function vitePreprocess(opts) {
|
||||
/** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup} */
|
||||
const preprocessor = {};
|
||||
if (opts?.script !== false) {
|
||||
preprocessor.script = viteScript().script;
|
||||
}
|
||||
if (opts?.style !== false) {
|
||||
const styleOpts = typeof opts?.style == 'object' ? opts?.style : undefined;
|
||||
preprocessor.style = viteStyle(styleOpts).style;
|
||||
}
|
||||
return preprocessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {{ script: import('svelte/types/compiler/preprocess').Preprocessor }}
|
||||
*/
|
||||
function viteScript() {
|
||||
return {
|
||||
async script({ attributes, content, filename = '' }) {
|
||||
const lang = /** @type {string} */ (attributes.lang);
|
||||
if (!supportedScriptLangs.includes(lang)) return;
|
||||
const { code, map } = await transformWithEsbuild(content, filename, {
|
||||
loader: /** @type {import('vite').ESBuildOptions['loader']} */ (lang),
|
||||
target: 'esnext',
|
||||
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/types/compiler/preprocess').Preprocessor }}
|
||||
*/
|
||||
function viteStyle(config = {}) {
|
||||
/** @type {CssTransform} */
|
||||
let transform;
|
||||
/** @type {import('svelte/types/compiler/preprocess').Preprocessor} */
|
||||
const style = async ({ attributes, content, filename = '' }) => {
|
||||
const lang = /** @type {string} */ (attributes.lang);
|
||||
if (!supportedStyleLangs.includes(lang)) return;
|
||||
if (!transform) {
|
||||
/** @type {import('vite').ResolvedConfig} */
|
||||
let resolvedConfig;
|
||||
// @ts-expect-error special prop added if running in v-p-s
|
||||
if (style.__resolvedConfig) {
|
||||
// @ts-expect-error
|
||||
resolvedConfig = style.__resolvedConfig;
|
||||
} else if (isResolvedConfig(config)) {
|
||||
resolvedConfig = config;
|
||||
} else {
|
||||
resolvedConfig = await resolveConfig(
|
||||
config,
|
||||
process.env.NODE_ENV === 'production' ? 'build' : 'serve'
|
||||
);
|
||||
}
|
||||
transform = getCssTransformFn(resolvedConfig);
|
||||
}
|
||||
const suffix = `${lang_sep}${lang}`;
|
||||
const moduleId = `${filename}${suffix}`;
|
||||
const { code, map, deps } = await transform(content, moduleId);
|
||||
removeLangSuffix(map, suffix);
|
||||
mapToRelative(map, filename);
|
||||
const dependencies = deps ? Array.from(deps).filter((d) => !d.endsWith(suffix)) : undefined;
|
||||
return {
|
||||
code,
|
||||
map: map ?? undefined,
|
||||
dependencies
|
||||
};
|
||||
};
|
||||
// @ts-expect-error tag so can be found by v-p-s
|
||||
style.__resolvedConfig = null;
|
||||
return { style };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('vite').ResolvedConfig} config
|
||||
* @returns {CssTransform}
|
||||
*/
|
||||
function getCssTransformFn(config) {
|
||||
return async (code, filename) => {
|
||||
return preprocessCSS(code, filename, config);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} config
|
||||
* @returns {config is import('vite').ResolvedConfig}
|
||||
*/
|
||||
function isResolvedConfig(config) {
|
||||
return !!config.inlineConfig;
|
||||
}
|
48
node_modules/@sveltejs/vite-plugin-svelte/src/types/compile.d.ts
generated
vendored
Normal file
48
node_modules/@sveltejs/vite-plugin-svelte/src/types/compile.d.ts
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
import type { Processed } from 'svelte/types/compiler/preprocess';
|
||||
import type { SvelteRequest } from './id.d.ts';
|
||||
import type { ResolvedOptions } from './options.d.ts';
|
||||
|
||||
export type CompileSvelte = (
|
||||
svelteRequest: SvelteRequest,
|
||||
code: string,
|
||||
options: Partial<ResolvedOptions>
|
||||
) => Promise<CompileData>;
|
||||
|
||||
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: Array<{
|
||||
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;
|
||||
}
|
46
node_modules/@sveltejs/vite-plugin-svelte/src/types/id.d.ts
generated
vendored
Normal file
46
node_modules/@sveltejs/vite-plugin-svelte/src/types/id.d.ts
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
import type { CompileOptions } from 'svelte/types/compiler/interfaces';
|
||||
|
||||
export type SvelteQueryTypes = 'style' | 'script' | 'preprocessed' | 'all';
|
||||
|
||||
export interface RequestQuery {
|
||||
// our own
|
||||
svelte?: boolean;
|
||||
type?: SvelteQueryTypes;
|
||||
sourcemap?: boolean;
|
||||
compilerOptions?: Pick<
|
||||
CompileOptions,
|
||||
'generate' | 'dev' | 'css' | 'hydratable' | 'customElement' | 'immutable' | 'enableSourcemap'
|
||||
>;
|
||||
// vite specific
|
||||
url?: boolean;
|
||||
raw?: boolean;
|
||||
direct?: boolean;
|
||||
}
|
||||
|
||||
export interface SvelteRequest {
|
||||
id: string;
|
||||
cssId: string;
|
||||
filename: string;
|
||||
normalizedFilename: string;
|
||||
query: RequestQuery;
|
||||
timestamp: number;
|
||||
ssr: boolean;
|
||||
raw: boolean;
|
||||
}
|
||||
|
||||
export interface SvelteModuleRequest {
|
||||
id: string;
|
||||
filename: string;
|
||||
normalizedFilename: string;
|
||||
query: RequestQuery;
|
||||
timestamp: number;
|
||||
ssr: boolean;
|
||||
}
|
||||
|
||||
export type IdParser = (id: string, ssr: boolean, timestamp?: number) => SvelteRequest | undefined;
|
||||
|
||||
export type ModuleIdParser = (
|
||||
id: string,
|
||||
ssr: boolean,
|
||||
timestamp?: number
|
||||
) => SvelteModuleRequest | undefined;
|
24
node_modules/@sveltejs/vite-plugin-svelte/src/types/log.d.ts
generated
vendored
Normal file
24
node_modules/@sveltejs/vite-plugin-svelte/src/types/log.d.ts
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
import type { Warning } from '../index.d.ts';
|
||||
|
||||
export interface LogFn extends SimpleLogFn {
|
||||
(message: string, payload?: any, namespace?: string): void;
|
||||
|
||||
enabled: boolean;
|
||||
once: SimpleLogFn;
|
||||
}
|
||||
|
||||
export interface SimpleLogFn {
|
||||
(message: string, payload?: any, namespace?: string): void;
|
||||
}
|
||||
|
||||
export type SvelteWarningsMessage = {
|
||||
id: string;
|
||||
filename: string;
|
||||
normalizedFilename: string;
|
||||
timestamp: number;
|
||||
warnings: Warning[]; // allWarnings filtered by warnings where onwarn did not call the default handler
|
||||
allWarnings: Warning[]; // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
|
||||
rawWarnings: Warning[]; // raw compiler output
|
||||
};
|
||||
|
||||
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
20
node_modules/@sveltejs/vite-plugin-svelte/src/types/options.d.ts
generated
vendored
Normal file
20
node_modules/@sveltejs/vite-plugin-svelte/src/types/options.d.ts
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import type { CompileOptions } from 'svelte/types/compiler/interfaces';
|
||||
import type { ViteDevServer } from 'vite';
|
||||
import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
|
||||
import type { Options } from '../index.d.ts';
|
||||
|
||||
export interface PreResolvedOptions extends Options {
|
||||
// these options are non-nullable after resolve
|
||||
compilerOptions: CompileOptions;
|
||||
// extra options
|
||||
root: string;
|
||||
isBuild: boolean;
|
||||
isServe: boolean;
|
||||
isDebug: boolean;
|
||||
}
|
||||
|
||||
export interface ResolvedOptions extends PreResolvedOptions {
|
||||
isProduction: boolean;
|
||||
server?: ViteDevServer;
|
||||
stats?: VitePluginSvelteStats;
|
||||
}
|
11
node_modules/@sveltejs/vite-plugin-svelte/src/types/plugin-api.d.ts
generated
vendored
Normal file
11
node_modules/@sveltejs/vite-plugin-svelte/src/types/plugin-api.d.ts
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import type { ResolvedOptions } from './options.d.ts';
|
||||
|
||||
export 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
|
||||
}
|
30
node_modules/@sveltejs/vite-plugin-svelte/src/types/vite-plugin-svelte-stats.d.ts
generated
vendored
Normal file
30
node_modules/@sveltejs/vite-plugin-svelte/src/types/vite-plugin-svelte-stats.d.ts
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
export interface Stat {
|
||||
file: string;
|
||||
pkg?: string;
|
||||
start: number;
|
||||
end: number;
|
||||
}
|
||||
|
||||
export interface StatCollection {
|
||||
name: string;
|
||||
options: CollectionOptions;
|
||||
|
||||
start: (file: string) => () => void;
|
||||
stats: Stat[];
|
||||
packageStats?: PackageStats[];
|
||||
collectionStart: number;
|
||||
duration?: number;
|
||||
finish: () => Promise<void> | void;
|
||||
finished: boolean;
|
||||
}
|
||||
|
||||
export interface PackageStats {
|
||||
pkg: string;
|
||||
files: number;
|
||||
duration: number;
|
||||
}
|
||||
|
||||
export interface CollectionOptions {
|
||||
logInProgress: (collection: StatCollection, now: number) => boolean;
|
||||
logResult: (collection: StatCollection) => boolean;
|
||||
}
|
207
node_modules/@sveltejs/vite-plugin-svelte/src/utils/compile.js
generated
vendored
Normal file
207
node_modules/@sveltejs/vite-plugin-svelte/src/utils/compile.js
generated
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
import * as svelte from 'svelte/compiler';
|
||||
// @ts-ignore
|
||||
import { createMakeHot } from 'svelte-hmr';
|
||||
import { safeBase64Hash } from './hash.js';
|
||||
import { log } from './log.js';
|
||||
|
||||
import { createInjectScopeEverythingRulePreprocessorGroup } from './preprocess.js';
|
||||
import { mapToRelative } from './sourcemaps.js';
|
||||
|
||||
const scriptLangRE = /<script [^>]*lang=["']?([^"' >]+)["']?[^>]*>/;
|
||||
|
||||
import { isSvelte3, isSvelte5 } from './svelte-version.js';
|
||||
|
||||
/**
|
||||
* @param {Function} [makeHot]
|
||||
* @returns {import('../types/compile.d.ts').CompileSvelte}
|
||||
*/
|
||||
export const _createCompileSvelte = (makeHot) => {
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
||||
let stats;
|
||||
const devStylePreprocessor = createInjectScopeEverythingRulePreprocessorGroup();
|
||||
/** @type {import('../types/compile.d.ts').CompileSvelte} */
|
||||
return async function compileSvelte(svelteRequest, code, options) {
|
||||
const { filename, normalizedFilename, cssId, ssr, raw } = svelteRequest;
|
||||
const { emitCss = true } = options;
|
||||
const dependencies = [];
|
||||
|
||||
if (options.stats) {
|
||||
if (options.isBuild) {
|
||||
if (!stats) {
|
||||
// build is either completely ssr or csr, create stats collector on first compile
|
||||
// it is then finished in the buildEnd hook.
|
||||
stats = options.stats.startCollection(`${ssr ? 'ssr' : 'dom'} compile`, {
|
||||
logInProgress: () => false
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// dev time ssr, it's a ssr request and there are no stats, assume new page load and start collecting
|
||||
if (ssr && !stats) {
|
||||
stats = options.stats.startCollection('ssr compile');
|
||||
}
|
||||
// stats are being collected but this isn't an ssr request, assume page loaded and stop collecting
|
||||
if (!ssr && stats) {
|
||||
stats.finish();
|
||||
stats = undefined;
|
||||
}
|
||||
// TODO find a way to trace dom compile during dev
|
||||
// problem: we need to call finish at some point but have no way to tell if page load finished
|
||||
// also they for hmr updates too
|
||||
}
|
||||
}
|
||||
/** @type {import('../index.d.ts').CompileOptions} */
|
||||
const compileOptions = {
|
||||
...options.compilerOptions,
|
||||
filename,
|
||||
// @ts-expect-error generate type is different for svelte5
|
||||
generate: isSvelte5 ? (ssr ? 'server' : 'client') : ssr ? 'ssr' : 'dom'
|
||||
};
|
||||
if (isSvelte3) {
|
||||
// @ts-ignore
|
||||
compileOptions.format = 'esm';
|
||||
}
|
||||
if (options.hot && options.emitCss) {
|
||||
const hash = `s-${safeBase64Hash(normalizedFilename)}`;
|
||||
log.debug(`setting cssHash ${hash} for ${normalizedFilename}`);
|
||||
compileOptions.cssHash = () => hash;
|
||||
}
|
||||
if (ssr && compileOptions.enableSourcemap !== false) {
|
||||
if (typeof compileOptions.enableSourcemap === 'object') {
|
||||
compileOptions.enableSourcemap.css = false;
|
||||
} else {
|
||||
compileOptions.enableSourcemap = { js: true, css: false };
|
||||
}
|
||||
}
|
||||
|
||||
let preprocessed;
|
||||
let preprocessors = options.preprocess;
|
||||
if (!options.isBuild && options.emitCss && options.hot) {
|
||||
// inject preprocessor that ensures css hmr works better
|
||||
if (!Array.isArray(preprocessors)) {
|
||||
preprocessors = preprocessors
|
||||
? [preprocessors, devStylePreprocessor]
|
||||
: [devStylePreprocessor];
|
||||
} else {
|
||||
preprocessors = preprocessors.concat(devStylePreprocessor);
|
||||
}
|
||||
}
|
||||
if (preprocessors) {
|
||||
try {
|
||||
preprocessed = await svelte.preprocess(code, preprocessors, { filename }); // full filename here so postcss works
|
||||
} catch (e) {
|
||||
e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (preprocessed.dependencies) dependencies.push(...preprocessed.dependencies);
|
||||
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
||||
}
|
||||
if (typeof preprocessed?.map === 'object') {
|
||||
mapToRelative(preprocessed?.map, filename);
|
||||
}
|
||||
if (raw && svelteRequest.query.type === 'preprocessed') {
|
||||
// @ts-expect-error shortcut
|
||||
return /** @type {import('../types/compile.d.ts').CompileData} */ {
|
||||
preprocessed: preprocessed ?? { code }
|
||||
};
|
||||
}
|
||||
const finalCode = preprocessed ? preprocessed.code : code;
|
||||
const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
|
||||
filename,
|
||||
code: finalCode,
|
||||
compileOptions
|
||||
});
|
||||
if (dynamicCompileOptions && log.debug.enabled) {
|
||||
log.debug(
|
||||
`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`
|
||||
);
|
||||
}
|
||||
const finalCompileOptions = dynamicCompileOptions
|
||||
? {
|
||||
...compileOptions,
|
||||
...dynamicCompileOptions
|
||||
}
|
||||
: compileOptions;
|
||||
|
||||
const endStat = stats?.start(filename);
|
||||
const compiled = svelte.compile(finalCode, finalCompileOptions);
|
||||
|
||||
if (isSvelte3) {
|
||||
// prevent dangling pure comments
|
||||
// see https://github.com/sveltejs/kit/issues/9492#issuecomment-1487704985
|
||||
// uses regex replace with whitespace to keep sourcemap/character count unmodified
|
||||
compiled.js.code = compiled.js.code.replace(
|
||||
/\/\* [@#]__PURE__ \*\/(\s*)$/gm,
|
||||
' $1'
|
||||
);
|
||||
}
|
||||
if (endStat) {
|
||||
endStat();
|
||||
}
|
||||
mapToRelative(compiled.js?.map, filename);
|
||||
mapToRelative(compiled.css?.map, filename);
|
||||
if (!raw) {
|
||||
// wire css import and code for hmr
|
||||
const hasCss = compiled.css?.code?.trim().length > 0;
|
||||
// compiler might not emit css with mode none or it may be empty
|
||||
if (emitCss && hasCss) {
|
||||
// TODO properly update sourcemap?
|
||||
compiled.js.code += `\nimport ${JSON.stringify(cssId)};\n`;
|
||||
}
|
||||
|
||||
// only apply hmr when not in ssr context and hot options are set
|
||||
if (!ssr && makeHot) {
|
||||
compiled.js.code = makeHot({
|
||||
id: filename,
|
||||
compiledCode: compiled.js.code,
|
||||
//@ts-expect-error hot isn't a boolean at this point
|
||||
hotOptions: { ...options.hot, injectCss: options.hot?.injectCss === true && hasCss },
|
||||
compiled,
|
||||
originalCode: code,
|
||||
compileOptions: finalCompileOptions
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
filename,
|
||||
normalizedFilename,
|
||||
lang: code.match(scriptLangRE)?.[1] || 'js',
|
||||
// @ts-ignore
|
||||
compiled,
|
||||
ssr,
|
||||
dependencies,
|
||||
preprocessed: preprocessed ?? { code }
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {Function | undefined}
|
||||
*/
|
||||
function buildMakeHot(options) {
|
||||
const needsMakeHot = options.hot !== false && options.isServe && !options.isProduction;
|
||||
if (needsMakeHot) {
|
||||
// @ts-ignore
|
||||
const hotApi = options?.hot?.hotApi;
|
||||
// @ts-ignore
|
||||
const adapter = options?.hot?.adapter;
|
||||
return createMakeHot({
|
||||
// TODO Svelte 5 doesn't expose walk anymore. If we decide to make v-p-s 2 work with Svelte 5 HMR, we need to import walk from estree-walker
|
||||
walk: svelte.walk,
|
||||
hotApi,
|
||||
adapter,
|
||||
hotOptions: { noOverlay: true, .../** @type {object} */ (options.hot) }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {import('../types/compile.d.ts').CompileSvelte}
|
||||
*/
|
||||
export function createCompileSvelte(options) {
|
||||
const makeHot = buildMakeHot(options);
|
||||
return _createCompileSvelte(makeHot);
|
||||
}
|
31
node_modules/@sveltejs/vite-plugin-svelte/src/utils/constants.js
generated
vendored
Normal file
31
node_modules/@sveltejs/vite-plugin-svelte/src/utils/constants.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { isSvelte3 } from './svelte-version.js';
|
||||
|
||||
export const VITE_RESOLVE_MAIN_FIELDS = ['module', 'jsnext:main', 'jsnext'];
|
||||
|
||||
export const SVELTE_RESOLVE_MAIN_FIELDS = ['svelte'];
|
||||
|
||||
export const SVELTE_IMPORTS = [
|
||||
'svelte/animate',
|
||||
'svelte/easing',
|
||||
'svelte/internal',
|
||||
'svelte/motion',
|
||||
'svelte/ssr',
|
||||
'svelte/store',
|
||||
'svelte/transition',
|
||||
'svelte'
|
||||
];
|
||||
// TODO add to global list after dropping svelte 3
|
||||
if (!isSvelte3) {
|
||||
SVELTE_IMPORTS.push('svelte/internal/disclose-version');
|
||||
}
|
||||
|
||||
export const SVELTE_HMR_IMPORTS = [
|
||||
'svelte-hmr/runtime/hot-api-esm.js',
|
||||
'svelte-hmr/runtime/proxy-adapter-dom.js',
|
||||
'svelte-hmr'
|
||||
];
|
||||
|
||||
export const SVELTE_EXPORT_CONDITIONS = ['svelte'];
|
||||
|
||||
export const FAQ_LINK_CONFLICTS_IN_SVELTE_RESOLVE =
|
||||
'https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#conflicts-in-svelte-resolve';
|
90
node_modules/@sveltejs/vite-plugin-svelte/src/utils/dependencies.js
generated
vendored
Normal file
90
node_modules/@sveltejs/vite-plugin-svelte/src/utils/dependencies.js
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs/promises';
|
||||
import { findDepPkgJsonPath } from 'vitefu';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* dir: string;
|
||||
* pkg: Record<string, any>;
|
||||
* }} DependencyData
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} dep
|
||||
* @param {string} parent
|
||||
* @returns {Promise<DependencyData | undefined>}
|
||||
*/
|
||||
export async function resolveDependencyData(dep, parent) {
|
||||
const depDataPath = await findDepPkgJsonPath(dep, parent);
|
||||
if (!depDataPath) return undefined;
|
||||
try {
|
||||
return {
|
||||
dir: path.dirname(depDataPath),
|
||||
pkg: JSON.parse(await fs.readFile(depDataPath, 'utf-8'))
|
||||
};
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD = [
|
||||
'@lukeed/uuid',
|
||||
'@playwright/test',
|
||||
'@sveltejs/kit',
|
||||
'@sveltejs/package',
|
||||
'@sveltejs/vite-plugin-svelte',
|
||||
'autoprefixer',
|
||||
'cookie',
|
||||
'dotenv',
|
||||
'esbuild',
|
||||
'eslint',
|
||||
'jest',
|
||||
'mdsvex',
|
||||
'playwright',
|
||||
'postcss',
|
||||
'prettier',
|
||||
'svelte',
|
||||
'svelte2tsx',
|
||||
'svelte-check',
|
||||
'svelte-hmr',
|
||||
'svelte-preprocess',
|
||||
'tslib',
|
||||
'typescript',
|
||||
'vite',
|
||||
'vitest',
|
||||
'__vite-browser-external' // see https://github.com/sveltejs/vite-plugin-svelte/issues/362
|
||||
];
|
||||
const COMMON_PREFIXES_WITHOUT_SVELTE_FIELD = [
|
||||
'@fontsource/',
|
||||
'@postcss-plugins/',
|
||||
'@rollup/',
|
||||
'@sveltejs/adapter-',
|
||||
'@types/',
|
||||
'@typescript-eslint/',
|
||||
'eslint-',
|
||||
'jest-',
|
||||
'postcss-plugin-',
|
||||
'prettier-plugin-',
|
||||
'rollup-plugin-',
|
||||
'vite-plugin-'
|
||||
];
|
||||
|
||||
/**
|
||||
* Test for common dependency names that tell us it is not a package including a svelte field, eg. eslint + plugins.
|
||||
*
|
||||
* This speeds up the find process as we don't have to try and require the package.json for all of them
|
||||
*
|
||||
* @param {string} dependency
|
||||
* @returns {boolean} true if it is a dependency without a svelte field
|
||||
*/
|
||||
export function isCommonDepWithoutSvelteField(dependency) {
|
||||
return (
|
||||
COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD.includes(dependency) ||
|
||||
COMMON_PREFIXES_WITHOUT_SVELTE_FIELD.some(
|
||||
(prefix) =>
|
||||
prefix.startsWith('@')
|
||||
? dependency.startsWith(prefix)
|
||||
: dependency.substring(dependency.lastIndexOf('/') + 1).startsWith(prefix) // check prefix omitting @scope/
|
||||
)
|
||||
);
|
||||
}
|
102
node_modules/@sveltejs/vite-plugin-svelte/src/utils/error.js
generated
vendored
Normal file
102
node_modules/@sveltejs/vite-plugin-svelte/src/utils/error.js
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
import { buildExtendedLogMessage } from './log.js';
|
||||
|
||||
/**
|
||||
* convert an error thrown by svelte.compile to a RollupError so that vite displays it in a user friendly way
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning & Error} error a svelte compiler error, which is a mix of Warning and an error
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {import('vite').Rollup.RollupError} the converted error
|
||||
*/
|
||||
export function toRollupError(error, options) {
|
||||
const { filename, frame, start, code, name, stack } = error;
|
||||
/** @type {import('vite').Rollup.RollupError} */
|
||||
const rollupError = {
|
||||
name, // needed otherwise sveltekit coalesce_to_error turns it into a string
|
||||
id: filename,
|
||||
message: buildExtendedLogMessage(error), // include filename:line:column so that it's clickable
|
||||
frame: formatFrameForVite(frame),
|
||||
code,
|
||||
stack: options.isBuild || options.isDebug || !frame ? stack : ''
|
||||
};
|
||||
if (start) {
|
||||
rollupError.loc = {
|
||||
line: start.line,
|
||||
column: start.column,
|
||||
file: filename
|
||||
};
|
||||
}
|
||||
return rollupError;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an error thrown by svelte.compile to an esbuild PartialMessage
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning & Error} error a svelte compiler error, which is a mix of Warning and an error
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {import('esbuild').PartialMessage} the converted error
|
||||
*/
|
||||
export function toESBuildError(error, options) {
|
||||
const { filename, frame, start, stack } = error;
|
||||
/** @type {import('esbuild').PartialMessage} */
|
||||
const partialMessage = {
|
||||
text: buildExtendedLogMessage(error)
|
||||
};
|
||||
if (start) {
|
||||
partialMessage.location = {
|
||||
line: start.line,
|
||||
column: start.column,
|
||||
file: filename,
|
||||
lineText: lineFromFrame(start.line, frame) // needed to get a meaningful error message on cli
|
||||
};
|
||||
}
|
||||
if (options.isBuild || options.isDebug || !frame) {
|
||||
partialMessage.detail = stack;
|
||||
}
|
||||
return partialMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract line with number from codeframe
|
||||
*
|
||||
* @param {number} lineNo
|
||||
* @param {string} [frame]
|
||||
* @returns {string}
|
||||
*/
|
||||
function lineFromFrame(lineNo, frame) {
|
||||
if (!frame) {
|
||||
return '';
|
||||
}
|
||||
const lines = frame.split('\n');
|
||||
const errorLine = lines.find((line) => line.trimStart().startsWith(`${lineNo}: `));
|
||||
return errorLine ? errorLine.substring(errorLine.indexOf(': ') + 3) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* vite error overlay expects a specific format to show frames
|
||||
* this reformats svelte frame (colon separated, less whitespace)
|
||||
* to one that vite displays on overlay ( pipe separated, more whitespace)
|
||||
* e.g.
|
||||
* ```
|
||||
* 1: foo
|
||||
* 2: bar;
|
||||
* ^
|
||||
* 3: baz
|
||||
* ```
|
||||
* to
|
||||
* ```
|
||||
* 1 | foo
|
||||
* 2 | bar;
|
||||
* ^
|
||||
* 3 | baz
|
||||
* ```
|
||||
* @see https://github.com/vitejs/vite/blob/96591bf9989529de839ba89958755eafe4c445ae/packages/vite/src/client/overlay.ts#L116
|
||||
* @param {string} [frame]
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatFrameForVite(frame) {
|
||||
if (!frame) {
|
||||
return '';
|
||||
}
|
||||
return frame
|
||||
.split('\n')
|
||||
.map((line) => (line.match(/^\s+\^/) ? ' ' + line : ' ' + line.replace(':', ' | ')))
|
||||
.join('\n');
|
||||
}
|
133
node_modules/@sveltejs/vite-plugin-svelte/src/utils/esbuild.js
generated
vendored
Normal file
133
node_modules/@sveltejs/vite-plugin-svelte/src/utils/esbuild.js
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import * as svelte from 'svelte/compiler';
|
||||
import { log } from './log.js';
|
||||
import { toESBuildError } from './error.js';
|
||||
import { isSvelte3, isSvelte5 } from './svelte-version.js';
|
||||
|
||||
/**
|
||||
* @typedef {NonNullable<import('vite').DepOptimizationOptions['esbuildOptions']>} EsbuildOptions
|
||||
* @typedef {NonNullable<EsbuildOptions['plugins']>[number]} EsbuildPlugin
|
||||
*/
|
||||
|
||||
export const facadeEsbuildSveltePluginName = 'vite-plugin-svelte:facade';
|
||||
|
||||
const svelteModuleExtension = '.svelte.js';
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {EsbuildPlugin}
|
||||
*/
|
||||
export function esbuildSveltePlugin(options) {
|
||||
return {
|
||||
name: 'vite-plugin-svelte:optimize-svelte',
|
||||
setup(build) {
|
||||
// Skip in scanning phase as Vite already handles scanning Svelte files.
|
||||
// Otherwise this would heavily slow down the scanning phase.
|
||||
if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
|
||||
|
||||
const svelteExtensions = (options.extensions ?? ['.svelte']).map((ext) => ext.slice(1));
|
||||
if (isSvelte5) {
|
||||
svelteExtensions.push(svelteModuleExtension.slice(1));
|
||||
}
|
||||
const svelteFilter = new RegExp('\\.(' + svelteExtensions.join('|') + ')(\\?.*)?$');
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
|
||||
let statsCollection;
|
||||
build.onStart(() => {
|
||||
statsCollection = options.stats?.startCollection('prebundle libraries', {
|
||||
logResult: (c) => c.stats.length > 1
|
||||
});
|
||||
});
|
||||
build.onLoad({ filter: svelteFilter }, async ({ path: filename }) => {
|
||||
const code = readFileSync(filename, 'utf8');
|
||||
try {
|
||||
const contents = await compileSvelte(options, { filename, code }, statsCollection);
|
||||
return { contents };
|
||||
} catch (e) {
|
||||
return { errors: [toESBuildError(e, options)] };
|
||||
}
|
||||
});
|
||||
build.onEnd(() => {
|
||||
statsCollection?.finish();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @param {{ filename: string; code: string }} input
|
||||
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function compileSvelte(options, { filename, code }, statsCollection) {
|
||||
if (isSvelte5 && filename.endsWith(svelteModuleExtension)) {
|
||||
const endStat = statsCollection?.start(filename);
|
||||
// @ts-ignore doesn't exist in Svelte 4
|
||||
const compiled = svelte.compileModule(code, {
|
||||
filename,
|
||||
generate: 'client'
|
||||
});
|
||||
if (endStat) {
|
||||
endStat();
|
||||
}
|
||||
return compiled.js.map
|
||||
? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
|
||||
: compiled.js.code;
|
||||
}
|
||||
|
||||
let css = options.compilerOptions.css;
|
||||
if (css !== 'none') {
|
||||
// TODO ideally we'd be able to externalize prebundled styles too, but for now always put them in the js
|
||||
css = 'injected';
|
||||
}
|
||||
/** @type {import('../index.d.ts').CompileOptions} */
|
||||
const compileOptions = {
|
||||
...options.compilerOptions,
|
||||
css,
|
||||
filename,
|
||||
// @ts-expect-error generate type is different for svelte5
|
||||
generate: isSvelte5 ? 'client' : 'dom'
|
||||
};
|
||||
if (isSvelte3) {
|
||||
// @ts-ignore
|
||||
compileOptions.format = 'esm';
|
||||
}
|
||||
let preprocessed;
|
||||
|
||||
if (options.preprocess) {
|
||||
try {
|
||||
preprocessed = await svelte.preprocess(code, options.preprocess, { filename });
|
||||
} catch (e) {
|
||||
e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
|
||||
throw e;
|
||||
}
|
||||
if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
|
||||
}
|
||||
|
||||
const finalCode = preprocessed ? preprocessed.code : code;
|
||||
|
||||
const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
|
||||
filename,
|
||||
code: finalCode,
|
||||
compileOptions
|
||||
});
|
||||
|
||||
if (dynamicCompileOptions && log.debug.enabled) {
|
||||
log.debug(`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`);
|
||||
}
|
||||
|
||||
const finalCompileOptions = dynamicCompileOptions
|
||||
? {
|
||||
...compileOptions,
|
||||
...dynamicCompileOptions
|
||||
}
|
||||
: compileOptions;
|
||||
const endStat = statsCollection?.start(filename);
|
||||
const compiled = svelte.compile(finalCode, finalCompileOptions);
|
||||
if (endStat) {
|
||||
endStat();
|
||||
}
|
||||
return compiled.js.map
|
||||
? compiled.js.code + '//# sourceMappingURL=' + compiled.js.map.toUrl()
|
||||
: compiled.js.code;
|
||||
}
|
43
node_modules/@sveltejs/vite-plugin-svelte/src/utils/hash.js
generated
vendored
Normal file
43
node_modules/@sveltejs/vite-plugin-svelte/src/utils/hash.js
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
import * as crypto from 'node:crypto';
|
||||
|
||||
const hashes = Object.create(null);
|
||||
|
||||
//TODO shorter?
|
||||
const hash_length = 12;
|
||||
|
||||
/**
|
||||
* replaces +/= in base64 output so they don't interfere
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {string} base64 hash safe to use in any context
|
||||
*/
|
||||
export function safeBase64Hash(input) {
|
||||
if (hashes[input]) {
|
||||
return hashes[input];
|
||||
}
|
||||
//TODO if performance really matters, use a faster one like xx-hash etc.
|
||||
// should be evenly distributed because short input length and similarities in paths could cause collisions otherwise
|
||||
// OR DON'T USE A HASH AT ALL, what about a simple counter?
|
||||
const md5 = crypto.createHash('md5');
|
||||
md5.update(input);
|
||||
const hash = toSafe(md5.digest('base64')).slice(0, hash_length);
|
||||
hashes[input] = hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/** @type {Record<string, string>} */
|
||||
const replacements = {
|
||||
'+': '-',
|
||||
'/': '_',
|
||||
'=': ''
|
||||
};
|
||||
|
||||
const replaceRE = new RegExp(`[${Object.keys(replacements).join('')}]`, 'g');
|
||||
|
||||
/**
|
||||
* @param {string} base64
|
||||
* @returns {string}
|
||||
*/
|
||||
function toSafe(base64) {
|
||||
return base64.replace(replaceRE, (x) => replacements[x]);
|
||||
}
|
231
node_modules/@sveltejs/vite-plugin-svelte/src/utils/id.js
generated
vendored
Normal file
231
node_modules/@sveltejs/vite-plugin-svelte/src/utils/id.js
generated
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
import { createFilter, normalizePath } from 'vite';
|
||||
import * as fs from 'node:fs';
|
||||
import { log } from './log.js';
|
||||
|
||||
const VITE_FS_PREFIX = '/@fs/';
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
const SUPPORTED_COMPILER_OPTIONS = [
|
||||
'generate',
|
||||
'dev',
|
||||
'css',
|
||||
'hydratable',
|
||||
'customElement',
|
||||
'immutable',
|
||||
'enableSourcemap'
|
||||
];
|
||||
const TYPES_WITH_COMPILER_OPTIONS = ['style', 'script', 'all'];
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @returns {{ filename: string, rawQuery: string }}
|
||||
*/
|
||||
function splitId(id) {
|
||||
const parts = id.split('?', 2);
|
||||
const filename = parts[0];
|
||||
const rawQuery = parts[1];
|
||||
return { filename, rawQuery };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {string} filename
|
||||
* @param {string} rawQuery
|
||||
* @param {string} root
|
||||
* @param {number} timestamp
|
||||
* @param {boolean} ssr
|
||||
* @returns {import('../types/id.d.ts').SvelteRequest | undefined}
|
||||
*/
|
||||
function parseToSvelteRequest(id, filename, rawQuery, root, timestamp, ssr) {
|
||||
const query = parseRequestQuery(rawQuery);
|
||||
const rawOrDirect = !!(query.raw || query.direct);
|
||||
if (query.url || (!query.svelte && rawOrDirect)) {
|
||||
// skip requests with special vite tags
|
||||
return;
|
||||
}
|
||||
const raw = rawOrDirect;
|
||||
const normalizedFilename = normalize(filename, root);
|
||||
const cssId = createVirtualImportId(filename, root, 'style');
|
||||
|
||||
return {
|
||||
id,
|
||||
filename,
|
||||
normalizedFilename,
|
||||
cssId,
|
||||
query,
|
||||
timestamp,
|
||||
ssr,
|
||||
raw
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {string} root
|
||||
* @param {import('../types/id.d.ts').SvelteQueryTypes} type
|
||||
* @returns {string}
|
||||
*/
|
||||
function createVirtualImportId(filename, root, type) {
|
||||
const parts = ['svelte', `type=${type}`];
|
||||
if (type === 'style') {
|
||||
parts.push('lang.css');
|
||||
}
|
||||
if (existsInRoot(filename, root)) {
|
||||
filename = root + filename;
|
||||
} else if (filename.startsWith(VITE_FS_PREFIX)) {
|
||||
filename = IS_WINDOWS
|
||||
? filename.slice(VITE_FS_PREFIX.length) // remove /@fs/ from /@fs/C:/...
|
||||
: filename.slice(VITE_FS_PREFIX.length - 1); // remove /@fs from /@fs/home/user
|
||||
}
|
||||
// return same virtual id format as vite-plugin-vue eg ...App.svelte?svelte&type=style&lang.css
|
||||
return `${filename}?${parts.join('&')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} rawQuery
|
||||
* @returns {import('../types/id.d.ts').RequestQuery}
|
||||
*/
|
||||
function parseRequestQuery(rawQuery) {
|
||||
const query = Object.fromEntries(new URLSearchParams(rawQuery));
|
||||
for (const key in query) {
|
||||
if (query[key] === '') {
|
||||
// @ts-ignore
|
||||
query[key] = true;
|
||||
}
|
||||
}
|
||||
const compilerOptions = query.compilerOptions;
|
||||
if (compilerOptions) {
|
||||
if (!((query.raw || query.direct) && TYPES_WITH_COMPILER_OPTIONS.includes(query.type))) {
|
||||
throw new Error(
|
||||
`Invalid compilerOptions in query ${rawQuery}. CompilerOptions are only supported for raw or direct queries with type in "${TYPES_WITH_COMPILER_OPTIONS.join(
|
||||
', '
|
||||
)}" e.g. '?svelte&raw&type=script&compilerOptions={"generate":"ssr","dev":false}`
|
||||
);
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(compilerOptions);
|
||||
const invalid = Object.keys(parsed).filter(
|
||||
(key) => !SUPPORTED_COMPILER_OPTIONS.includes(key)
|
||||
);
|
||||
if (invalid.length) {
|
||||
throw new Error(
|
||||
`Invalid compilerOptions in query ${rawQuery}: ${invalid.join(
|
||||
', '
|
||||
)}. Supported: ${SUPPORTED_COMPILER_OPTIONS.join(', ')}`
|
||||
);
|
||||
}
|
||||
query.compilerOptions = parsed;
|
||||
} catch (e) {
|
||||
log.error('failed to parse request query compilerOptions', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return /** @type {import('../types/id.d.ts').RequestQuery}*/ query;
|
||||
}
|
||||
|
||||
/**
|
||||
* posixify and remove root at start
|
||||
*
|
||||
* @param {string} filename
|
||||
* @param {string} normalizedRoot
|
||||
* @returns {string}
|
||||
*/
|
||||
function normalize(filename, normalizedRoot) {
|
||||
return stripRoot(normalizePath(filename), normalizedRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} filename
|
||||
* @param {string} root
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function existsInRoot(filename, root) {
|
||||
if (filename.startsWith(VITE_FS_PREFIX)) {
|
||||
return false; // vite already tagged it as out of root
|
||||
}
|
||||
return fs.existsSync(root + filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} normalizedFilename
|
||||
* @param {string} normalizedRoot
|
||||
* @returns {string}
|
||||
*/
|
||||
function stripRoot(normalizedFilename, normalizedRoot) {
|
||||
return normalizedFilename.startsWith(normalizedRoot + '/')
|
||||
? normalizedFilename.slice(normalizedRoot.length)
|
||||
: normalizedFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../index.d.ts').Arrayable<string> | undefined} include
|
||||
* @param {import('../index.d.ts').Arrayable<string> | undefined} exclude
|
||||
* @param {string[]} extensions
|
||||
* @returns {(filename: string) => boolean}
|
||||
*/
|
||||
function buildFilter(include, exclude, extensions) {
|
||||
const rollupFilter = createFilter(include, exclude);
|
||||
return (filename) => rollupFilter(filename) && extensions.some((ext) => filename.endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {import('../types/id.d.ts').IdParser}
|
||||
*/
|
||||
export function buildIdParser(options) {
|
||||
const { include, exclude, extensions, root } = options;
|
||||
const normalizedRoot = normalizePath(root);
|
||||
const filter = buildFilter(include, exclude, extensions ?? []);
|
||||
return (id, ssr, timestamp = Date.now()) => {
|
||||
const { filename, rawQuery } = splitId(id);
|
||||
if (filter(filename)) {
|
||||
return parseToSvelteRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {import('../types/id.d.ts').ModuleIdParser}
|
||||
*/
|
||||
export function buildModuleIdParser(options) {
|
||||
const { include, exclude, extensions } = options?.experimental?.compileModule ?? {};
|
||||
const root = options.root;
|
||||
const normalizedRoot = normalizePath(root);
|
||||
const filter = buildFilter(include, exclude, extensions ?? ['.svelte.js', '.svelte.ts']);
|
||||
return (id, ssr, timestamp = Date.now()) => {
|
||||
const { filename, rawQuery } = splitId(id);
|
||||
if (filter(filename)) {
|
||||
return parseToSvelteModuleRequest(id, filename, rawQuery, normalizedRoot, timestamp, ssr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {string} filename
|
||||
* @param {string} rawQuery
|
||||
* @param {string} root
|
||||
* @param {number} timestamp
|
||||
* @param {boolean} ssr
|
||||
* @returns {import('../types/id.d.ts').SvelteModuleRequest | undefined}
|
||||
*/
|
||||
function parseToSvelteModuleRequest(id, filename, rawQuery, root, timestamp, ssr) {
|
||||
const query = parseRequestQuery(rawQuery);
|
||||
|
||||
if (query.url || query.raw || query.direct) {
|
||||
// skip requests with special vite tags
|
||||
return;
|
||||
}
|
||||
|
||||
const normalizedFilename = normalize(filename, root);
|
||||
|
||||
return {
|
||||
id,
|
||||
filename,
|
||||
normalizedFilename,
|
||||
query,
|
||||
timestamp,
|
||||
ssr
|
||||
};
|
||||
}
|
132
node_modules/@sveltejs/vite-plugin-svelte/src/utils/load-raw.js
generated
vendored
Normal file
132
node_modules/@sveltejs/vite-plugin-svelte/src/utils/load-raw.js
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
import fs from 'node:fs';
|
||||
import { toRollupError } from './error.js';
|
||||
import { log } from './log.js';
|
||||
|
||||
/**
|
||||
* utility function to compile ?raw and ?direct requests in load hook
|
||||
*
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @param {import('../types/compile.d.ts').CompileSvelte} compileSvelte
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function loadRaw(svelteRequest, compileSvelte, options) {
|
||||
const { id, filename, query } = svelteRequest;
|
||||
|
||||
// raw svelte subrequest, compile on the fly and return requested subpart
|
||||
let compileData;
|
||||
const source = fs.readFileSync(filename, 'utf-8');
|
||||
try {
|
||||
//avoid compileSvelte doing extra ssr stuff unless requested
|
||||
svelteRequest.ssr = query.compilerOptions?.generate === 'ssr';
|
||||
const type = query.type;
|
||||
compileData = await compileSvelte(svelteRequest, source, {
|
||||
...options,
|
||||
// don't use dynamic vite-plugin-svelte defaults here to ensure stable result between ssr,dev and build
|
||||
compilerOptions: {
|
||||
dev: false,
|
||||
css: false,
|
||||
hydratable: false,
|
||||
enableSourcemap: query.sourcemap
|
||||
? {
|
||||
js: type === 'script' || type === 'all',
|
||||
css: type === 'style' || type === 'all'
|
||||
}
|
||||
: false,
|
||||
...svelteRequest.query.compilerOptions
|
||||
},
|
||||
hot: false,
|
||||
emitCss: true
|
||||
});
|
||||
} catch (e) {
|
||||
throw toRollupError(e, options);
|
||||
}
|
||||
let result;
|
||||
if (query.type === 'style') {
|
||||
result = compileData.compiled.css;
|
||||
} else if (query.type === 'script') {
|
||||
result = compileData.compiled.js;
|
||||
} else if (query.type === 'preprocessed') {
|
||||
result = compileData.preprocessed;
|
||||
} else if (query.type === 'all' && query.raw) {
|
||||
return allToRawExports(compileData, source);
|
||||
} else {
|
||||
throw new Error(
|
||||
`invalid "type=${query.type}" in ${id}. supported are script, style, preprocessed, all`
|
||||
);
|
||||
}
|
||||
if (query.direct) {
|
||||
const supportedDirectTypes = ['script', 'style'];
|
||||
if (!supportedDirectTypes.includes(query.type)) {
|
||||
throw new Error(
|
||||
`invalid "type=${
|
||||
query.type
|
||||
}" combined with direct in ${id}. supported are: ${supportedDirectTypes.join(', ')}`
|
||||
);
|
||||
}
|
||||
log.debug(`load returns direct result for ${id}`);
|
||||
let directOutput = result.code;
|
||||
if (query.sourcemap && result.map?.toUrl) {
|
||||
const map = `sourceMappingURL=${result.map.toUrl()}`;
|
||||
if (query.type === 'style') {
|
||||
directOutput += `\n\n/*# ${map} */\n`;
|
||||
} else if (query.type === 'script') {
|
||||
directOutput += `\n\n//# ${map}\n`;
|
||||
}
|
||||
}
|
||||
return directOutput;
|
||||
} else if (query.raw) {
|
||||
log.debug(`load returns raw result for ${id}`);
|
||||
return toRawExports(result);
|
||||
} else {
|
||||
throw new Error(`invalid raw mode in ${id}, supported are raw, direct`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* turn compileData and source into a flat list of raw exports
|
||||
*
|
||||
* @param {import('../types/compile.d.ts').CompileData} compileData
|
||||
* @param {string} source
|
||||
*/
|
||||
function allToRawExports(compileData, source) {
|
||||
// flatten CompileData
|
||||
/** @type {Partial<import('../types/compile.d.ts').CompileData & { source: string }>} */
|
||||
const exports = {
|
||||
...compileData,
|
||||
...compileData.compiled,
|
||||
source
|
||||
};
|
||||
delete exports.compiled;
|
||||
delete exports.filename; // absolute path, remove to avoid it in output
|
||||
return toRawExports(exports);
|
||||
}
|
||||
|
||||
/**
|
||||
* turn object into raw exports.
|
||||
*
|
||||
* every prop is returned as a const export, and if prop 'code' exists it is additionally added as default export
|
||||
*
|
||||
* eg {'foo':'bar','code':'baz'} results in
|
||||
*
|
||||
* ```js
|
||||
* export const code='baz'
|
||||
* export const foo='bar'
|
||||
* export default code
|
||||
* ```
|
||||
* @param {object} object
|
||||
* @returns {string}
|
||||
*/
|
||||
function toRawExports(object) {
|
||||
let exports =
|
||||
Object.entries(object)
|
||||
//eslint-disable-next-line no-unused-vars
|
||||
.filter(([key, value]) => typeof value !== 'function') // preprocess output has a toString function that's enumerable
|
||||
.sort(([a], [b]) => (a < b ? -1 : a === b ? 0 : 1))
|
||||
.map(([key, value]) => `export const ${key}=${JSON.stringify(value)}`)
|
||||
.join('\n') + '\n';
|
||||
if (Object.prototype.hasOwnProperty.call(object, 'code')) {
|
||||
exports += 'export default code\n';
|
||||
}
|
||||
return exports;
|
||||
}
|
117
node_modules/@sveltejs/vite-plugin-svelte/src/utils/load-svelte-config.js
generated
vendored
Normal file
117
node_modules/@sveltejs/vite-plugin-svelte/src/utils/load-svelte-config.js
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
import { createRequire } from 'node:module';
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { log } from './log.js';
|
||||
|
||||
// used to require cjs config in esm.
|
||||
// NOTE dynamic import() cjs technically works, but timestamp query cache bust
|
||||
// have no effect, likely because it has another internal cache?
|
||||
/** @type {NodeRequire}*/
|
||||
let esmRequire;
|
||||
|
||||
export const knownSvelteConfigNames = [
|
||||
'svelte.config.js',
|
||||
'svelte.config.cjs',
|
||||
'svelte.config.mjs'
|
||||
];
|
||||
|
||||
// hide dynamic import from ts transform to prevent it turning into a require
|
||||
// see https://github.com/microsoft/TypeScript/issues/43329#issuecomment-811606238
|
||||
// also use timestamp query to avoid caching on reload
|
||||
const dynamicImportDefault = new Function(
|
||||
'path',
|
||||
'timestamp',
|
||||
'return import(path + "?t=" + timestamp).then(m => m.default)'
|
||||
);
|
||||
|
||||
/** @type {import('../index.d.ts').loadSvelteConfig} */
|
||||
export async function loadSvelteConfig(viteConfig, inlineOptions) {
|
||||
if (inlineOptions?.configFile === false) {
|
||||
return;
|
||||
}
|
||||
const configFile = findConfigToLoad(viteConfig, inlineOptions);
|
||||
if (configFile) {
|
||||
let err;
|
||||
// try to use dynamic import for svelte.config.js first
|
||||
if (configFile.endsWith('.js') || configFile.endsWith('.mjs')) {
|
||||
try {
|
||||
const result = await dynamicImportDefault(
|
||||
pathToFileURL(configFile).href,
|
||||
fs.statSync(configFile).mtimeMs
|
||||
);
|
||||
if (result != null) {
|
||||
return {
|
||||
...result,
|
||||
configFile
|
||||
};
|
||||
} else {
|
||||
throw new Error(`invalid export in ${configFile}`);
|
||||
}
|
||||
} catch (e) {
|
||||
log.error(`failed to import config ${configFile}`, e);
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
// cjs or error with dynamic import
|
||||
if (!configFile.endsWith('.mjs')) {
|
||||
try {
|
||||
// identify which require function to use (esm and cjs mode)
|
||||
const _require = import.meta.url
|
||||
? esmRequire ?? (esmRequire = createRequire(import.meta.url))
|
||||
: require;
|
||||
|
||||
// avoid loading cached version on reload
|
||||
delete _require.cache[_require.resolve(configFile)];
|
||||
const result = _require(configFile);
|
||||
if (result != null) {
|
||||
return {
|
||||
...result,
|
||||
configFile
|
||||
};
|
||||
} else {
|
||||
throw new Error(`invalid export in ${configFile}`);
|
||||
}
|
||||
} catch (e) {
|
||||
log.error(`failed to require config ${configFile}`, e);
|
||||
if (!err) {
|
||||
err = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
// failed to load existing config file
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('vite').UserConfig | undefined} viteConfig
|
||||
* @param {Partial<import('../index.d.ts').Options> | undefined} inlineOptions
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function findConfigToLoad(viteConfig, inlineOptions) {
|
||||
const root = viteConfig?.root || process.cwd();
|
||||
if (inlineOptions?.configFile) {
|
||||
const abolutePath = path.isAbsolute(inlineOptions.configFile)
|
||||
? inlineOptions.configFile
|
||||
: path.resolve(root, inlineOptions.configFile);
|
||||
if (!fs.existsSync(abolutePath)) {
|
||||
throw new Error(`failed to find svelte config file ${abolutePath}.`);
|
||||
}
|
||||
return abolutePath;
|
||||
} else {
|
||||
const existingKnownConfigFiles = knownSvelteConfigNames
|
||||
.map((candidate) => path.resolve(root, candidate))
|
||||
.filter((file) => fs.existsSync(file));
|
||||
if (existingKnownConfigFiles.length === 0) {
|
||||
log.debug(`no svelte config found at ${root}`);
|
||||
return;
|
||||
} else if (existingKnownConfigFiles.length > 1) {
|
||||
log.warn(
|
||||
`found more than one svelte config file, using ${existingKnownConfigFiles[0]}. you should only have one!`,
|
||||
existingKnownConfigFiles
|
||||
);
|
||||
}
|
||||
return existingKnownConfigFiles[0];
|
||||
}
|
||||
}
|
255
node_modules/@sveltejs/vite-plugin-svelte/src/utils/log.js
generated
vendored
Normal file
255
node_modules/@sveltejs/vite-plugin-svelte/src/utils/log.js
generated
vendored
Normal file
@ -0,0 +1,255 @@
|
||||
/* eslint-disable no-console */
|
||||
import { cyan, red, yellow } from 'kleur/colors';
|
||||
import debug from 'debug';
|
||||
|
||||
/** @type {import('../types/log.d.ts').LogLevel[]} */
|
||||
const levels = ['debug', 'info', 'warn', 'error', 'silent'];
|
||||
const prefix = 'vite-plugin-svelte';
|
||||
/** @type {Record<import('../types/log.d.ts').LogLevel, any>} */
|
||||
const loggers = {
|
||||
debug: {
|
||||
log: debug(`vite:${prefix}`),
|
||||
enabled: false,
|
||||
isDebug: true
|
||||
},
|
||||
info: {
|
||||
color: cyan,
|
||||
log: console.log,
|
||||
enabled: true
|
||||
},
|
||||
warn: {
|
||||
color: yellow,
|
||||
log: console.warn,
|
||||
enabled: true
|
||||
},
|
||||
error: {
|
||||
color: red,
|
||||
log: console.error,
|
||||
enabled: true
|
||||
},
|
||||
silent: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {import('../types/log.d.ts').LogLevel} */
|
||||
let _level = 'info';
|
||||
/**
|
||||
* @param {import('../types/log.d.ts').LogLevel} level
|
||||
* @returns {void}
|
||||
*/
|
||||
function setLevel(level) {
|
||||
if (level === _level) {
|
||||
return;
|
||||
}
|
||||
const levelIndex = levels.indexOf(level);
|
||||
if (levelIndex > -1) {
|
||||
_level = level;
|
||||
for (let i = 0; i < levels.length; i++) {
|
||||
loggers[levels[i]].enabled = i >= levelIndex;
|
||||
}
|
||||
} else {
|
||||
_log(loggers.error, `invalid log level: ${level} `);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} logger
|
||||
* @param {string} message
|
||||
* @param {any} [payload]
|
||||
* @param {string} [namespace]
|
||||
* @returns
|
||||
*/
|
||||
function _log(logger, message, payload, namespace) {
|
||||
if (!logger.enabled) {
|
||||
return;
|
||||
}
|
||||
if (logger.isDebug) {
|
||||
const log = namespace ? logger.log.extend(namespace) : logger.log;
|
||||
payload !== undefined ? log(message, payload) : log(message);
|
||||
} else {
|
||||
logger.log(
|
||||
logger.color(
|
||||
`${new Date().toLocaleTimeString()} [${prefix}${
|
||||
namespace ? `:${namespace}` : ''
|
||||
}] ${message}`
|
||||
)
|
||||
);
|
||||
if (payload) {
|
||||
logger.log(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/log.d.ts').LogLevel} level
|
||||
* @returns {import('../types/log.d.ts').LogFn}
|
||||
*/
|
||||
function createLogger(level) {
|
||||
const logger = loggers[level];
|
||||
const logFn = /** @type {import('../types/log.d.ts').LogFn} */ (_log.bind(null, logger));
|
||||
/** @type {Set<string>} */
|
||||
const logged = new Set();
|
||||
/** @type {import('../types/log.d.ts').SimpleLogFn} */
|
||||
const once = function (message, payload, namespace) {
|
||||
if (!logger.enabled || logged.has(message)) {
|
||||
return;
|
||||
}
|
||||
logged.add(message);
|
||||
logFn.apply(null, [message, payload, namespace]);
|
||||
};
|
||||
Object.defineProperty(logFn, 'enabled', {
|
||||
get() {
|
||||
return logger.enabled;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(logFn, 'once', {
|
||||
get() {
|
||||
return once;
|
||||
}
|
||||
});
|
||||
return logFn;
|
||||
}
|
||||
|
||||
export const log = {
|
||||
debug: createLogger('debug'),
|
||||
info: createLogger('info'),
|
||||
warn: createLogger('warn'),
|
||||
error: createLogger('error'),
|
||||
setLevel
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest | import('../types/id.d.ts').SvelteModuleRequest} svelteRequest
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning[]} warnings
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
export function logCompilerWarnings(svelteRequest, warnings, options) {
|
||||
const { emitCss, onwarn, isBuild } = options;
|
||||
const sendViaWS = !isBuild && options.experimental?.sendWarningsToBrowser;
|
||||
let warn = isBuild ? warnBuild : warnDev;
|
||||
/** @type {import('svelte/types/compiler/interfaces').Warning[]} */
|
||||
const handledByDefaultWarn = [];
|
||||
const notIgnored = warnings?.filter((w) => !ignoreCompilerWarning(w, isBuild, emitCss));
|
||||
const extra = buildExtraWarnings(warnings, isBuild);
|
||||
const allWarnings = [...notIgnored, ...extra];
|
||||
if (sendViaWS) {
|
||||
const _warn = warn;
|
||||
/** @type {(w: import('svelte/types/compiler/interfaces').Warning) => void} */
|
||||
warn = (w) => {
|
||||
handledByDefaultWarn.push(w);
|
||||
_warn(w);
|
||||
};
|
||||
}
|
||||
allWarnings.forEach((warning) => {
|
||||
if (onwarn) {
|
||||
onwarn(warning, warn);
|
||||
} else {
|
||||
warn(warning);
|
||||
}
|
||||
});
|
||||
if (sendViaWS) {
|
||||
/** @type {import('../types/log.d.ts').SvelteWarningsMessage} */
|
||||
const message = {
|
||||
id: svelteRequest.id,
|
||||
filename: svelteRequest.filename,
|
||||
normalizedFilename: svelteRequest.normalizedFilename,
|
||||
timestamp: svelteRequest.timestamp,
|
||||
warnings: handledByDefaultWarn, // allWarnings filtered by warnings where onwarn did not call the default handler
|
||||
allWarnings, // includes warnings filtered by onwarn and our extra vite plugin svelte warnings
|
||||
rawWarnings: warnings // raw compiler output
|
||||
};
|
||||
log.debug(`sending svelte:warnings message for ${svelteRequest.normalizedFilename}`);
|
||||
options.server?.ws?.send('svelte:warnings', message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning} warning
|
||||
* @param {boolean} isBuild
|
||||
* @param {boolean} [emitCss]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function ignoreCompilerWarning(warning, isBuild, emitCss) {
|
||||
return (
|
||||
(!emitCss && warning.code === 'css-unused-selector') || // same as rollup-plugin-svelte
|
||||
(!isBuild && isNoScopableElementWarning(warning))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning} warning
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNoScopableElementWarning(warning) {
|
||||
// see https://github.com/sveltejs/vite-plugin-svelte/issues/153
|
||||
return warning.code === 'css-unused-selector' && warning.message.includes('"*"');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning[]} warnings
|
||||
* @param {boolean} isBuild
|
||||
* @returns {import('svelte/types/compiler/interfaces').Warning[]}
|
||||
*/
|
||||
function buildExtraWarnings(warnings, isBuild) {
|
||||
const extraWarnings = [];
|
||||
if (!isBuild) {
|
||||
const noScopableElementWarnings = warnings.filter((w) => isNoScopableElementWarning(w));
|
||||
if (noScopableElementWarnings.length > 0) {
|
||||
// in case there are multiple, use last one as that is the one caused by our *{} rule
|
||||
const noScopableElementWarning =
|
||||
noScopableElementWarnings[noScopableElementWarnings.length - 1];
|
||||
extraWarnings.push({
|
||||
...noScopableElementWarning,
|
||||
code: 'vite-plugin-svelte-css-no-scopable-elements',
|
||||
message:
|
||||
"No scopable elements found in template. If you're using global styles in the style tag, you should move it into an external stylesheet file and import it in JS. See https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/faq.md#where-should-i-put-my-global-styles."
|
||||
});
|
||||
}
|
||||
}
|
||||
return extraWarnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning} w
|
||||
*/
|
||||
function warnDev(w) {
|
||||
log.info.enabled && log.info(buildExtendedLogMessage(w));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning} w
|
||||
*/
|
||||
function warnBuild(w) {
|
||||
log.warn.enabled && log.warn(buildExtendedLogMessage(w), w.frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('svelte/types/compiler/interfaces').Warning} w
|
||||
*/
|
||||
export function buildExtendedLogMessage(w) {
|
||||
const parts = [];
|
||||
if (w.filename) {
|
||||
parts.push(w.filename);
|
||||
}
|
||||
if (w.start) {
|
||||
parts.push(':', w.start.line, ':', w.start.column);
|
||||
}
|
||||
if (w.message) {
|
||||
if (parts.length > 0) {
|
||||
parts.push(' ');
|
||||
}
|
||||
parts.push(w.message);
|
||||
}
|
||||
return parts.join('');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} namespace
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isDebugNamespaceEnabled(namespace) {
|
||||
return debug.enabled(`vite:${prefix}:${namespace}`);
|
||||
}
|
53
node_modules/@sveltejs/vite-plugin-svelte/src/utils/optimizer.js
generated
vendored
Normal file
53
node_modules/@sveltejs/vite-plugin-svelte/src/utils/optimizer.js
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
import { promises as fs } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
// List of options that changes the prebundling result
|
||||
/** @type {(keyof import('../types/options.d.ts').ResolvedOptions)[]} */
|
||||
const PREBUNDLE_SENSITIVE_OPTIONS = [
|
||||
'compilerOptions',
|
||||
'configFile',
|
||||
'experimental',
|
||||
'extensions',
|
||||
'ignorePluginPreprocessors',
|
||||
'preprocess'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string} cacheDir
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {Promise<boolean>} Whether the Svelte metadata has changed
|
||||
*/
|
||||
export async function saveSvelteMetadata(cacheDir, options) {
|
||||
const svelteMetadata = generateSvelteMetadata(options);
|
||||
const svelteMetadataPath = path.resolve(cacheDir, '_svelte_metadata.json');
|
||||
|
||||
const currentSvelteMetadata = JSON.stringify(svelteMetadata, (_, value) => {
|
||||
// Handle preprocessors
|
||||
return typeof value === 'function' ? value.toString() : value;
|
||||
});
|
||||
|
||||
/** @type {string | undefined} */
|
||||
let existingSvelteMetadata;
|
||||
try {
|
||||
existingSvelteMetadata = await fs.readFile(svelteMetadataPath, 'utf8');
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
await fs.mkdir(cacheDir, { recursive: true });
|
||||
await fs.writeFile(svelteMetadataPath, currentSvelteMetadata);
|
||||
return currentSvelteMetadata !== existingSvelteMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @returns {Partial<import('../types/options.d.ts').ResolvedOptions>}
|
||||
*/
|
||||
function generateSvelteMetadata(options) {
|
||||
/** @type {Record<string, any>} */
|
||||
const metadata = {};
|
||||
for (const key of PREBUNDLE_SENSITIVE_OPTIONS) {
|
||||
metadata[key] = options[key];
|
||||
}
|
||||
return metadata;
|
||||
}
|
617
node_modules/@sveltejs/vite-plugin-svelte/src/utils/options.js
generated
vendored
Normal file
617
node_modules/@sveltejs/vite-plugin-svelte/src/utils/options.js
generated
vendored
Normal file
@ -0,0 +1,617 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { normalizePath } from 'vite';
|
||||
import { isDebugNamespaceEnabled, log } from './log.js';
|
||||
import { loadSvelteConfig } from './load-svelte-config.js';
|
||||
import {
|
||||
SVELTE_EXPORT_CONDITIONS,
|
||||
SVELTE_HMR_IMPORTS,
|
||||
SVELTE_IMPORTS,
|
||||
SVELTE_RESOLVE_MAIN_FIELDS,
|
||||
VITE_RESOLVE_MAIN_FIELDS
|
||||
} from './constants.js';
|
||||
|
||||
import path from 'node:path';
|
||||
import { esbuildSveltePlugin, facadeEsbuildSveltePluginName } from './esbuild.js';
|
||||
import { addExtraPreprocessors } from './preprocess.js';
|
||||
import deepmerge from 'deepmerge';
|
||||
import {
|
||||
crawlFrameworkPkgs,
|
||||
isDepExcluded,
|
||||
isDepExternaled,
|
||||
isDepIncluded,
|
||||
isDepNoExternaled
|
||||
} from 'vitefu';
|
||||
|
||||
import { isCommonDepWithoutSvelteField } from './dependencies.js';
|
||||
import { VitePluginSvelteStats } from './vite-plugin-svelte-stats.js';
|
||||
import { VitePluginSvelteCache } from './vite-plugin-svelte-cache.js';
|
||||
import { isSvelte5 } from './svelte-version.js';
|
||||
|
||||
const allowedPluginOptions = new Set([
|
||||
'include',
|
||||
'exclude',
|
||||
'emitCss',
|
||||
'hot',
|
||||
'ignorePluginPreprocessors',
|
||||
'disableDependencyReinclusion',
|
||||
'prebundleSvelteLibraries',
|
||||
'inspector',
|
||||
'experimental'
|
||||
]);
|
||||
|
||||
const knownRootOptions = new Set(['extensions', 'compilerOptions', 'preprocess', 'onwarn']);
|
||||
|
||||
const allowedInlineOptions = new Set(['configFile', ...allowedPluginOptions, ...knownRootOptions]);
|
||||
|
||||
/**
|
||||
* @param {Partial<import('../index.d.ts').Options>} [inlineOptions]
|
||||
*/
|
||||
export function validateInlineOptions(inlineOptions) {
|
||||
const invalidKeys = Object.keys(inlineOptions || {}).filter(
|
||||
(key) => !allowedInlineOptions.has(key)
|
||||
);
|
||||
if (invalidKeys.length) {
|
||||
log.warn(`invalid plugin options "${invalidKeys.join(', ')}" in inline config`, inlineOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Partial<import('../index.d.ts').SvelteOptions>} [config]
|
||||
* @returns {Partial<import('../index.d.ts').Options> | undefined}
|
||||
*/
|
||||
function convertPluginOptions(config) {
|
||||
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];
|
||||
});
|
||||
}
|
||||
/** @type {import('../index.d.ts').Options} */
|
||||
const result = {
|
||||
...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
|
||||
* @param {Partial<import('../index.d.ts').Options> | undefined} inlineOptions
|
||||
* @param {import('vite').UserConfig} viteUserConfig
|
||||
* @param {import('vite').ConfigEnv} viteEnv
|
||||
* @returns {Promise<import('../types/options.d.ts').PreResolvedOptions>}
|
||||
*/
|
||||
export async function preResolveOptions(inlineOptions, viteUserConfig, viteEnv) {
|
||||
if (!inlineOptions) {
|
||||
inlineOptions = {};
|
||||
}
|
||||
/** @type {import('vite').UserConfig} */
|
||||
const viteConfigWithResolvedRoot = {
|
||||
...viteUserConfig,
|
||||
root: resolveViteRoot(viteUserConfig)
|
||||
};
|
||||
const isBuild = viteEnv.command === 'build';
|
||||
/** @type {Partial<import('../types/options.d.ts').PreResolvedOptions>} */
|
||||
const defaultOptions = {
|
||||
extensions: ['.svelte'],
|
||||
emitCss: true,
|
||||
prebundleSvelteLibraries: !isBuild
|
||||
};
|
||||
const svelteConfig = convertPluginOptions(
|
||||
await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)
|
||||
);
|
||||
/** @type {Partial<import('../types/options.d.ts').PreResolvedOptions>} */
|
||||
const extraOptions = {
|
||||
root: viteConfigWithResolvedRoot.root,
|
||||
isBuild,
|
||||
isServe: viteEnv.command === 'serve',
|
||||
isDebug: process.env.DEBUG != null
|
||||
};
|
||||
|
||||
const merged = /** @type {import('../types/options.d.ts').PreResolvedOptions} */ (
|
||||
mergeConfigs(defaultOptions, svelteConfig, inlineOptions, extraOptions)
|
||||
);
|
||||
// configFile of svelteConfig contains the absolute path it was loaded from,
|
||||
// prefer it over the possibly relative inline path
|
||||
if (svelteConfig?.configFile) {
|
||||
merged.configFile = svelteConfig.configFile;
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {(Partial<T> | undefined)[]} configs
|
||||
* @returns T
|
||||
*/
|
||||
function mergeConfigs(...configs) {
|
||||
/** @type {Partial<T>} */
|
||||
let result = {};
|
||||
for (const config of configs.filter((x) => x != null)) {
|
||||
result = deepmerge(result, /** @type {Partial<T>} */ (config), {
|
||||
// replace arrays
|
||||
arrayMerge: (target, source) => source ?? target
|
||||
});
|
||||
}
|
||||
return /** @type {T} */ result;
|
||||
}
|
||||
|
||||
/**
|
||||
* used in configResolved phase, merges a contextual default config, pre-resolved options, and some preprocessors. also validates the final config.
|
||||
*
|
||||
* @param {import('../types/options.d.ts').PreResolvedOptions} preResolveOptions
|
||||
* @param {import('vite').ResolvedConfig} viteConfig
|
||||
* @param {VitePluginSvelteCache} cache
|
||||
* @returns {import('../types/options.d.ts').ResolvedOptions}
|
||||
*/
|
||||
export function resolveOptions(preResolveOptions, viteConfig, cache) {
|
||||
const css = preResolveOptions.emitCss ? 'external' : 'injected';
|
||||
/** @type {Partial<import('../index.d.ts').Options>} */
|
||||
const defaultOptions = {
|
||||
hot: viteConfig.isProduction
|
||||
? false
|
||||
: {
|
||||
injectCss: css === 'injected',
|
||||
partialAccept: !!viteConfig.experimental?.hmrPartialAccept
|
||||
},
|
||||
compilerOptions: {
|
||||
css,
|
||||
dev: !viteConfig.isProduction
|
||||
}
|
||||
};
|
||||
/** @type {Partial<import('../types/options.d.ts').ResolvedOptions>} */
|
||||
const extraOptions = {
|
||||
root: viteConfig.root,
|
||||
isProduction: viteConfig.isProduction
|
||||
};
|
||||
const merged = /** @type {import('../types/options.d.ts').ResolvedOptions}*/ (
|
||||
mergeConfigs(defaultOptions, preResolveOptions, extraOptions)
|
||||
);
|
||||
|
||||
removeIgnoredOptions(merged);
|
||||
handleDeprecatedOptions(merged);
|
||||
addExtraPreprocessors(merged, viteConfig);
|
||||
enforceOptionsForHmr(merged);
|
||||
enforceOptionsForProduction(merged);
|
||||
// mergeConfigs would mangle functions on the stats class, so do this afterwards
|
||||
if (log.debug.enabled && isDebugNamespaceEnabled('stats')) {
|
||||
merged.stats = new VitePluginSvelteStats(cache);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
function enforceOptionsForHmr(options) {
|
||||
if (isSvelte5) {
|
||||
log.warn('svelte 5 does not support hmr api yet, disabling it for now');
|
||||
options.hot = false;
|
||||
}
|
||||
if (options.hot) {
|
||||
if (!options.compilerOptions.dev) {
|
||||
log.warn('hmr is enabled but compilerOptions.dev is false, forcing it to true');
|
||||
options.compilerOptions.dev = true;
|
||||
}
|
||||
if (options.emitCss) {
|
||||
if (options.hot !== true && options.hot.injectCss) {
|
||||
log.warn('hmr and emitCss are enabled but hot.injectCss is true, forcing it to false');
|
||||
options.hot.injectCss = false;
|
||||
}
|
||||
const css = options.compilerOptions.css;
|
||||
if (css === true || css === 'injected') {
|
||||
const forcedCss = 'external';
|
||||
log.warn(
|
||||
`hmr and emitCss are enabled but compilerOptions.css is ${css}, forcing it to ${forcedCss}`
|
||||
);
|
||||
options.compilerOptions.css = forcedCss;
|
||||
}
|
||||
} else {
|
||||
if (options.hot === true || !options.hot.injectCss) {
|
||||
log.warn(
|
||||
'hmr with emitCss disabled requires option hot.injectCss to be enabled, forcing it to true'
|
||||
);
|
||||
if (options.hot === true) {
|
||||
options.hot = { injectCss: true };
|
||||
} else {
|
||||
options.hot.injectCss = true;
|
||||
}
|
||||
}
|
||||
const css = options.compilerOptions.css;
|
||||
if (!(css === true || css === 'injected')) {
|
||||
const forcedCss = 'injected';
|
||||
log.warn(
|
||||
`hmr with emitCss disabled requires compilerOptions.css to be enabled, forcing it to ${forcedCss}`
|
||||
);
|
||||
options.compilerOptions.css = forcedCss;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
function enforceOptionsForProduction(options) {
|
||||
if (options.isProduction) {
|
||||
if (options.hot) {
|
||||
log.warn('options.hot is enabled but does not work on production build, forcing it to false');
|
||||
options.hot = false;
|
||||
}
|
||||
if (options.compilerOptions.dev) {
|
||||
log.warn(
|
||||
'you are building for production but compilerOptions.dev is true, forcing it to false'
|
||||
);
|
||||
options.compilerOptions.dev = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
function removeIgnoredOptions(options) {
|
||||
const ignoredCompilerOptions = ['generate', 'format', 'filename'];
|
||||
if (options.hot && options.emitCss) {
|
||||
ignoredCompilerOptions.push('cssHash');
|
||||
}
|
||||
const passedCompilerOptions = Object.keys(options.compilerOptions || {});
|
||||
const passedIgnored = passedCompilerOptions.filter((o) => ignoredCompilerOptions.includes(o));
|
||||
if (passedIgnored.length) {
|
||||
log.warn(
|
||||
`The following Svelte compilerOptions are controlled by vite-plugin-svelte and essential to its functionality. User-specified values are ignored. Please remove them from your configuration: ${passedIgnored.join(
|
||||
', '
|
||||
)}`
|
||||
);
|
||||
passedIgnored.forEach((ignored) => {
|
||||
// @ts-expect-error string access
|
||||
delete options.compilerOptions[ignored];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
function handleDeprecatedOptions(options) {
|
||||
const experimental = /** @type {Record<string, any>} */ (options.experimental);
|
||||
if (experimental) {
|
||||
for (const promoted of ['prebundleSvelteLibraries', 'inspector']) {
|
||||
if (experimental[promoted]) {
|
||||
//@ts-expect-error untyped assign
|
||||
options[promoted] = experimental[promoted];
|
||||
delete experimental[promoted];
|
||||
log.warn(
|
||||
`Option "vitePlugin.experimental.${promoted}" is no longer experimental and has moved to "vitePlugin.${promoted}". Please update your svelte config.`
|
||||
);
|
||||
}
|
||||
}
|
||||
if (experimental.generateMissingPreprocessorSourcemaps) {
|
||||
log.warn('experimental.generateMissingPreprocessorSourcemaps has been removed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vite passes unresolved `root`option to config hook but we need the resolved value, so do it here
|
||||
*
|
||||
* @see https://github.com/sveltejs/vite-plugin-svelte/issues/113
|
||||
* @see https://github.com/vitejs/vite/blob/43c957de8a99bb326afd732c962f42127b0a4d1e/packages/vite/src/node/config.ts#L293
|
||||
*
|
||||
* @param {import('vite').UserConfig} viteConfig
|
||||
* @returns {string | undefined}
|
||||
*/
|
||||
function resolveViteRoot(viteConfig) {
|
||||
return normalizePath(viteConfig.root ? path.resolve(viteConfig.root) : process.cwd());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').PreResolvedOptions} options
|
||||
* @param {import('vite').UserConfig} config
|
||||
* @returns {Promise<Partial<import('vite').UserConfig>>}
|
||||
*/
|
||||
export async function buildExtraViteConfig(options, config) {
|
||||
// make sure we only readd vite default mainFields when no other plugin has changed the config already
|
||||
// see https://github.com/sveltejs/vite-plugin-svelte/issues/581
|
||||
if (!config.resolve) {
|
||||
config.resolve = {};
|
||||
}
|
||||
config.resolve.mainFields = [
|
||||
...SVELTE_RESOLVE_MAIN_FIELDS,
|
||||
...(config.resolve.mainFields ?? VITE_RESOLVE_MAIN_FIELDS)
|
||||
];
|
||||
|
||||
/** @type {Partial<import('vite').UserConfig>} */
|
||||
const extraViteConfig = {
|
||||
resolve: {
|
||||
dedupe: [...SVELTE_IMPORTS, ...SVELTE_HMR_IMPORTS],
|
||||
conditions: [...SVELTE_EXPORT_CONDITIONS]
|
||||
}
|
||||
// this option is still awaiting a PR in vite to be supported
|
||||
// see https://github.com/sveltejs/vite-plugin-svelte/issues/60
|
||||
// @ts-ignore
|
||||
// knownJsSrcExtensions: options.extensions
|
||||
};
|
||||
|
||||
const extraSvelteConfig = buildExtraConfigForSvelte(config);
|
||||
const extraDepsConfig = await buildExtraConfigForDependencies(options, config);
|
||||
// merge extra svelte and deps config, but make sure dep values are not contradicting svelte
|
||||
extraViteConfig.optimizeDeps = {
|
||||
include: [
|
||||
...extraSvelteConfig.optimizeDeps.include,
|
||||
...extraDepsConfig.optimizeDeps.include.filter(
|
||||
(dep) => !isDepExcluded(dep, extraSvelteConfig.optimizeDeps.exclude)
|
||||
)
|
||||
],
|
||||
exclude: [
|
||||
...extraSvelteConfig.optimizeDeps.exclude,
|
||||
...extraDepsConfig.optimizeDeps.exclude.filter(
|
||||
(dep) => !isDepIncluded(dep, extraSvelteConfig.optimizeDeps.include)
|
||||
)
|
||||
]
|
||||
};
|
||||
|
||||
extraViteConfig.ssr = {
|
||||
external: [
|
||||
...extraSvelteConfig.ssr.external,
|
||||
...extraDepsConfig.ssr.external.filter(
|
||||
(dep) => !isDepNoExternaled(dep, extraSvelteConfig.ssr.noExternal)
|
||||
)
|
||||
],
|
||||
noExternal: [
|
||||
...extraSvelteConfig.ssr.noExternal,
|
||||
...extraDepsConfig.ssr.noExternal.filter(
|
||||
(dep) => !isDepExternaled(dep, extraSvelteConfig.ssr.external)
|
||||
)
|
||||
]
|
||||
};
|
||||
|
||||
// handle prebundling for svelte files
|
||||
if (options.prebundleSvelteLibraries) {
|
||||
extraViteConfig.optimizeDeps = {
|
||||
...extraViteConfig.optimizeDeps,
|
||||
// Experimental Vite API to allow these extensions to be scanned and prebundled
|
||||
// @ts-ignore
|
||||
extensions: options.extensions ?? ['.svelte'],
|
||||
// Add esbuild plugin to prebundle Svelte files.
|
||||
// Currently a placeholder as more information is needed after Vite config is resolved,
|
||||
// the real Svelte plugin is added in `patchResolvedViteConfig()`
|
||||
esbuildOptions: {
|
||||
plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {} }]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// enable hmrPartialAccept if not explicitly disabled
|
||||
if (
|
||||
(options.hot == null ||
|
||||
options.hot === true ||
|
||||
(options.hot && options.hot.partialAccept !== false)) && // deviate from svelte-hmr, default to true
|
||||
config.experimental?.hmrPartialAccept !== false
|
||||
) {
|
||||
log.debug('enabling "experimental.hmrPartialAccept" in vite config');
|
||||
extraViteConfig.experimental = { hmrPartialAccept: true };
|
||||
}
|
||||
validateViteConfig(extraViteConfig, config, options);
|
||||
return extraViteConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Partial<import('vite').UserConfig>} extraViteConfig
|
||||
* @param {import('vite').UserConfig} config
|
||||
* @param {import('../types/options.d.ts').PreResolvedOptions} options
|
||||
*/
|
||||
function validateViteConfig(extraViteConfig, config, options) {
|
||||
const { prebundleSvelteLibraries, isBuild } = options;
|
||||
if (prebundleSvelteLibraries) {
|
||||
/** @type {(option: 'dev' | 'build' | boolean)=> boolean} */
|
||||
const isEnabled = (option) => option !== true && option !== (isBuild ? 'build' : 'dev');
|
||||
/** @type {(name: string, value: 'dev' | 'build' | boolean, recommendation: string)=> void} */
|
||||
const logWarning = (name, value, recommendation) =>
|
||||
log.warn.once(
|
||||
`Incompatible options: \`prebundleSvelteLibraries: true\` and vite \`${name}: ${JSON.stringify(
|
||||
value
|
||||
)}\` ${isBuild ? 'during build.' : '.'} ${recommendation}`
|
||||
);
|
||||
const viteOptimizeDepsDisabled = config.optimizeDeps?.disabled ?? 'build'; // fall back to vite default
|
||||
const isOptimizeDepsEnabled = isEnabled(viteOptimizeDepsDisabled);
|
||||
if (!isBuild && !isOptimizeDepsEnabled) {
|
||||
logWarning(
|
||||
'optimizeDeps.disabled',
|
||||
viteOptimizeDepsDisabled,
|
||||
'Forcing `optimizeDeps.disabled: "build"`. Disable prebundleSvelteLibraries or update your vite config to enable optimizeDeps during dev.'
|
||||
);
|
||||
if (!extraViteConfig.optimizeDeps) {
|
||||
extraViteConfig.optimizeDeps = {};
|
||||
}
|
||||
extraViteConfig.optimizeDeps.disabled = 'build';
|
||||
} else if (isBuild && isOptimizeDepsEnabled) {
|
||||
logWarning(
|
||||
'optimizeDeps.disabled',
|
||||
viteOptimizeDepsDisabled,
|
||||
'Disable optimizeDeps or prebundleSvelteLibraries for build if you experience errors.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').PreResolvedOptions} options
|
||||
* @param {import('vite').UserConfig} config
|
||||
* @returns {Promise<import('vitefu').CrawlFrameworkPkgsResult>}
|
||||
*/
|
||||
async function buildExtraConfigForDependencies(options, config) {
|
||||
// extra handling for svelte dependencies in the project
|
||||
const depsConfig = await crawlFrameworkPkgs({
|
||||
root: options.root,
|
||||
isBuild: options.isBuild,
|
||||
viteUserConfig: config,
|
||||
isFrameworkPkgByJson(pkgJson) {
|
||||
let hasSvelteCondition = false;
|
||||
if (typeof pkgJson.exports === 'object') {
|
||||
// use replacer as a simple way to iterate over nested keys
|
||||
JSON.stringify(pkgJson.exports, (key, value) => {
|
||||
if (SVELTE_EXPORT_CONDITIONS.includes(key)) {
|
||||
hasSvelteCondition = true;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
}
|
||||
return hasSvelteCondition || !!pkgJson.svelte;
|
||||
},
|
||||
isSemiFrameworkPkgByJson(pkgJson) {
|
||||
return !!pkgJson.dependencies?.svelte || !!pkgJson.peerDependencies?.svelte;
|
||||
},
|
||||
isFrameworkPkgByName(pkgName) {
|
||||
const isNotSveltePackage = isCommonDepWithoutSvelteField(pkgName);
|
||||
if (isNotSveltePackage) {
|
||||
return false;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
log.debug('extra config for dependencies generated by vitefu', depsConfig);
|
||||
|
||||
if (options.prebundleSvelteLibraries) {
|
||||
// prebundling enabled, so we don't need extra dependency excludes
|
||||
depsConfig.optimizeDeps.exclude = [];
|
||||
// but keep dependency reinclusions of explicit user excludes
|
||||
const userExclude = config.optimizeDeps?.exclude;
|
||||
depsConfig.optimizeDeps.include = !userExclude
|
||||
? []
|
||||
: depsConfig.optimizeDeps.include.filter((dep) => {
|
||||
// reincludes look like this: foo > bar > baz
|
||||
// in case foo or bar are excluded, we have to retain the reinclude even with prebundling
|
||||
return (
|
||||
dep.includes('>') &&
|
||||
dep
|
||||
.split('>')
|
||||
.slice(0, -1)
|
||||
.some((d) => isDepExcluded(d.trim(), userExclude))
|
||||
);
|
||||
});
|
||||
}
|
||||
if (options.disableDependencyReinclusion === true) {
|
||||
depsConfig.optimizeDeps.include = depsConfig.optimizeDeps.include.filter(
|
||||
(dep) => !dep.includes('>')
|
||||
);
|
||||
} else if (Array.isArray(options.disableDependencyReinclusion)) {
|
||||
const disabledDeps = options.disableDependencyReinclusion;
|
||||
depsConfig.optimizeDeps.include = depsConfig.optimizeDeps.include.filter((dep) => {
|
||||
if (!dep.includes('>')) return true;
|
||||
const trimDep = dep.replace(/\s+/g, '');
|
||||
return disabledDeps.some((disabled) => trimDep.includes(`${disabled}>`));
|
||||
});
|
||||
}
|
||||
|
||||
log.debug('post-processed extra config for dependencies', depsConfig);
|
||||
|
||||
return depsConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('vite').UserConfig} config
|
||||
* @returns {import('vite').UserConfig & { optimizeDeps: { include: string[], exclude:string[] }, ssr: { noExternal:(string|RegExp)[], external: string[] } } }
|
||||
*/
|
||||
function buildExtraConfigForSvelte(config) {
|
||||
// include svelte imports for optimization unless explicitly excluded
|
||||
/** @type {string[]} */
|
||||
const include = [];
|
||||
const exclude = ['svelte-hmr'];
|
||||
if (!isDepExcluded('svelte', config.optimizeDeps?.exclude ?? [])) {
|
||||
const svelteImportsToInclude = SVELTE_IMPORTS.filter((x) => x !== 'svelte/ssr'); // not used on clientside
|
||||
log.debug(
|
||||
`adding bare svelte packages to optimizeDeps.include: ${svelteImportsToInclude.join(', ')} `
|
||||
);
|
||||
include.push(...svelteImportsToInclude);
|
||||
} else {
|
||||
log.debug('"svelte" is excluded in optimizeDeps.exclude, skipped adding it to include.');
|
||||
}
|
||||
/** @type {(string | RegExp)[]} */
|
||||
const noExternal = [];
|
||||
/** @type {string[]} */
|
||||
const external = [];
|
||||
// add svelte to ssr.noExternal unless it is present in ssr.external
|
||||
// so we can resolve it with svelte/ssr
|
||||
if (!isDepExternaled('svelte', config.ssr?.external ?? [])) {
|
||||
noExternal.push('svelte', /^svelte\//);
|
||||
}
|
||||
return { optimizeDeps: { include, exclude }, ssr: { noExternal, external } };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('vite').ResolvedConfig} viteConfig
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
*/
|
||||
export function patchResolvedViteConfig(viteConfig, options) {
|
||||
if (options.preprocess) {
|
||||
for (const preprocessor of arraify(options.preprocess)) {
|
||||
if (preprocessor.style && '__resolvedConfig' in preprocessor.style) {
|
||||
preprocessor.style.__resolvedConfig = viteConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// replace facade esbuild plugin with a real one
|
||||
const facadeEsbuildSveltePlugin = viteConfig.optimizeDeps.esbuildOptions?.plugins?.find(
|
||||
(plugin) => plugin.name === facadeEsbuildSveltePluginName
|
||||
);
|
||||
if (facadeEsbuildSveltePlugin) {
|
||||
Object.assign(facadeEsbuildSveltePlugin, esbuildSveltePlugin(options));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T | T[]} value
|
||||
* @returns {T[]}
|
||||
*/
|
||||
function arraify(value) {
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
118
node_modules/@sveltejs/vite-plugin-svelte/src/utils/preprocess.js
generated
vendored
Normal file
118
node_modules/@sveltejs/vite-plugin-svelte/src/utils/preprocess.js
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
import MagicString from 'magic-string';
|
||||
import { log } from './log.js';
|
||||
import path from 'node:path';
|
||||
|
||||
/**
|
||||
* this appends a *{} rule to component styles to force the svelte compiler to add style classes to all nodes
|
||||
* That means adding/removing class rules from <style> node won't trigger js updates as the scope classes are not changed
|
||||
*
|
||||
* only used during dev with enabled css hmr
|
||||
*
|
||||
* @returns {import('svelte/types/compiler/preprocess').PreprocessorGroup}
|
||||
*/
|
||||
export function createInjectScopeEverythingRulePreprocessorGroup() {
|
||||
return {
|
||||
style({ content, filename }) {
|
||||
const s = new MagicString(content);
|
||||
s.append(' *{}');
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: s.generateDecodedMap({
|
||||
source: filename ? path.basename(filename) : undefined,
|
||||
hires: true
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @param {import('vite').ResolvedConfig} config
|
||||
* @returns {{
|
||||
* prependPreprocessors: import('svelte/types/compiler/preprocess').PreprocessorGroup[],
|
||||
* appendPreprocessors: import('svelte/types/compiler/preprocess').PreprocessorGroup[]
|
||||
* }}
|
||||
*/
|
||||
function buildExtraPreprocessors(options, config) {
|
||||
/** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup[]} */
|
||||
const prependPreprocessors = [];
|
||||
/** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup[]} */
|
||||
const appendPreprocessors = [];
|
||||
|
||||
// @ts-ignore
|
||||
const pluginsWithPreprocessorsDeprecated = config.plugins.filter((p) => p?.sveltePreprocess);
|
||||
if (pluginsWithPreprocessorsDeprecated.length > 0) {
|
||||
log.warn(
|
||||
`The following plugins use the deprecated 'plugin.sveltePreprocess' field. Please contact their maintainers and ask them to move it to 'plugin.api.sveltePreprocess': ${pluginsWithPreprocessorsDeprecated
|
||||
.map((p) => p.name)
|
||||
.join(', ')}`
|
||||
);
|
||||
// patch plugin to avoid breaking
|
||||
pluginsWithPreprocessorsDeprecated.forEach((p) => {
|
||||
if (!p.api) {
|
||||
p.api = {};
|
||||
}
|
||||
if (p.api.sveltePreprocess === undefined) {
|
||||
// @ts-ignore
|
||||
p.api.sveltePreprocess = p.sveltePreprocess;
|
||||
} else {
|
||||
log.error(
|
||||
`ignoring plugin.sveltePreprocess of ${p.name} because it already defined plugin.api.sveltePreprocess.`
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
/** @type {import('vite').Plugin[]} */
|
||||
const pluginsWithPreprocessors = config.plugins.filter((p) => p?.api?.sveltePreprocess);
|
||||
/** @type {import('vite').Plugin[]} */
|
||||
const ignored = [];
|
||||
/** @type {import('vite').Plugin[]} */
|
||||
const included = [];
|
||||
for (const p of pluginsWithPreprocessors) {
|
||||
if (
|
||||
options.ignorePluginPreprocessors === true ||
|
||||
(Array.isArray(options.ignorePluginPreprocessors) &&
|
||||
options.ignorePluginPreprocessors?.includes(p.name))
|
||||
) {
|
||||
ignored.push(p);
|
||||
} else {
|
||||
included.push(p);
|
||||
}
|
||||
}
|
||||
if (ignored.length > 0) {
|
||||
log.debug(
|
||||
`Ignoring svelte preprocessors defined by these vite plugins: ${ignored
|
||||
.map((p) => p.name)
|
||||
.join(', ')}`
|
||||
);
|
||||
}
|
||||
if (included.length > 0) {
|
||||
log.debug(
|
||||
`Adding svelte preprocessors defined by these vite plugins: ${included
|
||||
.map((p) => p.name)
|
||||
.join(', ')}`
|
||||
);
|
||||
appendPreprocessors.push(...pluginsWithPreprocessors.map((p) => p.api.sveltePreprocess));
|
||||
}
|
||||
|
||||
return { prependPreprocessors, appendPreprocessors };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @param {import('vite').ResolvedConfig} config
|
||||
*/
|
||||
export function addExtraPreprocessors(options, config) {
|
||||
const { prependPreprocessors, appendPreprocessors } = buildExtraPreprocessors(options, config);
|
||||
if (prependPreprocessors.length > 0 || appendPreprocessors.length > 0) {
|
||||
if (!options.preprocess) {
|
||||
options.preprocess = [...prependPreprocessors, ...appendPreprocessors];
|
||||
} else if (Array.isArray(options.preprocess)) {
|
||||
options.preprocess.unshift(...prependPreprocessors);
|
||||
options.preprocess.push(...appendPreprocessors);
|
||||
} else {
|
||||
options.preprocess = [...prependPreprocessors, options.preprocess, ...appendPreprocessors];
|
||||
}
|
||||
}
|
||||
}
|
66
node_modules/@sveltejs/vite-plugin-svelte/src/utils/resolve.js
generated
vendored
Normal file
66
node_modules/@sveltejs/vite-plugin-svelte/src/utils/resolve.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import path from 'node:path';
|
||||
import { builtinModules } from 'node:module';
|
||||
import { resolveDependencyData, isCommonDepWithoutSvelteField } from './dependencies.js';
|
||||
import { normalizePath } from 'vite';
|
||||
|
||||
/**
|
||||
* @param {string} importee
|
||||
* @param {string | undefined} importer
|
||||
* @param {import('./vite-plugin-svelte-cache').VitePluginSvelteCache} cache
|
||||
* @returns {Promise<string | void>}
|
||||
*/
|
||||
export async function resolveViaPackageJsonSvelte(importee, importer, cache) {
|
||||
if (
|
||||
importer &&
|
||||
isBareImport(importee) &&
|
||||
!isNodeInternal(importee) &&
|
||||
!isCommonDepWithoutSvelteField(importee)
|
||||
) {
|
||||
const cached = cache.getResolvedSvelteField(importee, importer);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const pkgData = await resolveDependencyData(importee, importer);
|
||||
if (pkgData) {
|
||||
const { pkg, dir } = pkgData;
|
||||
if (pkg.svelte) {
|
||||
const result = normalizePath(path.resolve(dir, pkg.svelte));
|
||||
cache.setResolvedSvelteField(importee, importer, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} importee
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNodeInternal(importee) {
|
||||
return importee.startsWith('node:') || builtinModules.includes(importee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} importee
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isBareImport(importee) {
|
||||
if (
|
||||
!importee ||
|
||||
importee[0] === '.' ||
|
||||
importee[0] === '\0' ||
|
||||
importee.includes(':') ||
|
||||
path.isAbsolute(importee)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const parts = importee.split('/');
|
||||
switch (parts.length) {
|
||||
case 1:
|
||||
return true;
|
||||
case 2:
|
||||
return parts[0].startsWith('@');
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
81
node_modules/@sveltejs/vite-plugin-svelte/src/utils/sourcemaps.js
generated
vendored
Normal file
81
node_modules/@sveltejs/vite-plugin-svelte/src/utils/sourcemaps.js
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import path from 'node:path';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* file?: string;
|
||||
* sources?: string[];
|
||||
* sourceRoot?: string;
|
||||
* }} SourceMapFileRefs
|
||||
*/
|
||||
|
||||
/**
|
||||
* convert absolute paths in sourcemap file refs to their relative equivalents to avoid leaking fs info
|
||||
*
|
||||
* map is modified in place.
|
||||
*
|
||||
* @param {SourceMapFileRefs | undefined} map sourcemap
|
||||
* @param {string} filename absolute path to file the sourcemap is for
|
||||
*/
|
||||
export function mapToRelative(map, filename) {
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
const sourceRoot = map.sourceRoot;
|
||||
const dirname = path.dirname(filename);
|
||||
|
||||
/** @type {(s: string) => string} */
|
||||
const toRelative = (s) => {
|
||||
if (!s) {
|
||||
return s;
|
||||
}
|
||||
/** @type {string} */
|
||||
let sourcePath;
|
||||
if (s.startsWith('file:///')) {
|
||||
// windows has file:///C:/foo and posix has file:///foo, so we have to remove one extra on windows
|
||||
sourcePath = s.slice(IS_WINDOWS ? 8 : 7);
|
||||
} else if (sourceRoot) {
|
||||
const sep = sourceRoot[sourceRoot.length - 1] === '/' || s[0] === '/' ? '' : '/';
|
||||
sourcePath = `${sourceRoot}${sep}${s}`;
|
||||
} else {
|
||||
sourcePath = s;
|
||||
}
|
||||
return path.isAbsolute(sourcePath) ? path.relative(dirname, sourcePath) : sourcePath;
|
||||
};
|
||||
|
||||
if (map.file) {
|
||||
map.file = path.basename(filename);
|
||||
}
|
||||
if (map.sources) {
|
||||
map.sources = map.sources.map(toRelative);
|
||||
}
|
||||
if (map.sourceRoot) {
|
||||
// we have prepended sourceRoot and computed relative paths from it
|
||||
// remove it here to avoid downstream processing prepending it again
|
||||
delete map.sourceRoot;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vitePreprocess uses an extra lang extension to tell vite about the type of preprocessor to use
|
||||
* This function removes it afterwards to get back working file refs
|
||||
*
|
||||
* map is modified in place.
|
||||
*
|
||||
* @param {SourceMapFileRefs | undefined} map the output sourcemap
|
||||
* @param {string} suffix the suffix to remove
|
||||
*/
|
||||
export function removeLangSuffix(map, suffix) {
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
/** @type {(s:string)=> string} */
|
||||
const removeSuffix = (s) => (s?.endsWith(suffix) ? s.slice(0, -1 * suffix.length) : s);
|
||||
if (map.file) {
|
||||
map.file = removeSuffix(map.file);
|
||||
}
|
||||
if (map.sources) {
|
||||
map.sources = map.sources.map(removeSuffix);
|
||||
}
|
||||
}
|
11
node_modules/@sveltejs/vite-plugin-svelte/src/utils/svelte-version.js
generated
vendored
Normal file
11
node_modules/@sveltejs/vite-plugin-svelte/src/utils/svelte-version.js
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { VERSION } from 'svelte/compiler';
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const isSvelte3 = VERSION.startsWith('3.');
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const isSvelte5 = VERSION.startsWith('5.');
|
253
node_modules/@sveltejs/vite-plugin-svelte/src/utils/vite-plugin-svelte-cache.js
generated
vendored
Normal file
253
node_modules/@sveltejs/vite-plugin-svelte/src/utils/vite-plugin-svelte-cache.js
generated
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname } from 'node:path';
|
||||
import { findClosestPkgJsonPath } from 'vitefu';
|
||||
import { normalizePath } from 'vite';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* name: string;
|
||||
* version: string;
|
||||
* svelte?: string;
|
||||
* path: string;
|
||||
* }} PackageInfo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export class VitePluginSvelteCache {
|
||||
/** @type {Map<string, import('../types/compile.d.ts').Code>} */
|
||||
#css = new Map();
|
||||
/** @type {Map<string, import('../types/compile.d.ts').Code>} */
|
||||
#js = new Map();
|
||||
/** @type {Map<string, string[]>} */
|
||||
#dependencies = new Map();
|
||||
/** @type {Map<string, Set<string>>} */
|
||||
#dependants = new Map();
|
||||
/** @type {Map<string, string>} */
|
||||
#resolvedSvelteFields = new Map();
|
||||
/** @type {Map<string, any>} */
|
||||
#errors = new Map();
|
||||
/** @type {PackageInfo[]} */
|
||||
#packageInfos = [];
|
||||
|
||||
/**
|
||||
* @param {import('../types/compile.d.ts').CompileData} compileData
|
||||
*/
|
||||
update(compileData) {
|
||||
this.#errors.delete(compileData.normalizedFilename);
|
||||
this.#updateCSS(compileData);
|
||||
this.#updateJS(compileData);
|
||||
this.#updateDependencies(compileData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @returns {boolean}
|
||||
*/
|
||||
has(svelteRequest) {
|
||||
const id = svelteRequest.normalizedFilename;
|
||||
return this.#errors.has(id) || this.#js.has(id) || this.#css.has(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @param {any} error
|
||||
*/
|
||||
setError(svelteRequest, error) {
|
||||
// keep dependency info, otherwise errors in dependants would not trigger an update after fixing
|
||||
// because they are no longer watched
|
||||
this.remove(svelteRequest, true);
|
||||
this.#errors.set(svelteRequest.normalizedFilename, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/compile.d.ts').CompileData} compileData
|
||||
*/
|
||||
#updateCSS(compileData) {
|
||||
this.#css.set(compileData.normalizedFilename, compileData.compiled.css);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/compile.d.ts').CompileData} compileData
|
||||
*/
|
||||
#updateJS(compileData) {
|
||||
if (!compileData.ssr) {
|
||||
// do not cache SSR js
|
||||
this.#js.set(compileData.normalizedFilename, compileData.compiled.js);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/compile.d.ts').CompileData} compileData
|
||||
*/
|
||||
#updateDependencies(compileData) {
|
||||
const id = compileData.normalizedFilename;
|
||||
const prevDependencies = this.#dependencies.get(id) || [];
|
||||
const dependencies = compileData.dependencies;
|
||||
this.#dependencies.set(id, dependencies);
|
||||
const removed = prevDependencies.filter((d) => !dependencies.includes(d));
|
||||
const added = dependencies.filter((d) => !prevDependencies.includes(d));
|
||||
added.forEach((d) => {
|
||||
if (!this.#dependants.has(d)) {
|
||||
this.#dependants.set(d, new Set());
|
||||
}
|
||||
/** @type {Set<string>} */ (this.#dependants.get(d)).add(compileData.filename);
|
||||
});
|
||||
removed.forEach((d) => {
|
||||
/** @type {Set<string>} */ (this.#dependants.get(d)).delete(compileData.filename);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @param {boolean} [keepDependencies]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
remove(svelteRequest, keepDependencies = false) {
|
||||
const id = svelteRequest.normalizedFilename;
|
||||
let removed = false;
|
||||
if (this.#errors.delete(id)) {
|
||||
removed = true;
|
||||
}
|
||||
if (this.#js.delete(id)) {
|
||||
removed = true;
|
||||
}
|
||||
if (this.#css.delete(id)) {
|
||||
removed = true;
|
||||
}
|
||||
if (!keepDependencies) {
|
||||
const dependencies = this.#dependencies.get(id);
|
||||
if (dependencies) {
|
||||
removed = true;
|
||||
dependencies.forEach((d) => {
|
||||
const dependants = this.#dependants.get(d);
|
||||
if (dependants && dependants.has(svelteRequest.filename)) {
|
||||
dependants.delete(svelteRequest.filename);
|
||||
}
|
||||
});
|
||||
this.#dependencies.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @returns {import('../types/compile.d.ts').Code | undefined}
|
||||
*/
|
||||
getCSS(svelteRequest) {
|
||||
return this.#css.get(svelteRequest.normalizedFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @returns {import('../types/compile.d.ts').Code | undefined}
|
||||
*/
|
||||
getJS(svelteRequest) {
|
||||
if (!svelteRequest.ssr) {
|
||||
// SSR js isn't cached
|
||||
return this.#js.get(svelteRequest.normalizedFilename);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
|
||||
* @returns {any}
|
||||
*/
|
||||
getError(svelteRequest) {
|
||||
return this.#errors.get(svelteRequest.normalizedFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {string[]}
|
||||
*/
|
||||
getDependants(path) {
|
||||
const dependants = this.#dependants.get(path);
|
||||
return dependants ? [...dependants] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} [importer]
|
||||
* @returns {string|void}
|
||||
*/
|
||||
getResolvedSvelteField(name, importer) {
|
||||
return this.#resolvedSvelteFields.get(this.#getResolvedSvelteFieldKey(name, importer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} [importer]
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasResolvedSvelteField(name, importer) {
|
||||
return this.#resolvedSvelteFields.has(this.#getResolvedSvelteFieldKey(name, importer));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {string} importee
|
||||
* @param {string | undefined} importer
|
||||
* @param {string} resolvedSvelte
|
||||
*/
|
||||
setResolvedSvelteField(importee, importer, resolvedSvelte) {
|
||||
this.#resolvedSvelteFields.set(
|
||||
this.#getResolvedSvelteFieldKey(importee, importer),
|
||||
resolvedSvelte
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} importee
|
||||
* @param {string | undefined} importer
|
||||
* @returns {string}
|
||||
*/
|
||||
#getResolvedSvelteFieldKey(importee, importer) {
|
||||
return importer ? `${importer} > ${importee}` : importee;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @returns {Promise<PackageInfo>}
|
||||
*/
|
||||
async getPackageInfo(file) {
|
||||
let info = this.#packageInfos.find((pi) => file.startsWith(pi.path));
|
||||
if (!info) {
|
||||
info = await findPackageInfo(file);
|
||||
this.#packageInfos.push(info);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* utility to get some info from the closest package.json with a "name" set
|
||||
*
|
||||
* @param {string} file to find info for
|
||||
* @returns {Promise<PackageInfo>}
|
||||
*/
|
||||
async function findPackageInfo(file) {
|
||||
/** @type {PackageInfo} */
|
||||
const info = {
|
||||
name: '$unknown',
|
||||
version: '0.0.0-unknown',
|
||||
path: '$unknown'
|
||||
};
|
||||
let path = await findClosestPkgJsonPath(file, (pkgPath) => {
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
||||
if (pkg.name != null) {
|
||||
info.name = pkg.name;
|
||||
if (pkg.version != null) {
|
||||
info.version = pkg.version;
|
||||
}
|
||||
info.svelte = pkg.svelte;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// return normalized path with appended '/' so .startsWith works for future file checks
|
||||
path = normalizePath(dirname(path ?? file)) + '/';
|
||||
info.path = path;
|
||||
return info;
|
||||
}
|
199
node_modules/@sveltejs/vite-plugin-svelte/src/utils/vite-plugin-svelte-stats.js
generated
vendored
Normal file
199
node_modules/@sveltejs/vite-plugin-svelte/src/utils/vite-plugin-svelte-stats.js
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
import { log } from './log.js';
|
||||
import { performance } from 'node:perf_hooks';
|
||||
import { normalizePath } from 'vite';
|
||||
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').CollectionOptions} */
|
||||
const defaultCollectionOptions = {
|
||||
// log after 500ms and more than one file processed
|
||||
logInProgress: (c, now) => now - c.collectionStart > 500 && c.stats.length > 1,
|
||||
// always log results
|
||||
logResult: () => true
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} n
|
||||
* @returns
|
||||
*/
|
||||
function humanDuration(n) {
|
||||
// 99.9ms 0.10s
|
||||
return n < 100 ? `${n.toFixed(1)}ms` : `${(n / 1000).toFixed(2)}s`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/vite-plugin-svelte-stats.d.ts').PackageStats[]} pkgStats
|
||||
* @returns {string}
|
||||
*/
|
||||
function formatPackageStats(pkgStats) {
|
||||
const statLines = pkgStats.map((pkgStat) => {
|
||||
const duration = pkgStat.duration;
|
||||
const avg = duration / pkgStat.files;
|
||||
return [pkgStat.pkg, `${pkgStat.files}`, humanDuration(duration), humanDuration(avg)];
|
||||
});
|
||||
statLines.unshift(['package', 'files', 'time', 'avg']);
|
||||
const columnWidths = statLines.reduce(
|
||||
(widths, row) => {
|
||||
for (let i = 0; i < row.length; i++) {
|
||||
const cell = row[i];
|
||||
if (widths[i] < cell.length) {
|
||||
widths[i] = cell.length;
|
||||
}
|
||||
}
|
||||
return widths;
|
||||
},
|
||||
statLines[0].map(() => 0)
|
||||
);
|
||||
|
||||
const table = statLines
|
||||
.map((row) =>
|
||||
row
|
||||
.map((cell, i) => {
|
||||
if (i === 0) {
|
||||
return cell.padEnd(columnWidths[i], ' ');
|
||||
} else {
|
||||
return cell.padStart(columnWidths[i], ' ');
|
||||
}
|
||||
})
|
||||
.join('\t')
|
||||
)
|
||||
.join('\n');
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export class VitePluginSvelteStats {
|
||||
// package directory -> package name
|
||||
/** @type {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} */
|
||||
#cache;
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection[]} */
|
||||
#collections = [];
|
||||
|
||||
/**
|
||||
* @param {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} cache
|
||||
*/
|
||||
constructor(cache) {
|
||||
this.#cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {Partial<import('../types/vite-plugin-svelte-stats.d.ts').CollectionOptions>} [opts]
|
||||
* @returns {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection}
|
||||
*/
|
||||
startCollection(name, opts) {
|
||||
const options = {
|
||||
...defaultCollectionOptions,
|
||||
...opts
|
||||
};
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').Stat[]} */
|
||||
const stats = [];
|
||||
const collectionStart = performance.now();
|
||||
const _this = this;
|
||||
let hasLoggedProgress = false;
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} */
|
||||
const collection = {
|
||||
name,
|
||||
options,
|
||||
stats,
|
||||
collectionStart,
|
||||
finished: false,
|
||||
start(file) {
|
||||
if (collection.finished) {
|
||||
throw new Error('called after finish() has been used');
|
||||
}
|
||||
file = normalizePath(file);
|
||||
const start = performance.now();
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').Stat} */
|
||||
const stat = { file, start, end: start };
|
||||
return () => {
|
||||
const now = performance.now();
|
||||
stat.end = now;
|
||||
stats.push(stat);
|
||||
if (!hasLoggedProgress && options.logInProgress(collection, now)) {
|
||||
hasLoggedProgress = true;
|
||||
log.debug(`${name} in progress ...`, undefined, 'stats');
|
||||
}
|
||||
};
|
||||
},
|
||||
async finish() {
|
||||
await _this.#finish(collection);
|
||||
}
|
||||
};
|
||||
_this.#collections.push(collection);
|
||||
return collection;
|
||||
}
|
||||
|
||||
async finishAll() {
|
||||
await Promise.all(this.#collections.map((c) => c.finish()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} collection
|
||||
*/
|
||||
async #finish(collection) {
|
||||
try {
|
||||
collection.finished = true;
|
||||
const now = performance.now();
|
||||
collection.duration = now - collection.collectionStart;
|
||||
const logResult = collection.options.logResult(collection);
|
||||
if (logResult) {
|
||||
await this.#aggregateStatsResult(collection);
|
||||
log.debug(
|
||||
`${collection.name} done.\n${formatPackageStats(
|
||||
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').PackageStats[]}*/ (
|
||||
collection.packageStats
|
||||
)
|
||||
)}`,
|
||||
undefined,
|
||||
'stats'
|
||||
);
|
||||
}
|
||||
// cut some ties to free it for garbage collection
|
||||
const index = this.#collections.indexOf(collection);
|
||||
this.#collections.splice(index, 1);
|
||||
collection.stats.length = 0;
|
||||
collection.stats = [];
|
||||
if (collection.packageStats) {
|
||||
collection.packageStats.length = 0;
|
||||
collection.packageStats = [];
|
||||
}
|
||||
collection.start = () => () => {};
|
||||
collection.finish = () => {};
|
||||
} catch (e) {
|
||||
// this should not happen, but stats taking also should not break the process
|
||||
log.debug.once(`failed to finish stats for ${collection.name}\n`, e, 'stats');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} collection
|
||||
*/
|
||||
async #aggregateStatsResult(collection) {
|
||||
const stats = collection.stats;
|
||||
for (const stat of stats) {
|
||||
stat.pkg = (await this.#cache.getPackageInfo(stat.file)).name;
|
||||
}
|
||||
|
||||
// group stats
|
||||
/** @type {Record<string, import('../types/vite-plugin-svelte-stats.d.ts').PackageStats>} */
|
||||
const grouped = {};
|
||||
stats.forEach((stat) => {
|
||||
const pkg = /** @type {string} */ (stat.pkg);
|
||||
let group = grouped[pkg];
|
||||
if (!group) {
|
||||
group = grouped[pkg] = {
|
||||
files: 0,
|
||||
duration: 0,
|
||||
pkg
|
||||
};
|
||||
}
|
||||
group.files += 1;
|
||||
group.duration += stat.end - stat.start;
|
||||
});
|
||||
|
||||
const groups = Object.values(grouped);
|
||||
groups.sort((a, b) => b.duration - a.duration);
|
||||
collection.packageStats = groups;
|
||||
}
|
||||
}
|
118
node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js
generated
vendored
Normal file
118
node_modules/@sveltejs/vite-plugin-svelte/src/utils/watch.js
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
import fs from 'node:fs';
|
||||
import { log } from './log.js';
|
||||
import { knownSvelteConfigNames } from './load-svelte-config.js';
|
||||
import path from 'node:path';
|
||||
|
||||
/**
|
||||
* @param {import('../types/options.d.ts').ResolvedOptions} options
|
||||
* @param {import('./vite-plugin-svelte-cache').VitePluginSvelteCache} cache
|
||||
* @param {import('../types/id.d.ts').IdParser} requestParser
|
||||
* @returns {void}
|
||||
*/
|
||||
export function setupWatchers(options, cache, requestParser) {
|
||||
const { server, configFile: svelteConfigFile } = options;
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
const { watcher, ws } = server;
|
||||
const { root, server: serverConfig } = server.config;
|
||||
/** @type {(filename: string) => void} */
|
||||
const emitChangeEventOnDependants = (filename) => {
|
||||
const dependants = cache.getDependants(filename);
|
||||
dependants.forEach((dependant) => {
|
||||
if (fs.existsSync(dependant)) {
|
||||
log.debug(
|
||||
`emitting virtual change event for "${dependant}" because depdendency "${filename}" changed`
|
||||
);
|
||||
watcher.emit('change', dependant);
|
||||
}
|
||||
});
|
||||
};
|
||||
/** @type {(filename: string) => void} */
|
||||
const removeUnlinkedFromCache = (filename) => {
|
||||
const svelteRequest = requestParser(filename, false);
|
||||
if (svelteRequest) {
|
||||
const removedFromCache = cache.remove(svelteRequest);
|
||||
if (removedFromCache) {
|
||||
log.debug(`cleared VitePluginSvelteCache for deleted file ${filename}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
/** @type {(filename: string) => void} */
|
||||
const triggerViteRestart = (filename) => {
|
||||
if (serverConfig.middlewareMode) {
|
||||
// in middlewareMode we can't restart the server automatically
|
||||
// show the user an overlay instead
|
||||
const message =
|
||||
'Svelte config change detected, restart your dev process to apply the changes.';
|
||||
log.info(message, filename);
|
||||
ws.send({
|
||||
type: 'error',
|
||||
err: { message, stack: '', plugin: 'vite-plugin-svelte', id: filename }
|
||||
});
|
||||
} else {
|
||||
log.info(`svelte config changed: restarting vite server. - file: ${filename}`);
|
||||
server.restart();
|
||||
}
|
||||
};
|
||||
|
||||
// collection of watcher listeners by event
|
||||
/** @type {Record<string, Function[]>} */
|
||||
const listenerCollection = {
|
||||
add: [],
|
||||
change: [emitChangeEventOnDependants],
|
||||
unlink: [removeUnlinkedFromCache, emitChangeEventOnDependants]
|
||||
};
|
||||
|
||||
if (svelteConfigFile !== false) {
|
||||
// configFile false means we ignore the file and external process is responsible
|
||||
const possibleSvelteConfigs = knownSvelteConfigNames.map((cfg) => path.join(root, cfg));
|
||||
/** @type {(filename: string) => void} */
|
||||
const restartOnConfigAdd = (filename) => {
|
||||
if (possibleSvelteConfigs.includes(filename)) {
|
||||
triggerViteRestart(filename);
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {(filename: string) => void} */
|
||||
const restartOnConfigChange = (filename) => {
|
||||
if (filename === svelteConfigFile) {
|
||||
triggerViteRestart(filename);
|
||||
}
|
||||
};
|
||||
|
||||
if (svelteConfigFile) {
|
||||
listenerCollection.change.push(restartOnConfigChange);
|
||||
listenerCollection.unlink.push(restartOnConfigChange);
|
||||
} else {
|
||||
listenerCollection.add.push(restartOnConfigAdd);
|
||||
}
|
||||
}
|
||||
|
||||
Object.entries(listenerCollection).forEach(([evt, listeners]) => {
|
||||
if (listeners.length > 0) {
|
||||
watcher.on(evt, (filename) => listeners.forEach((listener) => listener(filename)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* taken from vite utils
|
||||
* @param {import('vite').FSWatcher} watcher
|
||||
* @param {string | null} file
|
||||
* @param {string} root
|
||||
* @returns {void}
|
||||
*/
|
||||
export function ensureWatchedFile(watcher, file, root) {
|
||||
if (
|
||||
file &&
|
||||
// only need to watch if out of root
|
||||
!file.startsWith(root + '/') &&
|
||||
// some rollup plugins use null bytes for private resolved Ids
|
||||
!file.includes('\0') &&
|
||||
fs.existsSync(file)
|
||||
) {
|
||||
// resolve file to normalized system path
|
||||
watcher.add(path.resolve(file));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user