@sveltejs/vite-plugin-svelte 1.0.0-next.35 → 1.0.0-next.38

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 CHANGED
@@ -27,7 +27,6 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
27
27
  }
28
28
  validateInlineOptions(inlineOptions);
29
29
  const cache = new VitePluginSvelteCache();
30
- const pkg_resolve_errors = new Set();
31
30
  // updated in configResolved hook
32
31
  let requestParser: IdParser;
33
32
  let options: ResolvedOptions;
@@ -136,41 +135,24 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
136
135
  return resolvedSvelteSSR;
137
136
  }
138
137
 
139
- try {
140
- const resolved = resolveViaPackageJsonSvelte(importee, importer, cache);
141
- if (resolved) {
142
- log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
143
- return resolved;
144
- }
145
- } catch (err) {
146
- pkg_resolve_errors.add(importee);
138
+ const resolved = resolveViaPackageJsonSvelte(importee, importer, cache);
139
+ if (resolved) {
140
+ log.debug(`resolveId resolved ${resolved} via package.json svelte field of ${importee}`);
141
+ return resolved;
147
142
  }
148
143
  },
149
144
 
150
145
  async transform(code, id, opts) {
151
146
  const ssr = !!opts?.ssr;
152
147
  const svelteRequest = requestParser(id, ssr);
153
- if (!svelteRequest) {
148
+ if (!svelteRequest || svelteRequest.query.svelte) {
154
149
  return;
155
150
  }
156
- const { filename, query } = svelteRequest;
157
-
158
- if (query.svelte) {
159
- if (query.type === 'style') {
160
- const css = cache.getCSS(svelteRequest);
161
- if (css) {
162
- log.debug(`transform returns css for ${filename}`);
163
- return css; // TODO return code arg instead? it's the code from load hook.
164
- }
165
- }
166
- log.error('failed to transform tagged svelte request', svelteRequest);
167
- throw new Error(`failed to transform tagged svelte request for id ${id}`);
168
- }
169
151
  let compileData;
170
152
  try {
171
153
  compileData = await compileSvelte(svelteRequest, code, options);
172
154
  } catch (e) {
173
- throw toRollupError(e);
155
+ throw toRollupError(e, options);
174
156
  }
175
157
  logCompilerWarnings(compileData.compiled.warnings, options);
176
158
  cache.update(compileData);
@@ -179,7 +161,7 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
179
161
  ensureWatchedFile(options.server!.watcher, d, options.root);
180
162
  });
181
163
  }
182
- log.debug(`transform returns compiled js for ${filename}`);
164
+ log.debug(`transform returns compiled js for ${svelteRequest.filename}`);
183
165
  return compileData.compiled.js;
184
166
  },
185
167
 
@@ -191,20 +173,6 @@ export function svelte(inlineOptions?: Partial<Options>): Plugin {
191
173
  if (svelteRequest) {
192
174
  return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
193
175
  }
194
- },
195
-
196
- /**
197
- * All resolutions done; display warnings wrt `package.json` access.
198
- */
199
- // TODO generateBundle isn't called by vite, is buildEnd enough or should it be logged once per violation in resolve
200
- buildEnd() {
201
- if (pkg_resolve_errors.size > 0) {
202
- log.warn(
203
- `vite-plugin-svelte was unable to find package.json of the following packages and wasn't able to resolve via their "svelte" field.
204
- If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.
205
- ${Array.from(pkg_resolve_errors, (s) => `- ${s}`).join('\n')}`.replace(/\t/g, '')
206
- );
207
- }
208
176
  }
209
177
  };
210
178
  }
@@ -1,15 +1,16 @@
1
- import { findRootSvelteDependencies } from '../dependencies';
1
+ import { findRootSvelteDependencies, needsOptimization } from '../dependencies';
2
2
  import * as path from 'path';
3
+ import { createRequire } from 'module';
3
4
 
