@rsvelte/vite-plugin-svelte 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 [these people](https://github.com/sveltejs/vite-plugin-svelte/graphs/contributors)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @sveltejs/vite-plugin-svelte
2
+
3
+ The official [Svelte](https://svelte.dev) plugin for [Vite](https://vitejs.dev).
4
+
5
+ ## Usage
6
+
7
+ ```js
8
+ // vite.config.js
9
+ import { defineConfig } from 'vite';
10
+ import { svelte } from '@sveltejs/vite-plugin-svelte';
11
+
12
+ export default defineConfig({
13
+ plugins: [
14
+ svelte({
15
+ /* plugin options */
16
+ })
17
+ ]
18
+ });
19
+ ```
20
+
21
+ ## Documentation
22
+
23
+ - [Plugin options](../../docs/config.md)
24
+ - [FAQ](../../docs/faq.md)
25
+
26
+ ## License
27
+
28
+ [MIT](./LICENSE)
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@rsvelte/vite-plugin-svelte",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "author": "dominikg",
6
+ "files": [
7
+ "src",
8
+ "types"
9
+ ],
10
+ "type": "module",
11
+ "types": "types/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./types/index.d.ts",
15
+ "default": "./src/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "check:publint": "publint --strict",
20
+ "check:types": "tsc --noEmit",
21
+ "generate:types": "dts-buddy -m \"@rsvelte/vite-plugin-svelte:src/public.d.ts\""
22
+ },
23
+ "engines": {
24
+ "node": "^20.19 || ^22.12 || >=24"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/baseballyama/vite-plugin-svelte.git",
29
+ "directory": "packages/vite-plugin-svelte"
30
+ },
31
+ "keywords": [
32
+ "vite-plugin",
33
+ "vite plugin",
34
+ "vite",
35
+ "svelte"
36
+ ],
37
+ "bugs": {
38
+ "url": "https://github.com/baseballyama/vite-plugin-svelte/issues"
39
+ },
40
+ "homepage": "https://github.com/baseballyama/vite-plugin-svelte#readme",
41
+ "dependencies": {
42
+ "@rsvelte/compiler": ">=0.1.0",
43
+ "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0",
44
+ "deepmerge": "^4.3.1",
45
+ "magic-string": "^0.30.21",
46
+ "obug": "^2.1.0",
47
+ "vitefu": "^1.1.1"
48
+ },
49
+ "peerDependencies": {
50
+ "svelte": "^5.0.0",
51
+ "vite": "^6.3.0 || ^7.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/debug": "^4.1.12",
55
+ "sass": "^1.94.2",
56
+ "svelte": "^5.45.4",
57
+ "vite": "^7.2.6"
58
+ }
59
+ }
package/src/index.js ADDED
@@ -0,0 +1,42 @@
1
+ import process from 'node:process';
2
+ import { log } from './utils/log.js';
3
+ import { configure } from './plugins/configure.js';
4
+ import { preprocess } from './plugins/preprocess.js';
5
+ import { compile } from './plugins/compile.js';
6
+ import { loadCompiledCss } from './plugins/load-compiled-css.js';
7
+ import { setupOptimizer } from './plugins/setup-optimizer.js';
8
+ import { compileModule } from './plugins/compile-module.js';
9
+ import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
10
+ import { loadCustom } from './plugins/load-custom.js';
11
+ import { hotUpdate } from './plugins/hot-update.js';
12
+
13
+ /**
14
+ * returns a list of plugins to handle svelte files
15
+ * plugins are named `vite-plugin-svelte:<task>`
16
+ *
17
+ * @param {Partial<import('./public.d.ts').Options>} [inlineOptions]
18
+ * @returns {import('vite').Plugin[]}
19
+ */
20
+ export function svelte(inlineOptions) {
21
+ if (process.env.DEBUG != null) {
22
+ log.setLevel('debug');
23
+ }
24
+ /** @type {import('./types/plugin-api.js').PluginAPI} */
25
+ // @ts-expect-error initialize empty to guard against early use
26
+ const api = {}; // initialized by configure plugin, used in others
27
+ return [
28
+ { name: 'vite-plugin-svelte' }, // marker for detection logic in other plugins that expect this name
29
+ configure(api, inlineOptions),
30
+ setupOptimizer(api),
31
+ loadCompiledCss(api),
32
+ loadCustom(api),
33
+ preprocess(api),
34
+ compile(api),
35
+ compileModule(api),
36
+ hotUpdate(api),
37
+ svelteInspector()
38
+ ];
39
+ }
40
+
41
+ export { vitePreprocess } from './preprocess.js';
42
+ export { loadSvelteConfig } from './utils/load-svelte-config.js';
@@ -0,0 +1,130 @@
1
+ import { buildModuleIdFilter, buildModuleIdParser } from '../utils/id.js';
2
+ import * as svelteCompiler from '@rsvelte/compiler';
3
+ import { log, logCompilerWarnings } from '../utils/log.js';
4
+ import { toRollupError } from '../utils/error.js';
5
+ import { isSvelteWithAsync } from '../utils/svelte-version.js';
6
+
7
+ /**
8
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
9
+ * @returns {import('vite').Plugin}
10
+ */
11
+ export function compileModule(api) {
12
+ /**
13
+ * @type {import("../types/options.js").ResolvedOptions}
14
+ */
15
+ let options;
16
+ /**
17
+ * @type {import("../types/id.js").ModuleIdParser}
18
+ */
19
+ let idParser;
20
+
21
+ /**
22
+ * @type {import('@rsvelte/compiler').ModuleCompileOptions}
23
+ */
24
+ let staticModuleCompileOptions;
25
+
26
+ /** @type {import('vite').Plugin} */
27
+ const plugin = {
28
+ name: 'vite-plugin-svelte:compile-module',
29
+ enforce: 'post',
30
+ async configResolved() {
31
+ options = api.options;
32
+ //@ts-expect-error transform defined below but filter not in type
33
+ plugin.transform.filter = buildModuleIdFilter(options);
34
+ idParser = buildModuleIdParser(options);
35
+ staticModuleCompileOptions = filterNonModuleCompilerOptions(options.compilerOptions);
36
+ },
37
+ transform: {
38
+ async handler(code, id) {
39
+ const ssr = this.environment.config.consumer === 'server';
40
+ const moduleRequest = idParser(id, ssr);
41
+ if (!moduleRequest) {
42
+ return;
43
+ }
44
+ const filename = moduleRequest.filename;
45
+ /** @type {import('@rsvelte/compiler').CompileOptions} */
46
+ const compileOptions = {
47
+ ...staticModuleCompileOptions,
48
+ dev: !this.environment.config.isProduction,
49
+ generate: ssr ? 'server' : 'client',
50
+ filename
51
+ };
52
+ const dynamicCompileOptions = await options?.dynamicCompileOptions?.({
53
+ filename,
54
+ code,
55
+ compileOptions
56
+ });
57
+ if (dynamicCompileOptions && log.debug.enabled) {
58
+ log.debug(
59
+ `dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`,
60
+ undefined,
61
+ 'compileModule'
62
+ );
63
+ }
64
+ const finalCompileOptions = dynamicCompileOptions
65
+ ? {
66
+ ...compileOptions,
67
+ ...dynamicCompileOptions
68
+ }
69
+ : compileOptions;
70
+ if (dynamicCompileOptions?.experimental) {
71
+ finalCompileOptions.experimental = {
72
+ ...compileOptions.experimental,
73
+ ...dynamicCompileOptions.experimental
74
+ };
75
+ }
76
+ const finalModuleCompileOptions = filterNonModuleCompilerOptions(finalCompileOptions);
77
+ if (log.debug.enabled) {
78
+ log.debug(
79
+ `final ModuleCompileOptions for ${filename}: ${JSON.stringify(finalModuleCompileOptions)}`,
80
+ undefined,
81
+ 'compileModule'
82
+ );
83
+ }
84
+ try {
85
+ const compileResult = svelteCompiler.compileModule(code, finalModuleCompileOptions);
86
+ logCompilerWarnings(moduleRequest, compileResult.warnings, options);
87
+ return compileResult.js;
88
+ } catch (e) {
89
+ throw toRollupError(e, options);
90
+ }
91
+ }
92
+ }
93
+ };
94
+ return plugin;
95
+ }
96
+
97
+ /**
98
+ *
99
+ * @param {import('@rsvelte/compiler').CompileOptions} compilerOptions
100
+ * @return {import('@rsvelte/compiler').ModuleCompileOptions}
101
+ */
102
+ function filterNonModuleCompilerOptions(compilerOptions) {
103
+ /** @type {Array<keyof import('@rsvelte/compiler').ModuleCompileOptions>} */
104
+ const knownModuleCompileOptionNames = ['dev', 'generate', 'filename', 'rootDir', 'warningFilter'];
105
+ if (isSvelteWithAsync) {
106
+ knownModuleCompileOptionNames.push('experimental');
107
+ }
108
+ // not typed but this is temporary until svelte itself ignores CompileOptions passed to compileModule
109
+ const experimentalModuleCompilerOptionNames = ['async'];
110
+
111
+ /** @type {import('@rsvelte/compiler').ModuleCompileOptions} */
112
+ const filtered = filterByPropNames(compilerOptions, knownModuleCompileOptionNames);
113
+ if (filtered.experimental) {
114
+ filtered.experimental = filterByPropNames(
115
+ filtered.experimental,
116
+ experimentalModuleCompilerOptionNames
117
+ );
118
+ }
119
+ return filtered;
120
+ }
121
+
122
+ /**
123
+ *
124
+ * @param {object} o
125
+ * @param {string[]} names
126
+ * @returns {object}
127
+ */
128
+ function filterByPropNames(o, names) {
129
+ return Object.fromEntries(Object.entries(o).filter(([name]) => names.includes(name)));
130
+ }
@@ -0,0 +1,65 @@
1
+ import { toRollupError } from '../utils/error.js';
2
+ import { logCompilerWarnings } from '../utils/log.js';
3
+
4
+ /**
5
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
6
+ * @returns {import('vite').Plugin}
7
+ */
8
+ export function compile(api) {
9
+ /**
10
+ * @type {import("../types/options.js").ResolvedOptions}
11
+ */
12
+ let options;
13
+
14
+ /**
15
+ * @type {import("../types/compile.d.ts").CompileSvelte}
16
+ */
17
+ let compileSvelte;
18
+ /** @type {import('vite').Plugin} */
19
+ const plugin = {
20
+ name: 'vite-plugin-svelte:compile',
21
+ configResolved() {
22
+ //@ts-expect-error defined below but filter not in type
23
+ plugin.transform.filter = api.filter;
24
+ options = api.options;
25
+ compileSvelte = api.compileSvelte;
26
+ },
27
+ transform: {
28
+ async handler(code, id) {
29
+ const ssr = this.environment.config.consumer === 'server';
30
+ const svelteRequest = api.idParser(id, ssr);
31
+ if (!svelteRequest || svelteRequest.raw) {
32
+ return;
33
+ }
34
+ let compileData;
35
+ try {
36
+ compileData = await compileSvelte(
37
+ svelteRequest,
38
+ code,
39
+ options,
40
+ this.getCombinedSourcemap()
41
+ );
42
+ } catch (e) {
43
+ throw toRollupError(e, options);
44
+ }
45
+ if (compileData.compiled?.warnings) {
46
+ logCompilerWarnings(svelteRequest, compileData.compiled.warnings, options);
47
+ }
48
+
49
+ return {
50
+ ...compileData.compiled.js,
51
+ moduleType: 'js',
52
+ meta: {
53
+ vite: {
54
+ lang: compileData.lang
55
+ },
56
+ svelte: {
57
+ css: compileData.compiled.css
58
+ }
59
+ }
60
+ };
61
+ }
62
+ }
63
+ };
64
+ return plugin;
65
+ }
@@ -0,0 +1,97 @@
1
+ import process from 'node:process';
2
+ import { isDebugNamespaceEnabled, log } from '../utils/log.js';
3
+ import * as vite from 'vite';
4
+ import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
5
+ import {
6
+ buildExtraViteConfig,
7
+ validateInlineOptions,
8
+ resolveOptions,
9
+ preResolveOptions,
10
+ ensureConfigEnvironmentMainFields,
11
+ ensureConfigEnvironmentConditions
12
+ } from '../utils/options.js';
13
+ import { buildIdFilter, buildIdParser } from '../utils/id.js';
14
+ import { createCompileSvelte } from '../utils/compile.js';
15
+
16
+ // @ts-ignore rolldownVersion
17
+ const { version: viteVersion, rolldownVersion } = vite;
18
+
19
+ /**
20
+ * @param {Partial<import('../public.d.ts').Options>} [inlineOptions]
21
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
22
+ * @returns {import('vite').Plugin}
23
+ */
24
+ export function configure(api, inlineOptions) {
25
+ if (rolldownVersion) {
26
+ log.warn.once(
27
+ `!!! Support for vite 8 beta in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!
28
+ See https://github.com/sveltejs/vite-plugin-svelte/issues/1143 for a list of known issues and to report feedback.`.replace(
29
+ /\t+/g,
30
+ '\t'
31
+ )
32
+ );
33
+ }
34
+
35
+ validateInlineOptions(inlineOptions);
36
+
37
+ /**
38
+ * @type {import("../types/options.d.ts").PreResolvedOptions}
39
+ */
40
+ let preOptions;
41
+
42
+ /** @type {import('vite').Plugin} */
43
+ return {
44
+ name: 'vite-plugin-svelte:config',
45
+ api,
46
+ // make sure it runs first
47
+ enforce: 'pre',
48
+ config: {
49
+ order: 'pre',
50
+ async handler(config, configEnv) {
51
+ // setup logger
52
+ if (process.env.DEBUG) {
53
+ log.setLevel('debug');
54
+ } else if (config.logLevel) {
55
+ log.setLevel(config.logLevel);
56
+ }
57
+
58
+ preOptions = await preResolveOptions(inlineOptions, config, configEnv);
59
+ // extra vite config
60
+ const extraViteConfig = await buildExtraViteConfig(preOptions, config);
61
+ log.debug('additional vite config', extraViteConfig, 'config');
62
+ return extraViteConfig;
63
+ }
64
+ },
65
+ configResolved: {
66
+ order: 'pre',
67
+ handler(config) {
68
+ const options = resolveOptions(preOptions, config);
69
+ api.options = options;
70
+ if (isDebugNamespaceEnabled('stats')) {
71
+ api.options.stats = new VitePluginSvelteStats();
72
+ }
73
+
74
+ api.filter = buildIdFilter(options);
75
+ api.idFilter = api.filter;
76
+ api.idParser = buildIdParser(options);
77
+ api.compileSvelte = createCompileSvelte();
78
+ log.debug('resolved options', api.options, 'config');
79
+ }
80
+ },
81
+
82
+ configEnvironment(name, config, opts) {
83
+ ensureConfigEnvironmentMainFields(name, config, opts);
84
+ // @ts-expect-error the function above should make `resolve.mainFields` non-nullable
85
+ config.resolve.mainFields.unshift('svelte');
86
+
87
+ ensureConfigEnvironmentConditions(name, config, opts);
88
+ // @ts-expect-error the function above should make `resolve.conditions` non-nullable
89
+ config.resolve.conditions.push('svelte');
90
+ },
91
+
92
+ configureServer(server) {
93
+ const { options } = api;
94
+ options.server = server;
95
+ }
96
+ };
97
+ }
@@ -0,0 +1,196 @@
1
+ import { log } from '../utils/log.js';
2
+ import { setupWatchers } from '../utils/watch.js';
3
+ import { SVELTE_VIRTUAL_STYLE_ID_REGEX } from '../utils/constants.js';
4
+
5
+ /**
6
+ * @param {import('../types/plugin-api.d.ts').PluginAPI} api
7
+ * @returns {import('vite').Plugin}
8
+ */
9
+ export function hotUpdate(api) {
10
+ /**
11
+ * @type {import("../types/options.js").ResolvedOptions}
12
+ */
13
+ let options;
14
+ /**
15
+ * @type {import('../types/id.d.ts').IdParser}
16
+ */
17
+ let idParser;
18
+
19
+ /**
20
+ *
21
+ * @type {Map<string|null,string>}
22
+ */
23
+ const transformResultCache = new Map();
24
+
25
+ /** @type {import('vite').Plugin} */
26
+ const plugin = {
27
+ name: 'vite-plugin-svelte:hot-update',
28
+ enforce: 'post',
29
+ configResolved() {
30
+ options = api.options;
31
+ idParser = api.idParser;
32
+
33
+ // @ts-expect-error
34
+ plugin.transform.filter = {
35
+ id: {
36
+ // reinclude virtual styles to get their output
37
+ include: [...api.filter.id.include, SVELTE_VIRTUAL_STYLE_ID_REGEX],
38
+ exclude: [
39
+ // ignore files in node_modules, we don't hot update them
40
+ /\/node_modules\//,
41
+ // remove style exclusion
42
+ ...api.filter.id.exclude.filter((filter) => filter !== SVELTE_VIRTUAL_STYLE_ID_REGEX)
43
+ ]
44
+ }
45
+ };
46
+ },
47
+
48
+ applyToEnvironment(env) {
49
+ // we only handle updates for client components
50
+ // ssr frameworks have to handle updating/reloading themselves as v-p-s can't know what they prefer
51
+ const hmrEnabled = options.compilerOptions.hmr && options.emitCss;
52
+ return hmrEnabled && env.config.consumer === 'client';
53
+ },
54
+
55
+ configureServer(server) {
56
+ const clientEnvironment = Object.values(server.environments).find(
57
+ (e) => e.config.consumer === 'client'
58
+ );
59
+ if (clientEnvironment) {
60
+ setupWatchers(options);
61
+ } else {
62
+ log.warn(
63
+ 'No client environment found, not adding watchers for svelte config and preprocessor dependencies'
64
+ );
65
+ }
66
+ },
67
+
68
+ buildStart() {
69
+ transformResultCache.clear();
70
+ },
71
+
72
+ transform: {
73
+ order: 'post',
74
+ handler(code, id) {
75
+ transformResultCache.set(id, code);
76
+ }
77
+ },
78
+ hotUpdate: {
79
+ order: 'post',
80
+ async handler(ctx) {
81
+ const svelteRequest = idParser(ctx.file, false, ctx.timestamp);
82
+ if (svelteRequest) {
83
+ const { modules } = ctx;
84
+ const svelteModules = [];
85
+ const nonSvelteModules = [];
86
+ for (const mod of modules) {
87
+ if (transformResultCache.has(mod.id)) {
88
+ svelteModules.push(mod);
89
+ } else {
90
+ nonSvelteModules.push(mod);
91
+ }
92
+ }
93
+
94
+ if (svelteModules.length === 0) {
95
+ return; // nothing to do for us
96
+ }
97
+ const affectedModules = [];
98
+ const prevResults = svelteModules.map((m) => transformResultCache.get(m.id));
99
+
100
+ /** @type {Set<string>} */
101
+ const seen = new Set();
102
+ /** @param {string} url */
103
+ const transformRequest = async (url) => {
104
+ if (!seen.has(url)) {
105
+ seen.add(url);
106
+ await this.environment.transformRequest(url);
107
+ }
108
+ };
109
+
110
+ // Transform the Svelte component itself first, so that the
111
+ // CSS cache always gets updated.
112
+ await transformRequest(svelteRequest.filename);
113
+
114
+ for (let i = 0; i < svelteModules.length; i++) {
115
+ const mod = svelteModules[i];
116
+ const prev = prevResults[i];
117
+ await transformRequest(mod.url);
118
+ const next = transformResultCache.get(mod.id);
119
+ if (hasCodeChanged(prev, next, mod.id)) {
120
+ affectedModules.push(mod);
121
+ } else {
122
+ log.debug(
123
+ `skipping hot update for ${mod.id} because result is unchanged`,
124
+ undefined,
125
+ 'hmr'
126
+ );
127
+ }
128
+ }
129
+ log.debug(
130
+ `hotUpdate for ${svelteRequest.id} result: [${affectedModules.map((m) => m.id).join(', ')}]`,
131
+ undefined,
132
+ 'hmr'
133
+ );
134
+ return [...affectedModules, ...nonSvelteModules];
135
+ }
136
+ }
137
+ }
138
+ };
139
+
140
+ return plugin;
141
+ }
142
+
143
+ /**
144
+ * @param {string | undefined | null} prev
145
+ * @param {string | undefined | null} next
146
+ * @param {string | null} id
147
+ * @returns {boolean}
148
+ */
149
+ function hasCodeChanged(prev, next, id) {
150
+ const isStrictEqual = nullSafeEqual(prev, next);
151
+ if (isStrictEqual) {
152
+ return false;
153
+ }
154
+ const isLooseEqual = nullSafeEqual(normalize(prev), normalize(next));
155
+ if (!isStrictEqual && isLooseEqual) {
156
+ log.debug(
157
+ `ignoring compiler output change for ${id} as it is equal to previous output after normalization`,
158
+ undefined,
159
+ 'hmr'
160
+ );
161
+ }
162
+ return !isLooseEqual;
163
+ }
164
+
165
+ /**
166
+ * @param {string | null | undefined} prev
167
+ * @param {string | null | undefined} next
168
+ * @returns {boolean}
169
+ */
170
+ function nullSafeEqual(prev, next) {
171
+ return (prev == null && next == null) || (prev != null && next != null && prev === next);
172
+ }
173
+
174
+ /**
175
+ * remove code that only changes metadata and does not require a js update for the component to keep working
176
+ *
177
+ * 1) location numbers argument from $.add_locations calls in svelte output eg [[1,2],[3,4]]
178
+ * 2) timestamp queries added to imports by vite eg ?t=0123456789123
179
+ *
180
+ * @param {string | null | undefined } code
181
+ * @returns {string | null | undefined}
182
+ */
183
+ function normalize(code) {
184
+ if (code == null) {
185
+ return code;
186
+ }
187
+
188
+ return (
189
+ code
190
+ // svelte5 $.add_locations line numbers argument [[1,2],[3,4]]
191
+ // uses matching group replace to keep the template argument intact
192
+ .replace(/(\$\.add_locations\(.*), (\[\[[\d, [\]]+]])\)/g, '$1, []')
193
+ // vite import analysis timestamp queries, ?t=0123456789123&
194
+ .replace(/[?&]t=\d{13}\b/g, '')
195
+ );
196
+ }