Skip to content

Commit 548301b

Browse files
committed
add parserOptions.svelteConfig
1 parent 7b76dee commit 548301b

16 files changed

+2955
-160
lines changed

README.md

+31-3
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,30 @@ For example in `.eslintrc.*`:
245245
}
246246
```
247247

248+
### parserOptions.svelteConfig
249+
250+
If you are using `eslint.config.js`, you can provide a `svelte.config.js` in the `parserOptions.svelteConfig` property.
251+
252+
For example:
253+
254+
```js
255+
import svelteConfig from "./svelte.config.js";
256+
export default [
257+
{
258+
files: ["**/*.svelte", "*.svelte"],
259+
languageOptions: {
260+
parser: svelteParser,
261+
parserOptions: {
262+
svelteConfig: svelteConfig,
263+
},
264+
},
265+
},
266+
];
267+
```
268+
248269
### parserOptions.svelteFeatures
249270

250-
You can use `parserOptions.svelteFeatures` property to specify how to parse related to Svelte features. For example:
271+
You can use `parserOptions.svelteFeatures` property to specify how to parse related to Svelte features.
251272

252273
For example in `eslint.config.js`:
253274

@@ -263,7 +284,7 @@ export default [
263284
/* It may be changed or removed in minor versions without notice. */
264285
// If true, it will analyze Runes.
265286
// By default, it will try to read `compilerOptions.runes` from `svelte.config.js`.
266-
// However, note that if it cannot be resolved due to static analysis, it will behave as false.
287+
// However, note that if `parserOptions.svelteConfig` is not specified and the file cannot be parsed by static analysis, it will behave as `false`.
267288
runes: false,
268289
/* -- Experimental Svelte Features -- */
269290
/* It may be changed or removed in minor versions without notice. */
@@ -288,7 +309,7 @@ For example in `.eslintrc.*`:
288309
/* It may be changed or removed in minor versions without notice. */
289310
// If true, it will analyze Runes.
290311
// By default, it will try to read `compilerOptions.runes` from `svelte.config.js`.
291-
// However, note that if it cannot be resolved due to static analysis, it will behave as false.
312+
// However, note that if the file cannot be parsed by static analysis, it will behave as false.
292313
"runes": false,
293314
/* -- Experimental Svelte Features -- */
294315
/* It may be changed or removed in minor versions without notice. */
@@ -311,13 +332,15 @@ When using this mode in an ESLint configuration, it is recommended to set it per
311332
For example in `eslint.config.js`:
312333

313334
```js
335+
import svelteConfig from "./svelte.config.js";
314336
export default [
315337
{
316338
files: ["**/*.svelte", "*.svelte"],
317339
languageOptions: {
318340
parser: svelteParser,
319341
parserOptions: {
320342
parser: "...",
343+
svelteConfig,
321344
/* ... */
322345
},
323346
},
@@ -327,6 +350,7 @@ export default [
327350
languageOptions: {
328351
parser: svelteParser,
329352
parserOptions: {
353+
svelteConfig,
330354
/* ... */
331355
},
332356
},
@@ -337,6 +361,7 @@ export default [
337361
parser: svelteParser,
338362
parserOptions: {
339363
parser: "...(ts parser)...",
364+
svelteConfig,
340365
/* ... */
341366
},
342367
},
@@ -354,13 +379,15 @@ For example in `.eslintrc.*`:
354379
"parser": "svelte-eslint-parser",
355380
"parserOptions": {
356381
"parser": "...",
382+
"svelteFeatures": { "runes": true },
357383
/* ... */
358384
},
359385
},
360386
{
361387
"files": ["*.svelte.js"],
362388
"parser": "svelte-eslint-parser",
363389
"parserOptions": {
390+
"svelteFeatures": { "runes": true },
364391
/* ... */
365392
},
366393
},
@@ -369,6 +396,7 @@ For example in `.eslintrc.*`:
369396
"parser": "svelte-eslint-parser",
370397
"parserOptions": {
371398
"parser": "...(ts parser)...",
399+
"svelteFeatures": { "runes": true },
372400
/* ... */
373401
},
374402
},

src/index.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import { KEYS } from "./visitor-keys";
44
import { ParseError } from "./errors";
55
export {
66
parseForESLint,
7-
StyleContext,
8-
StyleContextNoStyleElement,
9-
StyleContextParseError,
10-
StyleContextSuccess,
11-
StyleContextUnknownLang,
7+
type StyleContext,
8+
type StyleContextNoStyleElement,
9+
type StyleContextParseError,
10+
type StyleContextSuccess,
11+
type StyleContextUnknownLang,
1212
} from "./parser";
1313
export * as meta from "./meta";
1414
export { name } from "./meta";
15+
export type { SvelteConfig } from "./svelte-config";
1516

1617
export { AST, ParseError };
1718

src/parser/index.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ import {
4444
resolveSvelteParseContextForSvelteScript,
4545
type SvelteParseContext,
4646
} from "./svelte-parse-context";
47-
import type { StaticSvelteConfigFile } from "../svelte-config";
48-
import { resolveSvelteConfig } from "../svelte-config";
47+
import type { SvelteConfig } from "../svelte-config";
48+
import { resolveSvelteConfigFromOption } from "../svelte-config";
4949

5050
export {
5151
StyleContext,
@@ -96,7 +96,7 @@ type ParseResult = {
9696
* Parse source code
9797
*/
9898
export function parseForESLint(code: string, options?: any): ParseResult {
99-
const svelteConfig = resolveSvelteConfig(options?.filePath);
99+
const svelteConfig = resolveSvelteConfigFromOption(options);
100100
const parserOptions = normalizeParserOptions(options);
101101

102102
if (
@@ -124,7 +124,7 @@ export function parseForESLint(code: string, options?: any): ParseResult {
124124
*/
125125
function parseAsSvelte(
126126
code: string,
127-
svelteConfig: StaticSvelteConfigFile | null,
127+
svelteConfig: SvelteConfig | null,
128128
parserOptions: NormalizedParserOptions,
129129
): ParseResult {
130130
const ctx = new Context(code, parserOptions);

src/parser/svelte-parse-context.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type * as Compiler from "svelte/compiler";
22
import type * as SvAST from "./svelte-ast-types";
33
import type { NormalizedParserOptions } from "./parser-options";
44
import { compilerVersion, svelteVersion } from "./svelte-version";
5-
import type { StaticSvelteConfigFile } from "../svelte-config";
5+
import type { SvelteConfig } from "../svelte-config";
66

77
/** The context for parsing. */
88
export type SvelteParseContext = {
@@ -15,24 +15,24 @@ export type SvelteParseContext = {
1515
/** The version of "svelte/compiler". */
1616
compilerVersion: string;
1717
/** The result of static analysis of `svelte.config.js`. */
18-
svelteConfig: StaticSvelteConfigFile | null;
18+
svelteConfig: SvelteConfig | null;
1919
};
2020

2121
export function isEnableRunes(
22-
svelteConfig: StaticSvelteConfigFile | null,
22+
svelteConfig: SvelteConfig | null,
2323
parserOptions: NormalizedParserOptions,
2424
): boolean {
2525
if (!svelteVersion.gte(5)) return false;
2626
if (parserOptions.svelteFeatures?.runes != null) {
2727
return Boolean(parserOptions.svelteFeatures.runes);
28-
} else if (svelteConfig?.config.compilerOptions?.runes != null) {
29-
return Boolean(svelteConfig.config.compilerOptions.runes);
28+
} else if (svelteConfig?.compilerOptions?.runes != null) {
29+
return Boolean(svelteConfig.compilerOptions.runes);
3030
}
3131
return false;
3232
}
3333

3434
export function resolveSvelteParseContextForSvelte(
35-
svelteConfig: StaticSvelteConfigFile | null,
35+
svelteConfig: SvelteConfig | null,
3636
parserOptions: NormalizedParserOptions,
3737
svelteAst: Compiler.Root | SvAST.AstLegacy,
3838
): SvelteParseContext {
@@ -53,14 +53,14 @@ export function resolveSvelteParseContextForSvelte(
5353
}
5454

5555
export function resolveSvelteParseContextForSvelteScript(
56-
svelteConfig: StaticSvelteConfigFile | null,
56+
svelteConfig: SvelteConfig | null,
5757
parserOptions: NormalizedParserOptions,
5858
): SvelteParseContext {
5959
return resolveSvelteParseContext(svelteConfig, parserOptions);
6060
}
6161

6262
function resolveSvelteParseContext(
63-
svelteConfig: StaticSvelteConfigFile | null,
63+
svelteConfig: SvelteConfig | null,
6464
parserOptions: NormalizedParserOptions,
6565
): SvelteParseContext {
6666
return {

src/svelte-config/index.ts

+94-22
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,108 @@
11
import path from "path";
22
import fs from "fs";
33
import { parseConfig } from "./parser";
4+
import type * as Compiler from "svelte/compiler";
45

5-
/** The result of static analysis of `svelte.config.js`. */
6-
export type StaticSvelteConfig = {
7-
compilerOptions?: {
8-
runes?: boolean;
6+
export type SvelteConfig = {
7+
compilerOptions?: Compiler.CompileOptions;
8+
extensions?: string[];
9+
kit?: KitConfig;
10+
preprocess?: unknown;
11+
vitePlugin?: unknown;
12+
onwarn?: (
13+
warning: Compiler.Warning,
14+
defaultHandler: (warning: Compiler.Warning) => void,
15+
) => void;
16+
[key: string]: unknown;
17+
};
18+
19+
interface KitConfig {
20+
adapter?: unknown;
21+
alias?: Record<string, string>;
22+
appDir?: string;
23+
csp?: {
24+
mode?: "hash" | "nonce" | "auto";
25+
directives?: unknown;
26+
reportOnly?: unknown;
27+
};
28+
csrf?: {
29+
checkOrigin?: boolean;
930
};
10-
kit?: {
11-
files?: {
12-
routes?: string;
31+
embedded?: boolean;
32+
env?: {
33+
dir?: string;
34+
publicPrefix?: string;
35+
privatePrefix?: string;
36+
};
37+
files?: {
38+
assets?: string;
39+
hooks?: {
40+
client?: string;
41+
server?: string;
42+
universal?: string;
1343
};
44+
lib?: string;
45+
params?: string;
46+
routes?: string;
47+
serviceWorker?: string;
48+
appTemplate?: string;
49+
errorTemplate?: string;
1450
};
15-
};
16-
export type StaticSvelteConfigFile = {
17-
filePath: string;
18-
config: StaticSvelteConfig;
19-
};
51+
inlineStyleThreshold?: number;
52+
moduleExtensions?: string[];
53+
outDir?: string;
54+
output?: {
55+
preloadStrategy?: "modulepreload" | "preload-js" | "preload-mjs";
56+
};
57+
paths?: {
58+
assets?: "" | `http://${string}` | `https://${string}`;
59+
base?: "" | `/${string}`;
60+
relative?: boolean;
61+
};
62+
prerender?: {
63+
concurrency?: number;
64+
crawl?: boolean;
65+
entries?: ("*" | `/${string}`)[];
66+
handleHttpError?: unknown;
67+
handleMissingId?: unknown;
68+
handleEntryGeneratorMismatch?: unknown;
69+
origin?: string;
70+
};
71+
serviceWorker?: {
72+
register?: boolean;
73+
files?(filepath: string): boolean;
74+
};
75+
typescript?: {
76+
config?: (config: Record<string, any>) => Record<string, any> | void;
77+
};
78+
version?: {
79+
name?: string;
80+
pollInterval?: number;
81+
};
82+
}
83+
84+
const caches = new Map<string, SvelteConfig | null>();
2085

21-
const caches = new Map<string, StaticSvelteConfigFile | null>();
86+
/**
87+
* Resolves svelte.config.
88+
*/
89+
export function resolveSvelteConfigFromOption(
90+
options: any,
91+
): SvelteConfig | null {
92+
if (options?.svelteConfig) {
93+
return options.svelteConfig;
94+
}
95+
return resolveSvelteConfig(options?.filePath);
96+
}
2297

2398
/**
24-
* Resolves svelte.config.js.
25-
* It searches the parent directories of the given file to find svelte.config.js,
99+
* Resolves `svelte.config.js`.
100+
* It searches the parent directories of the given file to find `svelte.config.js`,
26101
* and returns the static analysis result for it.
27102
*/
28-
export function resolveSvelteConfig(
103+
function resolveSvelteConfig(
29104
filePath: string | undefined,
30-
): StaticSvelteConfigFile | null {
105+
): SvelteConfig | null {
31106
const cwd =
32107
filePath && fs.existsSync(filePath)
33108
? path.dirname(filePath)
@@ -41,11 +116,8 @@ export function resolveSvelteConfig(
41116

42117
const code = fs.readFileSync(configFilePath, "utf8");
43118
const config = parseConfig(code);
44-
const result: StaticSvelteConfigFile | null = config
45-
? { config, filePath: configFilePath }
46-
: null;
47-
caches.set(configFilePath, result);
48-
return result;
119+
caches.set(configFilePath, config);
120+
return config;
49121
}
50122

51123
/**

0 commit comments

Comments
 (0)