4
5
  describe('dependencies', () => {
5
6
  describe('findRootSvelteDependencies', () => {
6
- it('should find svelte dependencies in packages/e2e-test/hmr', async () => {
7
+ it('should find svelte dependencies in packages/e2e-test/hmr', () => {
7
8
  const deps = findRootSvelteDependencies(path.resolve('packages/e2e-tests/hmr'));
8
9
  expect(deps).toHaveLength(1);
9
10
  expect(deps[0].name).toBe('e2e-test-dep-svelte-simple');
10
11
  expect(deps[0].path).toEqual([]);
11
12
  });
12
- it('should find nested svelte dependencies in packages/e2e-test/package-json-svelte-field', async () => {
13
+ it('should find nested svelte dependencies in packages/e2e-test/package-json-svelte-field', () => {
13
14
  const deps = findRootSvelteDependencies(
14
15
  path.resolve('packages/e2e-tests/package-json-svelte-field')
15
16
  );
@@ -26,4 +27,14 @@ describe('dependencies', () => {
26
27
  expect(simple.path[0]).toBe('e2e-test-dep-svelte-nested');
27
28
  });
28
29
  });
30
+ describe('needsOptimization', () => {
31
+ it('should optimize cjs deps only', () => {
32
+ const localRequire = createRequire(path.resolve('packages/e2e-tests/dependencies'));
33
+ expect(needsOptimization('e2e-test-dep-cjs-and-esm', localRequire)).toBe(false);
34
+ expect(needsOptimization('e2e-test-dep-cjs-only', localRequire)).toBe(true);
35
+ expect(needsOptimization('e2e-test-dep-esm-only', localRequire)).toBe(false);
36
+ expect(needsOptimization('e2e-test-dep-index-only', localRequire)).toBe(true);
37
+ expect(needsOptimization('e2e-test-dep-types-only', localRequire)).toBe(false);
38
+ });
39
+ });
29
40
  });
@@ -37,7 +37,13 @@ const _createCompileSvelte = (makeHot: Function) =>
37
37
  let preprocessed;
38
38
 
39
39
  if (options.preprocess) {
40
- preprocessed = await preprocess(code, options.preprocess, { filename });
40
+ try {
41
+ preprocessed = await preprocess(code, options.preprocess, { filename });
42
+ } catch (e) {
43
+ e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
44
+ throw e;
45
+ }
46
+
41
47
  if (preprocessed.dependencies) dependencies.push(...preprocessed.dependencies);
42
48
  if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
43
49
  }
@@ -187,12 +187,23 @@ export function needsOptimization(dep: string, localRequire: NodeRequire): boole
187
187
  const pkg = depData.pkg;
188
188
  // only optimize if is cjs, using the below as heuristic
189
189
  // see https://github.com/sveltejs/vite-plugin-svelte/issues/162
190
- const isCjs = pkg.main && !pkg.module && !pkg.exports;
191
- if (!isCjs) return false;
192
- // ensure entry is js so vite can prebundle it
193
- // see https://github.com/sveltejs/vite-plugin-svelte/issues/233
194
- const entryExt = path.extname(pkg.main);
195
- return !entryExt || entryExt === '.js' || entryExt === '.cjs';
190
+ const hasEsmFields = pkg.module || pkg.exports;
191
+ if (hasEsmFields) return false;
192
+ if (pkg.main) {
193
+ // ensure entry is js so vite can prebundle it
194
+ // see https://github.com/sveltejs/vite-plugin-svelte/issues/233
195
+ const entryExt = path.extname(pkg.main);
196
+ return !entryExt || entryExt === '.js' || entryExt === '.cjs';
197
+ } else {
198
+ // check if has implicit index.js entrypoint
199
+ // https://github.com/sveltejs/vite-plugin-svelte/issues/281
200
+ try {
201
+ localRequire.resolve(`${dep}/index.js`);
202
+ return true;
203
+ } catch {
204
+ return false;
205
+ }
206
+ }
196
207
  }
197
208
 
198
209
  interface DependencyData {
@@ -1,5 +1,5 @@
1
1
  import { RollupError } from 'rollup';
2
- import { Warning } from './options';
2
+ import { ResolvedOptions, Warning } from './options';
3
3
  import { buildExtendedLogMessage } from './log';
4
4
  import { PartialMessage } from 'esbuild';
5
5
 
@@ -8,15 +8,15 @@ import { PartialMessage } from 'esbuild';
8
8
  * @param error a svelte compiler error, which is a mix of Warning and an error
9
9
  * @returns {RollupError} the converted error
10
10
  */
11
- export function toRollupError(error: Warning & Error): RollupError {
12
- const { filename, frame, start, code, name } = error;
11
+ export function toRollupError(error: Warning & Error, options: ResolvedOptions): RollupError {
12
+ const { filename, frame, start, code, name, stack } = error;
13
13
  const rollupError: RollupError = {
14
14
  name, // needed otherwise sveltekit coalesce_to_error turns it into a string
15
15
  id: filename,
16
16
  message: buildExtendedLogMessage(error), // include filename:line:column so that it's clickable
17
17
  frame: formatFrameForVite(frame),
18
18
  code,
19
- stack: ''
19
+ stack: options.isBuild || options.isDebug || !frame ? stack : ''
20
20
  };
21
21
  if (start) {
22
22
  rollupError.loc = {
@@ -33,8 +33,8 @@ export function toRollupError(error: Warning & Error): RollupError {
33
33
  * @param error a svelte compiler error, which is a mix of Warning and an error
34
34
  * @returns {PartialMessage} the converted error
35
35
  */
36
- export function toESBuildError(error: Warning & Error): PartialMessage {
37
- const { filename, frame, start } = error;
36
+ export function toESBuildError(error: Warning & Error, options: ResolvedOptions): PartialMessage {
37
+ const { filename, frame, start, stack } = error;
38
38
  const partialMessage: PartialMessage = {
39
39
  text: buildExtendedLogMessage(error)
40
40
  };
@@ -46,6 +46,9 @@ export function toESBuildError(error: Warning & Error): PartialMessage {
46
46
  lineText: lineFromFrame(start.line, frame) // needed to get a meaningful error message on cli
47
47
  };
48
48
  }
49
+ if (options.isBuild || options.isDebug || !frame) {
50
+ partialMessage.detail = stack;
51
+ }
49
52
  return partialMessage;
50
53
  }
51
54
 
@@ -27,7 +27,7 @@ export function esbuildSveltePlugin(options: ResolvedOptions): EsbuildPlugin {
27
27
  const contents = await compileSvelte(options, { filename, code });
28
28
  return { contents };
29
29
  } catch (e) {
30
- return { errors: [toESBuildError(e)] };
30
+ return { errors: [toESBuildError(e, options)] };
31
31
  }
32
32
  });
33
33
  }
@@ -73,7 +73,12 @@ async function compileSvelte(
73
73
  let preprocessed;
74
74
 
75
75
  if (options.preprocess) {
76
- preprocessed = await preprocess(code, options.preprocess, { filename });
76
+ try {
77
+ preprocessed = await preprocess(code, options.preprocess, { filename });
78
+ } catch (e) {
79
+ e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ''}`;
80
+ throw e;
81
+ }
77
82
  if (preprocessed.map) compileOptions.sourcemap = preprocessed.map;
78
83
  }
79
84
 
package/src/utils/log.ts CHANGED
@@ -164,7 +164,10 @@ export function buildExtendedLogMessage(w: Warning) {
164
164
  parts.push(':', w.start.line, ':', w.start.column);
165
165
  }
166
166
  if (w.message) {
167
- parts.push(' ', w.message);
167
+ if (parts.length > 0) {
168
+ parts.push(' ');
169
+ }
170
+ parts.push(w.message);
168
171
  }
169
172
  return parts.join('');
170
173
  }
@@ -16,11 +16,10 @@ const PREBUNDLE_SENSITIVE_OPTIONS: (keyof ResolvedOptions)[] = [
16
16
  export async function handleOptimizeDeps(options: ResolvedOptions, viteConfig: ResolvedConfig) {
17
17
  if (!options.experimental.prebundleSvelteLibraries || !viteConfig.cacheDir) return;
18
18
 
19
- const viteMetadataPath = path.resolve(viteConfig.cacheDir, '_metadata.json');
19
+ const viteMetadataPath = findViteMetadataPath(viteConfig.cacheDir);
20
+ if (!viteMetadataPath) return;
20
21
 
21
- if (!fs.existsSync(viteMetadataPath)) return;
22
-
23
- const svelteMetadataPath = path.resolve(viteConfig.cacheDir, '_svelte_metadata.json');
22
+ const svelteMetadataPath = path.resolve(viteMetadataPath, '../_svelte_metadata.json');
24
23
  const currentSvelteMetadata = JSON.stringify(generateSvelteMetadata(options), (_, value) => {
25
24
  return typeof value === 'function' ? value.toString() : value;
26
25
  });
@@ -41,3 +40,11 @@ function generateSvelteMetadata(options: ResolvedOptions) {
41
40
  }
42
41
  return metadata;
43
42
  }
43
+
44
+ function findViteMetadataPath(cacheDir: string) {
45
+ const metadataPaths = ['_metadata.json', 'deps/_metadata.json'];
46
+ for (const metadataPath of metadataPaths) {
47
+ const viteMetadataPath = path.resolve(cacheDir, metadataPath);
48
+ if (fs.existsSync(viteMetadataPath)) return viteMetadataPath;
49
+ }
50
+ }
@@ -82,7 +82,8 @@ export async function preResolveOptions(
82
82
  // extras
83
83
  root: viteConfigWithResolvedRoot.root!,
84
84
  isBuild: viteEnv.command === 'build',
85
- isServe: viteEnv.command === 'serve'
85
+ isServe: viteEnv.command === 'serve',
86
+ isDebug: process.env.DEBUG != null
86
87
  };
87
88
  // configFile of svelteConfig contains the absolute path it was loaded from,
88
89
  // prefer it over the possibly relative inline path
@@ -491,6 +492,7 @@ export interface PreResolvedOptions extends Options {
491
492
  root: string;
492
493
  isBuild: boolean;
493
494
  isServe: boolean;
495
+ isDebug: boolean;
494
496
  }
495
497
 
496
498
  export interface ResolvedOptions extends PreResolvedOptions {
@@ -1,5 +1,5 @@
1
1
  import path from 'path';
2
- import { createRequire } from 'module';
2
+ import { builtinModules, createRequire } from 'module';
3
3
  import { is_common_without_svelte_field, resolveDependencyData } from './dependencies';
4
4
  import { VitePluginSvelteCache } from './vite-plugin-svelte-cache';
5
5
 
@@ -8,7 +8,12 @@ export function resolveViaPackageJsonSvelte(
8
8
  importer: string | undefined,
9
9
  cache: VitePluginSvelteCache
10
10
  ): string | void {
11
- if (importer && isBareImport(importee) && !is_common_without_svelte_field(importee)) {
11
+ if (
12
+ importer &&
13
+ isBareImport(importee) &&
14
+ !isNodeInternal(importee) &&
15
+ !is_common_without_svelte_field(importee)
16
+ ) {
12
17
  const cached = cache.getResolvedSvelteField(importee, importer);
13
18
  if (cached) {
14
19
  return cached;
@@ -22,12 +27,14 @@ export function resolveViaPackageJsonSvelte(
22
27
  cache.setResolvedSvelteField(importee, importer, result);
23
28
  return result;
24
29
  }
25
- } else {
26
- throw new Error(`failed to resolve package.json of ${importee} imported by ${importer}`);
27
30
  }
28
31
  }
29
32
  }
30
33
 
34
+ function isNodeInternal(importee: string) {
35
+ return importee.startsWith('node:') || builtinModules.includes(importee);
36
+ }
37
+
31
38
  function isBareImport(importee: string): boolean {
32
39
  if (
33
40
  !importee ||