@sveltejs/vite-plugin-svelte 1.0.0-next.3 → 1.0.0-next.33

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/src/index.ts ADDED
@@ -0,0 +1,225 @@
1
+ import fs from 'fs';
2
+ import { HmrContext, ModuleNode, Plugin, ResolvedConfig, UserConfig } from 'vite';
3
+ import { handleHotUpdate } from './handle-hot-update';
4
+ import { log, logCompilerWarnings } from './utils/log';
5
+ import { CompileData, createCompileSvelte } from './utils/compile';
6
+ import { buildIdParser, IdParser, SvelteRequest } from './utils/id';
7
+ import {
8
+ buildExtraViteConfig,
9
+ validateInlineOptions,
10
+ Options,
11
+ ResolvedOptions,
12
+ resolveOptions,
13
+ patchResolvedViteConfig,
14
+ preResolveOptions
15
+ } from './utils/options';
16
+ import { VitePluginSvelteCache } from './utils/vite-plugin-svelte-cache';
17
+
18
+ import { ensureWatchedFile, setupWatchers } from './utils/watch';
19
+ import { resolveViaPackageJsonSvelte } from './utils/resolve';
20
+ import { PartialResolvedId } from 'rollup';
21
+ import { toRollupError } from './utils/error';
22
+
23
+ export function svelte(inlineOptions?: Partial<Options>): Plugin {
24
+ if (process.env.DEBUG != null) {
25
+ log.setLevel('debug');
26
+ }
27
+ validateInlineOptions(inlineOptions);
28
+ const cache = new VitePluginSvelteCache();
29
+ const pkg_export_errors = new Set();
30
+ // updated in configResolved hook
31
+ let requestParser: IdParser;
32
+ let options: ResolvedOptions;
33
+ let viteConfig: ResolvedConfig;
34
+ /* eslint-disable no-unused-vars */
35
+ let compileSvelte: (
36
+ svelteRequest: SvelteRequest,
37
+ code: string,
38
+ options: Partial<ResolvedOptions>
39
+ ) => Promise<CompileData>;
40
+ /* eslint-enable no-unused-vars */
41
+
42
+ let resolvedSvelteSSR: Promise<PartialResolvedId | null>;
43
+
44
+ return {
45
+ name: 'vite-plugin-svelte',
46
+ // make sure our resolver runs before vite internal resolver to resolve svelte field correctly
47
+ enforce: 'pre',
48
+ async config(config, configEnv): Promise<Partial<UserConfig>> {
49
+ // setup logger
50
+ if (process.env.DEBUG) {
51
+ log.setLevel('debug');
52
+ } else if (config.logLevel) {
53
+ log.setLevel(config.logLevel);
54
+ }
55
+ // @ts-expect-error temporarily lend the options variable until fixed in configResolved
56
+ options = await preResolveOptions(inlineOptions, config, configEnv);
57
+ // extra vite config
58
+ const extraViteConfig = buildExtraViteConfig(options, config, configEnv);
59
+ log.debug('additional vite config', extraViteConfig);
60
+ return extraViteConfig;
61
+ },
62
+
63
+ async configResolved(config) {
64
+ options = resolveOptions(options, config);
65
+ patchResolvedViteConfig(config, options);
66
+ requestParser = buildIdParser(options);
67
+ compileSvelte = createCompileSvelte(options);
68
+ viteConfig = config;
69
+ log.debug('resolved options', options);
70
+ },
71
+
72
+ configureServer(server) {
73
+ // eslint-disable-next-line no-unused-vars
74
+ options.server = server;
75
+ setupWatchers(options, cache, requestParser);
76
+ },
77
+
78
+ load(id, opts) {
79
+ // @ts-expect-error anticipate vite changing second parameter as options object
80
+ // see https://github.com/vitejs/vite/discussions/5109
81
+ const ssr: boolean = opts === true || opts?.ssr;
82
+ const svelteRequest = requestParser(id, !!ssr);
83
+ if (svelteRequest) {
84
+ const { filename, query } = svelteRequest;
85
+ // virtual css module
86
+ if (query.svelte && query.type === 'style') {
87
+ const css = cache.getCSS(svelteRequest);
88
+ if (css) {
89
+ log.debug(`load returns css for ${filename}`);
90
+ return css;
91
+ }
92
+ }
93
+ // prevent vite asset plugin from loading files as url that should be compiled in transform
94
+ if (viteConfig.assetsInclude(filename)) {
95
+ log.debug(`load returns raw content for ${filename}`);
96
+ return fs.readFileSync(filename, 'utf-8');
97
+ }
98
+ }
99
+ },
100
+
101
+ async resolveId(importee, importer, opts) {
102
+ const ssr = !!opts?.ssr;
103
+ const svelteRequest = requestParser(importee, ssr);
104
+ if (svelteRequest?.query.svelte) {
105
+ if (svelteRequest.query.type === 'style') {
106
+ // return cssId with root prefix so postcss pipeline of vite finds the directory correctly
107
+ // see https://github.com/sveltejs/vite-plugin-svelte/issues/14
108
+ log.debug(`resolveId resolved virtual css module ${svelteRequest.cssId}`);
109
+ return svelteRequest.cssId;
110
+ }
111
+ log.debug(`resolveId resolved ${importee}`);
112
+ return importee; // query with svelte tag, an id we generated, no need for further analysis
113
+ }
114
+
115
+ if (ssr && importee === 'svelte') {
116
+ if (!resolvedSvelteSSR) {
117
+ resolvedSvelteSSR = this.resolve('svelte/ssr', undefined, { skipSelf: true }).then(
118
+ (svelteSSR) => {
119
+ log.debug('resolved svelte to svelte/ssr');
120
+ return svelteSSR;
121
+ },
122
+ (err) => {
123
+ log.debug(
124
+ 'failed to resolve svelte to svelte/ssr. Update svelte to a version that exports it',
125
+ err
126
+ );
127
+ return null; // returning null here leads to svelte getting resolved regularly
128
+ }
129
+ );
130
+ }
131
+ return resolvedSvelteSSR;
132
+ }
133
+
134
+ try {
135
+ const resolved = resolveViaPackageJsonSvelte(importee, importer);
136
+ if (resolved) {
137
+ log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
138
+ return resolved;
139
+ }
140
+ } catch (err) {
141
+ switch (err.code) {
142
+ case 'ERR_PACKAGE_PATH_NOT_EXPORTED':
143
+ pkg_export_errors.add(importee);
144
+ return null;
145
+ case 'MODULE_NOT_FOUND':
146
+ return null;
147
+ default:
148
+ throw err;
149
+ }
150
+ }
151
+ },
152
+
153
+ async transform(code, id, opts) {
154
+ const ssr = !!opts?.ssr;
155
+ const svelteRequest = requestParser(id, ssr);
156
+ if (!svelteRequest) {
157
+ return;
158
+ }
159
+ const { filename, query } = svelteRequest;
160
+
161
+ if (query.svelte) {
162
+ if (query.type === 'style') {
163
+ const css = cache.getCSS(svelteRequest);
164
+ if (css) {
165
+ log.debug(`transform returns css for ${filename}`);
166
+ return css; // TODO return code arg instead? it's the code from load hook.
167
+ }
168
+ }
169
+ log.error('failed to transform tagged svelte request', svelteRequest);
170
+ throw new Error(`failed to transform tagged svelte request for id ${id}`);
171
+ }
172
+ let compileData;
173
+ try {
174
+ compileData = await compileSvelte(svelteRequest, code, options);
175
+ } catch (e) {
176
+ throw toRollupError(e);
177
+ }
178
+ logCompilerWarnings(compileData.compiled.warnings, options);
179
+ cache.update(compileData);
180
+ if (compileData.dependencies?.length && options.server) {
181
+ compileData.dependencies.forEach((d) => {
182
+ ensureWatchedFile(options.server!.watcher, d, options.root);
183
+ });
184
+ }
185
+ log.debug(`transform returns compiled js for ${filename}`);
186
+ return compileData.compiled.js;
187
+ },
188
+
189
+ handleHotUpdate(ctx: HmrContext): void | Promise<Array<ModuleNode> | void> {
190
+ if (!options.hot || !options.emitCss) {
191
+ return;
192
+ }
193
+ const svelteRequest = requestParser(ctx.file, false, ctx.timestamp);
194
+ if (svelteRequest) {
195
+ return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
196
+ }
197
+ },
198
+
199
+ /**
200
+ * All resolutions done; display warnings wrt `package.json` access.
201
+ */
202
+ // TODO generateBundle isn't called by vite, is buildEnd enough or should it be logged once per violation in resolve
203
+ buildEnd() {
204
+ if (pkg_export_errors.size > 0) {
205
+ log.warn(
206
+ `The following packages did not export their \`package.json\` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.`,
207
+ Array.from(pkg_export_errors, (s) => `- ${s}`).join('\n')
208
+ );
209
+ }
210
+ }
211
+ };
212
+ }
213
+
214
+ export {
215
+ Options,
216
+ Preprocessor,
217
+ PreprocessorGroup,
218
+ CompileOptions,
219
+ CssHashGetter,
220
+ Arrayable,
221
+ MarkupPreprocessor,
222
+ ModuleFormat,
223
+ Processed,
224
+ Warning
225
+ } from './utils/options';
@@ -0,0 +1,29 @@
1
+ import { findRootSvelteDependencies } from '../dependencies';
2
+ import * as path from 'path';
3
+
4
+ describe('dependencies', () => {
5
+ describe('findRootSvelteDependencies', () => {
6
+ it('should find svelte dependencies in packages/e2e-test/hmr', async () => {
7
+ const deps = findRootSvelteDependencies(path.resolve('packages/e2e-tests/hmr'));
8
+ expect(deps).toHaveLength(1);
9
+ expect(deps[0].name).toBe('e2e-test-dep-svelte-simple');
10
+ expect(deps[0].path).toEqual([]);
11
+ });
12
+ it('should find nested svelte dependencies in packages/e2e-test/package-json-svelte-field', async () => {
13
+ const deps = findRootSvelteDependencies(
14
+ path.resolve('packages/e2e-tests/package-json-svelte-field')
15
+ );
16
+ expect(deps).toHaveLength(3);
17
+ const hybrid = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-hybrid');
18
+ expect(hybrid).toBeTruthy();
19
+ expect(hybrid.path).toHaveLength(0);
20
+ const nested = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-nested');
21
+ expect(nested).toBeTruthy();
22
+ expect(nested.path).toHaveLength(0);
23
+ const simple = deps.find((dep) => dep.name === 'e2e-test-dep-svelte-simple');
24
+ expect(simple).toBeTruthy();
25
+ expect(simple.path).toHaveLength(1);
26
+ expect(simple.path[0]).toBe('e2e-test-dep-svelte-nested');
27
+ });
28
+ });
29
+ });
@@ -0,0 +1,24 @@
1
+ import { buildMagicString, buildSourceMap } from '../sourcemap';
2
+
3
+ describe('sourcemap', () => {
4
+ describe('buildMagicString', () => {
5
+ it('should return a valid magic string', async () => {
6
+ const from = 'h1{color: blue}\nh2{color: green}\nh3{color: red}\n';
7
+ const to = 'h1{color: blue}\ndiv{color: white}\nh3{color: red}\nh2{color: green}\n';
8
+ const m = await buildMagicString(from, to);
9
+ expect(m).toBeDefined();
10
+ expect(m.original).toBe(from);
11
+ expect(m.toString()).toBe(to);
12
+ });
13
+ });
14
+ describe('buildSourceMap', () => {
15
+ it('should return a map with mappings and filename', async () => {
16
+ const map = await buildSourceMap('foo', 'bar', 'foo.txt');
17
+ expect(map).toBeDefined();
18
+ expect(map.mappings).toBeDefined();
19
+ expect(map.mappings[0]).toBeDefined();
20
+ expect(map.mappings[0][0]).toBeDefined();
21
+ expect(map.sources[0]).toBe('foo.txt');
22
+ });
23
+ });
24
+ });
@@ -0,0 +1,148 @@
1
+ import { CompileOptions, ResolvedOptions } from './options';
2
+ import { compile, preprocess, walk } from 'svelte/compiler';
3
+ // @ts-ignore
4
+ import { createMakeHot } from 'svelte-hmr';
5
+ import { SvelteRequest } from './id';
6
+ import { safeBase64Hash } from './hash';
7
+ import { log } from './log';
8
+
9
+ const _createCompileSvelte = (makeHot: Function) =>
10
+ async function compileSvelte(
11
+ svelteRequest: SvelteRequest,
12
+ code: string,
13
+ options: Partial<ResolvedOptions>
14
+ ): Promise<CompileData> {
15
+ const { filename, normalizedFilename, cssId, ssr } = svelteRequest;
16
+ const { emitCss = true } = options;
17
+ const dependencies = [];
18
+
19
+ const compileOptions: CompileOptions = {
20
+ ...options.compilerOptions,
21
+ filename,
22
+ generate: ssr ? 'ssr' : 'dom'
23
+ };
24
+ if (options.hot && options.emitCss) {
25
+ const hash = `s-${safeBase64Hash(normalizedFilename)}`;
26
+ log.debug(`setting cssHash ${hash} for ${normalizedFilename}`);
27
+ compileOptions.cssHash = () => hash;
28
+ }
29
+ if (ssr && compileOptions.enableSourcemap !== false) {
30
+ if (typeof compileOptions.enableSourcemap === 'object') {
31
+ compileOptions.enableSourcemap.css = false;
32
+ } else {
33
+ compileOptions.enableSourcemap = { js: true, css: false };
34
+ }
35
+ }
36
+
37
+ let preprocessed;
38
+
39
+ if (options.preprocess) {
40
+ preprocessed = await preprocess(code, options.preprocess, { filename });
41
+ if (preprocessed.dependencies) dependencies.push(...preprocessed.dependencies);
42
+ if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
43
+ }
44
+ const finalCode = preprocessed ? preprocessed.code : code;
45
+ const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
46
+ filename,
47
+ code: finalCode,
48
+ compileOptions
49
+ });
50
+ if (dynamicCompileOptions && log.debug.enabled) {
51
+ log.debug(
52
+ `dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`
53
+ );
54
+ }
55
+ const finalCompileOptions = dynamicCompileOptions
56
+ ? {
57
+ ...compileOptions,
58
+ ...dynamicCompileOptions
59
+ }
60
+ : compileOptions;
61
+ const compiled = compile(finalCode, finalCompileOptions);
62
+
63
+ if (emitCss && compiled.css.code) {
64
+ // TODO properly update sourcemap?
65
+ compiled.js.code += `\nimport ${JSON.stringify(cssId)};\n`;
66
+ }
67
+
68
+ // only apply hmr when not in ssr context and hot options are set
69
+ if (!ssr && makeHot) {
70
+ compiled.js.code = makeHot({
71
+ id: filename,
72
+ compiledCode: compiled.js.code,
73
+ hotOptions: options.hot,
74
+ compiled,
75
+ originalCode: code,
76
+ compileOptions: finalCompileOptions
77
+ });
78
+ }
79
+
80
+ compiled.js.dependencies = dependencies;
81
+
82
+ return {
83
+ filename,
84
+ normalizedFilename,
85
+ // @ts-ignore
86
+ compiled,
87
+ ssr,
88
+ dependencies
89
+ };
90
+ };
91
+
92
+ function buildMakeHot(options: ResolvedOptions) {
93
+ const needsMakeHot = options.hot !== false && options.isServe && !options.isProduction;
94
+ if (needsMakeHot) {
95
+ // @ts-ignore
96
+ const hotApi = options?.hot?.hotApi;
97
+ // @ts-ignore
98
+ const adapter = options?.hot?.adapter;
99
+ return createMakeHot({
100
+ walk,
101
+ hotApi,
102
+ adapter,
103
+ hotOptions: { noOverlay: true, ...(options.hot as object) }
104
+ });
105
+ }
106
+ }
107
+
108
+ export function createCompileSvelte(options: ResolvedOptions) {
109
+ const makeHot = buildMakeHot(options);
110
+ return _createCompileSvelte(makeHot);
111
+ }
112
+
113
+ export interface Code {
114
+ code: string;
115
+ map?: any;
116
+ dependencies?: any[];
117
+ }
118
+
119
+ export interface Compiled {
120
+ js: Code;
121
+ css: Code;
122
+ ast: any; // TODO type
123
+ warnings: any[]; // TODO type
124
+ vars: {
125
+ name: string;
126
+ export_name: string;
127
+ injected: boolean;
128
+ module: boolean;
129
+ mutated: boolean;
130
+ reassigned: boolean;
131
+ referenced: boolean;
132
+ writable: boolean;
133
+ referenced_from_script: boolean;
134
+ }[];
135
+ stats: {
136
+ timings: {
137
+ total: number;
138
+ };
139
+ };
140
+ }
141
+
142
+ export interface CompileData {
143
+ filename: string;
144
+ normalizedFilename: string;
145
+ compiled: Compiled;
146
+ ssr: boolean | undefined;
147
+ dependencies: string[];
148
+ }
@@ -0,0 +1,20 @@
1
+ const VITE_RESOLVE_MAIN_FIELDS = ['module', 'jsnext:main', 'jsnext'];
2
+
3
+ export const SVELTE_RESOLVE_MAIN_FIELDS = ['svelte', ...VITE_RESOLVE_MAIN_FIELDS];
4
+
5
+ export const SVELTE_IMPORTS = [
6
+ 'svelte/animate',
7
+ 'svelte/easing',
8
+ 'svelte/internal',
9
+ 'svelte/motion',
10
+ 'svelte/ssr',
11
+ 'svelte/store',
12
+ 'svelte/transition',
13
+ 'svelte'
14
+ ];
15
+
16
+ export const SVELTE_HMR_IMPORTS = [
17
+ 'svelte-hmr/runtime/hot-api-esm.js',
18
+ 'svelte-hmr/runtime/proxy-adapter-dom.js',
19
+ 'svelte-hmr'
20
+ ];
@@ -0,0 +1,223 @@
1
+ import { log } from './log';
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import { createRequire } from 'module';
5
+
6
+ export function findRootSvelteDependencies(root: string, cwdFallback = true): SvelteDependency[] {
7
+ log.debug(`findSvelteDependencies: searching svelte dependencies in ${root}`);
8
+ const pkgFile = path.join(root, 'package.json');
9
+ if (!fs.existsSync(pkgFile)) {
10
+ if (cwdFallback) {
11
+ const cwd = process.cwd();
12
+ if (root !== cwd) {
13
+ log.debug(`no package.json found in vite root ${root}`);
14
+ return findRootSvelteDependencies(cwd, false);
15
+ }
16
+ }
17
+ log.warn(`no package.json found, findRootSvelteDependencies failed`);
18
+ return [];
19
+ }
20
+
21
+ const pkg = parsePkg(root);
22
+ if (!pkg) {
23
+ return [];
24
+ }
25
+
26
+ const deps = [
27
+ ...Object.keys(pkg.dependencies || {}),
28
+ ...Object.keys(pkg.devDependencies || {})
29
+ ].filter((dep) => !is_common_without_svelte_field(dep));
30
+
31
+ return getSvelteDependencies(deps, root);
32
+ }
33
+
34
+ function getSvelteDependencies(
35
+ deps: string[],
36
+ pkgDir: string,
37
+ path: string[] = []
38
+ ): SvelteDependency[] {
39
+ const result = [];
40
+ const localRequire = createRequire(`${pkgDir}/package.json`);
41
+ const resolvedDeps = deps
42
+ .map((dep) => resolveDependencyData(dep, localRequire))
43
+ .filter(Boolean) as DependencyData[];
44
+ for (const { pkg, dir } of resolvedDeps) {
45
+ const type = getSvelteDependencyType(pkg);
46
+ if (!type) continue;
47
+ result.push({ name: pkg.name, type, pkg, dir, path });
48
+ // continue crawling for component libraries so we can optimize them, js libraries are fine
49
+ if (type === 'component-library' && pkg.dependencies) {
50
+ let dependencyNames = Object.keys(pkg.dependencies);
51
+ const circular = dependencyNames.filter((name) => path.includes(name));
52
+ if (circular.length > 0) {
53
+ log.warn.enabled &&
54
+ log.warn(
55
+ `skipping circular svelte dependencies in automated vite optimizeDeps handling`,
56
+ circular.map((x) => path.concat(x).join('>'))
57
+ );
58
+ dependencyNames = dependencyNames.filter((name) => !path.includes(name));
59
+ }
60
+ if (path.length === 3) {
61
+ log.debug.once(`encountered deep svelte dependency tree: ${path.join('>')}`);
62
+ }
63
+ result.push(...getSvelteDependencies(dependencyNames, dir, path.concat(pkg.name)));
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+
69
+ function resolveDependencyData(dep: string, localRequire: NodeRequire): DependencyData | void {
70
+ try {
71
+ const pkgJson = `${dep}/package.json`;
72
+ const pkg = localRequire(pkgJson);
73
+ const dir = path.dirname(localRequire.resolve(pkgJson));
74
+ return { dir, pkg };
75
+ } catch (e) {
76
+ log.debug.once(`dependency ${dep} does not export package.json`, e);
77
+ // walk up from default export until we find package.json with name=dep
78
+ try {
79
+ let dir = path.dirname(localRequire.resolve(dep));
80
+ while (dir) {
81
+ const pkg = parsePkg(dir, true);
82
+ if (pkg && pkg.name === dep) {
83
+ return { dir, pkg };
84
+ }
85
+ const parent = path.dirname(dir);
86
+ if (parent === dir) {
87
+ break;
88
+ }
89
+ dir = parent;
90
+ }
91
+ } catch (e) {
92
+ log.debug.once(`error while trying to find package.json of ${dep}`, e);
93
+ }
94
+ }
95
+ log.debug.once(`failed to resolve ${dep}`);
96
+ }
97
+
98
+ function parsePkg(dir: string, silent = false): Pkg | void {
99
+ const pkgFile = path.join(dir, 'package.json');
100
+ try {
101
+ return JSON.parse(fs.readFileSync(pkgFile, 'utf-8'));
102
+ } catch (e) {
103
+ !silent && log.warn.enabled && log.warn(`failed to parse ${pkgFile}`, e);
104
+ }
105
+ }
106
+
107
+ function getSvelteDependencyType(pkg: Pkg): SvelteDependencyType | undefined {
108
+ if (isSvelteComponentLib(pkg)) {
109
+ return 'component-library';
110
+ } else if (isSvelteLib(pkg)) {
111
+ return 'js-library';
112
+ } else {
113
+ return undefined;
114
+ }
115
+ }
116
+
117
+ function isSvelteComponentLib(pkg: Pkg) {
118
+ return !!pkg.svelte;
119
+ }
120
+
121
+ function isSvelteLib(pkg: Pkg) {
122
+ return !!pkg.dependencies?.svelte || !!pkg.peerDependencies?.svelte;
123
+ }
124
+
125
+ const COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD = [
126
+ '@lukeed/uuid',
127
+ '@sveltejs/vite-plugin-svelte',
128
+ '@sveltejs/kit',
129
+ 'autoprefixer',
130
+ 'cookie',
131
+ 'dotenv',
132
+ 'esbuild',
133
+ 'eslint',
134
+ 'jest',
135
+ 'mdsvex',
136
+ 'postcss',
137
+ 'prettier',
138
+ 'svelte',
139
+ 'svelte-check',
140
+ 'svelte-hmr',
141
+ 'svelte-preprocess',
142
+ 'tslib',
143
+ 'typescript',
144
+ 'vite'
145
+ ];
146
+ const COMMON_PREFIXES_WITHOUT_SVELTE_FIELD = [
147
+ '@fontsource/',
148
+ '@postcss-plugins/',
149
+ '@rollup/',
150
+ '@sveltejs/adapter-',
151
+ '@types/',
152
+ '@typescript-eslint/',
153
+ 'eslint-',
154
+ 'jest-',
155
+ 'postcss-plugin-',
156
+ 'prettier-plugin-',
157
+ 'rollup-plugin-',
158
+ 'vite-plugin-'
159
+ ];
160
+
161
+ /**
162
+ * Test for common dependency names that tell us it is not a package including a svelte field, eg. eslint + plugins.
163
+ *
164
+ * This speeds up the find process as we don't have to try and require the package.json for all of them
165
+ *
166
+ * @param dependency {string}
167
+ * @returns {boolean} true if it is a dependency without a svelte field
168
+ */
169
+ function is_common_without_svelte_field(dependency: string): boolean {
170
+ return (
171
+ COMMON_DEPENDENCIES_WITHOUT_SVELTE_FIELD.includes(dependency) ||
172
+ COMMON_PREFIXES_WITHOUT_SVELTE_FIELD.some(
173
+ (prefix) =>
174
+ prefix.startsWith('@')
175
+ ? dependency.startsWith(prefix)
176
+ : dependency.substring(dependency.lastIndexOf('/') + 1).startsWith(prefix) // check prefix omitting @scope/
177
+ )
178
+ );
179
+ }
180
+
181
+ export function needsOptimization(dep: string, localRequire: NodeRequire): boolean {
182
+ const depData = resolveDependencyData(dep, localRequire);
183
+ if (!depData) return false;
184
+ const pkg = depData.pkg;
185
+ // only optimize if is cjs, using the below as heuristic
186
+ // see https://github.com/sveltejs/vite-plugin-svelte/issues/162
187
+ const isCjs = pkg.main && !pkg.module && !pkg.exports;
188
+ if (!isCjs) return false;
189
+ // ensure entry is js so vite can prebundle it
190
+ // see https://github.com/sveltejs/vite-plugin-svelte/issues/233
191
+ const entryExt = path.extname(pkg.main);
192
+ return !entryExt || entryExt === '.js' || entryExt === '.cjs';
193
+ }
194
+
195
+ interface DependencyData {
196
+ dir: string;
197
+ pkg: Pkg;
198
+ }
199
+
200
+ export interface SvelteDependency {
201
+ name: string;
202
+ type: SvelteDependencyType;
203
+ dir: string;
204
+ pkg: Pkg;
205
+ path: string[];
206
+ }
207
+
208
+ // component-library => exports svelte components
209
+ // js-library => only uses svelte api, no components
210
+ export type SvelteDependencyType = 'component-library' | 'js-library';
211
+
212
+ export interface Pkg {
213
+ name: string;
214
+ svelte?: string;
215
+ dependencies?: DependencyList;
216
+ devDependencies?: DependencyList;
217
+ peerDependencies?: DependencyList;
218
+ [key: string]: any;
219
+ }
220
+
221
+ export interface DependencyList {
222
+ [key: string]: string;
223
+ }