From bdd35804e67dd13b362231603d6be54d9a25a13e Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sat, 29 Oct 2022 23:52:15 +0900 Subject: [PATCH 01/24] feat: add no-export-load-in-svelte-module-in-kit-pages --- README.md | 1 + docs/rules.md | 1 + ...port-load-in-svelte-module-in-kit-pages.md | 55 +++++++++++++++++++ src/configs/recommended.ts | 1 + ...port-load-in-svelte-module-in-kit-pages.ts | 52 ++++++++++++++++++ src/utils/rules.ts | 2 + .../presets/html/preset-html-errors.yaml | 16 ++++++ .../presets/none/preset-none-errors.yaml | 16 ++++++ .../invalid/test01-errors.yaml | 4 ++ .../invalid/test01-input.svelte | 3 + .../invalid/test02-errors.yaml | 4 ++ .../invalid/test02-input.svelte | 3 + .../valid/test01-input.svelte | 3 + .../valid/test02-input.svelte | 3 + .../valid/test03-input.svelte | 3 + .../valid/test04-input.svelte | 3 + ...port-load-in-svelte-module-in-kit-pages.ts | 16 ++++++ 17 files changed, 186 insertions(+) create mode 100644 docs/rules/no-export-load-in-svelte-module-in-kit-pages.md create mode 100644 src/rules/no-export-load-in-svelte-module-in-kit-pages.ts create mode 100644 tests/fixtures/rules/html-self-closing/invalid/presets/html/preset-html-errors.yaml create mode 100644 tests/fixtures/rules/html-self-closing/invalid/presets/none/preset-none-errors.yaml create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test01-errors.yaml create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test01-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-errors.yaml create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test01-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test02-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test03-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test04-input.svelte create mode 100644 tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts diff --git a/README.md b/README.md index 4f19f5e35..6a61a1838 100644 --- a/README.md +++ b/README.md @@ -266,6 +266,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-else-if-blocks](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-else-if-blocks/) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-style-properties](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-style-properties/) | disallow duplicate style properties | :star: | | [svelte/no-dynamic-slot-name](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: | +| [svelte/no-export-load-in-svelte-module-in-kit-pages](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-export-load-in-svelte-module-in-kit-pages/) | Disallow exporting load functions in `*.svelte` module in Svelte Kit page components. | :star: | | [svelte/no-not-function-handler](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-not-function-handler/) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-object-in-text-mustaches/) | disallow objects in text mustache interpolation | :star: | | [svelte/no-shorthand-style-property-overrides](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-shorthand-style-property-overrides/) | disallow shorthand style properties that override related longhand properties | :star: | diff --git a/docs/rules.md b/docs/rules.md index 9601f4517..4ea223ab0 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -19,6 +19,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | [svelte/no-dupe-else-if-blocks](./rules/no-dupe-else-if-blocks.md) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-style-properties](./rules/no-dupe-style-properties.md) | disallow duplicate style properties | :star: | | [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: | +| [svelte/no-export-load-in-svelte-module-in-kit-pages](./rules/no-export-load-in-svelte-module-in-kit-pages.md) | Disallow exporting load functions in `*.svelte` module in Svelte Kit page components. | :star: | | [svelte/no-not-function-handler](./rules/no-not-function-handler.md) | disallow use of not function in event handler | :star: | | [svelte/no-object-in-text-mustaches](./rules/no-object-in-text-mustaches.md) | disallow objects in text mustache interpolation | :star: | | [svelte/no-shorthand-style-property-overrides](./rules/no-shorthand-style-property-overrides.md) | disallow shorthand style properties that override related longhand properties | :star: | diff --git a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md new file mode 100644 index 000000000..61114bfb5 --- /dev/null +++ b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md @@ -0,0 +1,55 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "svelte/no-export-load-in-svelte-module-in-kit-pages" +description: "Disallow exporting load functions in `*.svelte` module in Svelte Kit page components." +--- + +# svelte/no-export-load-in-svelte-module-in-kit-pages + +> Disallow exporting load functions in `*.svelte` module in Svelte Kit page components. + +- :gear: This rule is included in `"plugin:svelte/recommended"`. + +## :book: Rule Details + +This rule reports unexpected exported `load` function at ` +``` + + + +## :wrench: Options + +```json +{ + "svelte/no-export-load-in-svelte-module-in-kit-pages": ["error", {}] +} +``` + +- + +## :books: Further Reading + +- [SvelteKit Migration Guide (v1.0.0-next.405)](https://github.com/sveltejs/kit/discussions/5774#discussioncomment-3292693) + +## :mag: Implementation + +- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts) +- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts) diff --git a/src/configs/recommended.ts b/src/configs/recommended.ts index b513c4b65..461efa888 100644 --- a/src/configs/recommended.ts +++ b/src/configs/recommended.ts @@ -12,6 +12,7 @@ export = { "svelte/no-dupe-else-if-blocks": "error", "svelte/no-dupe-style-properties": "error", "svelte/no-dynamic-slot-name": "error", + "svelte/no-export-load-in-svelte-module-in-kit-pages": "error", "svelte/no-inner-declarations": "error", "svelte/no-not-function-handler": "error", "svelte/no-object-in-text-mustaches": "error", diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts new file mode 100644 index 000000000..354d24a74 --- /dev/null +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -0,0 +1,52 @@ +import type * as ESTree from "estree" +import { createRule } from "../utils" +import fs from "fs" + +const hasSvelteKit = (() => { + try { + const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) + return Boolean(packageJson.dependencies["@sveltejs/kit"]) + } catch (_e) { + return false + } +})() + +export default createRule("no-export-load-in-svelte-module-in-kit-pages", { + meta: { + docs: { + description: + "Disallow exporting load functions in `*.svelte` module in Svelte Kit page components.", + category: "Possible Errors", + recommended: true, + }, + schema: [], + messages: { + unexpected: + "Disallow exporting load functions in `*.svelte` module in Svelte Kit page components.", + }, + type: "problem", + }, + create(context) { + if (!hasSvelteKit) return {} + let isModule = false + return { + // diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-errors.yaml b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-errors.yaml new file mode 100644 index 000000000..45723fd65 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-errors.yaml @@ -0,0 +1,4 @@ +- message: "Disallow exporting load functions in `*.svelte` module in Svelte Kit page components." + line: 2 + column: 16 + suggestions: null diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-input.svelte new file mode 100644 index 000000000..dbc677cab --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/test02-input.svelte @@ -0,0 +1,3 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test01-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test01-input.svelte new file mode 100644 index 000000000..5c80bb85b --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test01-input.svelte @@ -0,0 +1,3 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test02-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test02-input.svelte new file mode 100644 index 000000000..73e91756d --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test02-input.svelte @@ -0,0 +1,3 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test03-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test03-input.svelte new file mode 100644 index 000000000..64139d64b --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test03-input.svelte @@ -0,0 +1,3 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test04-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test04-input.svelte new file mode 100644 index 000000000..f2990d566 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test04-input.svelte @@ -0,0 +1,3 @@ + diff --git a/tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts new file mode 100644 index 000000000..fc83d0b3a --- /dev/null +++ b/tests/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -0,0 +1,16 @@ +import { RuleTester } from "eslint" +import rule from "../../../src/rules/no-export-load-in-svelte-module-in-kit-pages" +import { loadTestCases } from "../../utils/utils" + +const tester = new RuleTester({ + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, +}) + +tester.run( + "no-export-load-in-svelte-module-in-kit-pages", + rule as any, + loadTestCases("no-export-load-in-svelte-module-in-kit-pages"), +) From ab5e4d21350bf239cc30d3a9276094d8286b6a47 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 00:20:28 +0900 Subject: [PATCH 02/24] chore: add changeset --- .changeset/orange-months-sparkle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/orange-months-sparkle.md diff --git a/.changeset/orange-months-sparkle.md b/.changeset/orange-months-sparkle.md new file mode 100644 index 000000000..0021c4893 --- /dev/null +++ b/.changeset/orange-months-sparkle.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat: add `no-export-load-in-svelte-module-in-kit-pages` rule From c92a0529899baeef74ef80a8ab92e4fef7b4c1d6 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 00:36:22 +0900 Subject: [PATCH 03/24] chore: add test --- .../valid/test05-input.svelte | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test05-input.svelte diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test05-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test05-input.svelte new file mode 100644 index 000000000..304b081e0 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test05-input.svelte @@ -0,0 +1,3 @@ + From 07dbc08f64c32a00b31a47bc70d715eca13b8c3a Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 00:36:40 +0900 Subject: [PATCH 04/24] fix: check devDependencies also --- package.json | 2 +- src/rules/no-export-load-in-svelte-module-in-kit-pages.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 09bf15212..53039aca0 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,7 @@ "access": "public" }, "typeCoverage": { - "atLeast": 98.71, + "atLeast": 98.7, "cache": true, "detail": true, "ignoreAsAssertion": true, diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 354d24a74..092c2dc43 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -5,7 +5,10 @@ import fs from "fs" const hasSvelteKit = (() => { try { const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) - return Boolean(packageJson.dependencies["@sveltejs/kit"]) + return Boolean( + packageJson.dependencies["@sveltejs/kit"] ?? + packageJson.devDependencies["@sveltejs/kit"], + ) } catch (_e) { return false } From 08fc369084762109f9473ba163ce61af0e861958 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 01:35:37 +0900 Subject: [PATCH 05/24] fix: adjust for test --- package.json | 2 +- src/rules/no-export-load-in-svelte-module-in-kit-pages.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 53039aca0..0bd6d9649 100644 --- a/package.json +++ b/package.json @@ -174,7 +174,7 @@ "access": "public" }, "typeCoverage": { - "atLeast": 98.7, + "atLeast": 98.69, "cache": true, "detail": true, "ignoreAsAssertion": true, diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 092c2dc43..25ce83768 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -5,6 +5,9 @@ import fs from "fs" const hasSvelteKit = (() => { try { const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) + // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. + // So always it returns true if it runs on the package. + if (packageJson.name === "eslint-plugin-svelte") return true return Boolean( packageJson.dependencies["@sveltejs/kit"] ?? packageJson.devDependencies["@sveltejs/kit"], From 4cf5a14e732cdad26dc39e2401c1f3b836c6e7fd Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 02:26:39 +0900 Subject: [PATCH 06/24] feat: add config --- README.md | 22 +++++++++++++++++++ ...port-load-in-svelte-module-in-kit-pages.md | 9 ++++++-- docs/user-guide.md | 22 +++++++++++++++++++ ...port-load-in-svelte-module-in-kit-pages.ts | 6 +++++ src/types.ts | 5 +++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6a61a1838..05371f507 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,28 @@ module.exports = { } ``` +#### settings.kit + +If you use SvelteKit with not default configuration, you need to set below configurations. +Object of it is subset of SvelteKit's configuration. +THerefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for each configuration. + +e.g. + +```js +module.exports = { + // ... + settings: { + kit: { + files: { + routes: "src/routes", + }, + }, + }, + // ... +} +``` + ### Running ESLint from the command line If you want to run `eslint` from the command line, make sure you include the `.svelte` extension using [the `--ext` option](https://eslint.org/docs/user-guide/configuring#specifying-file-extensions-to-lint) or a glob pattern, because ESLint targets only `.js` files by default. diff --git a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md index 61114bfb5..0f03a3ff9 100644 --- a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md +++ b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md @@ -39,11 +39,16 @@ And the API has changed. ```json { - "svelte/no-export-load-in-svelte-module-in-kit-pages": ["error", {}] + "svelte/no-export-load-in-svelte-module-in-kit-pages": [ + "error", + { + "routes": "src/routes" + } + ] } ``` -- +- `routes`: Please set a value if `kit.files.routes` of `svelte.config.js` is not `src/routes`. ## :books: Further Reading diff --git a/docs/user-guide.md b/docs/user-guide.md index bd1295900..ff9c6a886 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -168,6 +168,28 @@ module.exports = { } ``` +#### settings.kit + +If you use SvelteKit with not default configuration, you need to set below configurations. +Object of it is subset of SvelteKit's configuration. +THerefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for each configuration. + +e.g. + +```js +module.exports = { + // ... + settings: { + kit: { + files: { + routes: "src/routes", + }, + }, + }, + // ... +} +``` + ### Running ESLint from the command line If you want to run `eslint` from the command line, make sure you include the `.svelte` extension using [the `--ext` option](https://eslint.org/docs/user-guide/configuring#specifying-file-extensions-to-lint) or a glob pattern, because ESLint targets only `.js` files by default. diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 25ce83768..7418ad964 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -35,6 +35,12 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { create(context) { if (!hasSvelteKit) return {} let isModule = false + + // return false if it's not a Svelte Kit page component. + const routes = context.settings?.kit?.files?.routes || "src/routes" + const filePath = context.getFilename().replace(context.getCwd?.() ?? "", "") + if (filePath.includes(routes)) return {} + return { // + ["SvelteEndTag"]: () => { + isModule = false + }, + // export function load() {} // export const load = () => {} [`ExportNamedDeclaration :matches(FunctionDeclaration, VariableDeclaration > VariableDeclarator) > Identifier[name="load"]`]: diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test06-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test06-input.svelte new file mode 100644 index 000000000..8c752e69e --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test06-input.svelte @@ -0,0 +1,7 @@ + + + From a9fb99de8ad3bdd08b708e97d2d63fb55f71a855 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 11:30:09 +0900 Subject: [PATCH 09/24] fix: bug --- .../no-export-load-in-svelte-module-in-kit-pages.ts | 11 ++++++++--- .../invalid/_config.json | 9 +++++++++ .../valid/_config.json | 9 +++++++++ .../valid/not-page/_config.json | 9 +++++++++ .../valid/not-page/test01-input.svelte | 3 +++ .../valid/not-page/test02-input.svelte | 3 +++ 6 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/invalid/_config.json create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/_config.json create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/_config.json create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/test01-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/test02-input.svelte diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 78c9fd6fd..1bc3761da 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -37,9 +37,14 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { let isModule = false // return false if it's not a Svelte Kit page component. - const routes = context.settings?.kit?.files?.routes || "src/routes" - const filePath = context.getFilename().replace(context.getCwd?.() ?? "", "") - if (filePath.includes(routes)) return {} + const routes = + context.settings?.kit?.files?.routes?.replace(/^\//, "") || "src/routes" + + const filePath = context + .getFilename() + .replace(context.getCwd?.() ?? "", "") + .replace(/^\//, "") + if (!filePath.startsWith(routes)) return {} return { // diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/test02-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/test02-input.svelte new file mode 100644 index 000000000..dbc677cab --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/not-page/test02-input.svelte @@ -0,0 +1,3 @@ + From 59d3097ae783e40b72e8c9a799f96a98c8468f3b Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 11:46:23 +0900 Subject: [PATCH 10/24] chore: uupdate docus --- README.md | 2 +- .../no-export-load-in-svelte-module-in-kit-pages.md | 13 +------------ docs/user-guide.md | 2 +- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7931ee8e9..fdf3420ec 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ module.exports = { If you use SvelteKit with not default configuration, you need to set below configurations. The schema is subset of SvelteKit's configuration. -Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for each configuration. +Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details. e.g. diff --git a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md index 0f03a3ff9..9898635a2 100644 --- a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md +++ b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md @@ -37,18 +37,7 @@ And the API has changed. ## :wrench: Options -```json -{ - "svelte/no-export-load-in-svelte-module-in-kit-pages": [ - "error", - { - "routes": "src/routes" - } - ] -} -``` - -- `routes`: Please set a value if `kit.files.routes` of `svelte.config.js` is not `src/routes`. +Nothing. But if use are using not default routes folder, please set configuration according the [user guide](../user-guide.md#settings-kit). ## :books: Further Reading diff --git a/docs/user-guide.md b/docs/user-guide.md index 53d529f27..57179db7c 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -172,7 +172,7 @@ module.exports = { If you use SvelteKit with not default configuration, you need to set below configurations. The schema is subset of SvelteKit's configuration. -Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for each configuration. +Therefore please check [SvelteKit docs](https://kit.svelte.dev/docs/configuration) for more details. e.g. From 4fc4c2261095d41cb803162e824d16c930395cb2 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 11:49:30 +0900 Subject: [PATCH 11/24] chore: update docs --- docs/rules/no-export-load-in-svelte-module-in-kit-pages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md index 9898635a2..9b04f4ae1 100644 --- a/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md +++ b/docs/rules/no-export-load-in-svelte-module-in-kit-pages.md @@ -37,7 +37,7 @@ And the API has changed. ## :wrench: Options -Nothing. But if use are using not default routes folder, please set configuration according the [user guide](../user-guide.md#settings-kit). +Nothing. But if use are using not default routes folder, please set configuration according to the [user guide](../user-guide.md#settings-kit). ## :books: Further Reading From 332c4bcce26f7b3bc87d814c5ae84b0915289988 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Sun, 30 Oct 2022 12:37:36 +0900 Subject: [PATCH 12/24] chore: add kit helper --- src/rules/kit-helpers/kit-helpers.ts | 33 +++++++++++++++++++ ...port-load-in-svelte-module-in-kit-pages.ts | 30 ++--------------- 2 files changed, 35 insertions(+), 28 deletions(-) create mode 100644 src/rules/kit-helpers/kit-helpers.ts diff --git a/src/rules/kit-helpers/kit-helpers.ts b/src/rules/kit-helpers/kit-helpers.ts new file mode 100644 index 000000000..f83fe87c4 --- /dev/null +++ b/src/rules/kit-helpers/kit-helpers.ts @@ -0,0 +1,33 @@ +import type { RuleContext } from "../../types" +import fs from "fs" + +/** + * return true if it's a Svelte Kit page component. + * @param context + * @returns + */ +export function isKitPageComponent(context: RuleContext): boolean { + // return false if it's not a Svelte Kit page component. + const routes = + context.settings?.kit?.files?.routes?.replace(/^\//, "") || "src/routes" + const filePath = context + .getFilename() + .replace(context.getCwd?.() ?? "", "") + .replace(/^\//, "") + return filePath.startsWith(routes) +} + +export const hasSvelteKit = (() => { + try { + const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) + // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. + // So always it returns true if it runs on the package. + if (packageJson.name === "eslint-plugin-svelte") return true + return Boolean( + packageJson.dependencies["@sveltejs/kit"] ?? + packageJson.devDependencies["@sveltejs/kit"], + ) + } catch (_e) { + return false + } +})() diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 1bc3761da..e6e92eb8c 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -1,21 +1,6 @@ import type * as ESTree from "estree" import { createRule } from "../utils" -import fs from "fs" - -const hasSvelteKit = (() => { - try { - const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) - // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. - // So always it returns true if it runs on the package. - if (packageJson.name === "eslint-plugin-svelte") return true - return Boolean( - packageJson.dependencies["@sveltejs/kit"] ?? - packageJson.devDependencies["@sveltejs/kit"], - ) - } catch (_e) { - return false - } -})() +import { isKitPageComponent, hasSvelteKit } from "./kit-helpers/kit-helpers" export default createRule("no-export-load-in-svelte-module-in-kit-pages", { meta: { @@ -33,19 +18,8 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { type: "problem", }, create(context) { - if (!hasSvelteKit) return {} + if (!hasSvelteKit || !isKitPageComponent(context)) return {} let isModule = false - - // return false if it's not a Svelte Kit page component. - const routes = - context.settings?.kit?.files?.routes?.replace(/^\//, "") || "src/routes" - - const filePath = context - .getFilename() - .replace(context.getCwd?.() ?? "", "") - .replace(/^\//, "") - if (!filePath.startsWith(routes)) return {} - return { // + + diff --git a/src/rules/kit-helpers/kit-helpers.ts b/src/rules/kit-helpers/kit-helpers.ts index f83fe87c4..50ff1b726 100644 --- a/src/rules/kit-helpers/kit-helpers.ts +++ b/src/rules/kit-helpers/kit-helpers.ts @@ -9,7 +9,7 @@ import fs from "fs" export function isKitPageComponent(context: RuleContext): boolean { // return false if it's not a Svelte Kit page component. const routes = - context.settings?.kit?.files?.routes?.replace(/^\//, "") || "src/routes" + context.settings?.kit?.files?.routes?.replace(/^\//, "") ?? "src/routes" const filePath = context .getFilename() .replace(context.getCwd?.() ?? "", "") @@ -18,6 +18,8 @@ export function isKitPageComponent(context: RuleContext): boolean { } export const hasSvelteKit = (() => { + // Hack: if it runs on browser, it regards as Svelte Kit project. + if (!fs.readFileSync) return true try { const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index e6e92eb8c..b0a3b7008 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -22,13 +22,13 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { let isModule = false return { // - ["SvelteEndTag"]: () => { + "Program > SvelteScriptElement:exit": () => { isModule = false }, From 5353b32a4795994622f3dfb7669ff90c9eaab847 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 1 Nov 2022 02:22:59 +0900 Subject: [PATCH 19/24] fix: project root path finding logic --- src/rules/kit-helpers/kit-helpers.ts | 63 ++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/src/rules/kit-helpers/kit-helpers.ts b/src/rules/kit-helpers/kit-helpers.ts index 50ff1b726..b4a2a0deb 100644 --- a/src/rules/kit-helpers/kit-helpers.ts +++ b/src/rules/kit-helpers/kit-helpers.ts @@ -1,5 +1,10 @@ import type { RuleContext } from "../../types" import fs from "fs" +import path from "path" + +const isRunOnBrowser = !fs.readFileSync + +const projectRootPath = isRunOnBrowser ? "" : getProjectRootPath() /** * return true if it's a Svelte Kit page component. @@ -7,24 +12,28 @@ import fs from "fs" * @returns */ export function isKitPageComponent(context: RuleContext): boolean { - // return false if it's not a Svelte Kit page component. + // Hack: if it runs on browser, it regards as Svelte Kit project. + if (isRunOnBrowser) return true + const routes = context.settings?.kit?.files?.routes?.replace(/^\//, "") ?? "src/routes" const filePath = context .getFilename() - .replace(context.getCwd?.() ?? "", "") + .replace(projectRootPath ?? "", "") .replace(/^\//, "") return filePath.startsWith(routes) } export const hasSvelteKit = (() => { // Hack: if it runs on browser, it regards as Svelte Kit project. - if (!fs.readFileSync) return true + if (isRunOnBrowser || !projectRootPath) return true try { - const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf8")) - // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. - // So always it returns true if it runs on the package. - if (packageJson.name === "eslint-plugin-svelte") return true + const packageJson = readPackageJson(projectRootPath) + if (!packageJson) return false + if (packageJson.name === "eslint-plugin-svelte") + // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. + // So always it returns true if it runs on the package. + return true return Boolean( packageJson.dependencies["@sveltejs/kit"] ?? packageJson.devDependencies["@sveltejs/kit"], @@ -33,3 +42,43 @@ export const hasSvelteKit = (() => { return false } })() + +/** + * refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/get-package-json.js#L46-L75 + * @param startPath + * @returns + */ +function getProjectRootPath(startPath = "a.js"): string | null { + const startDir = path.dirname(path.resolve(startPath)) + let dir = startDir + let prevDir = "" + do { + const filePath = path.join(dir, "package.json") + if (fs.existsSync(filePath)) return dir + prevDir = dir + dir = path.resolve(dir, "..") + } while (dir !== prevDir) + return null +} + +/** + * + * @param dir directory path + * @returns JSON data of package.json or null + */ +function readPackageJson(dir: string): Record | null { + const filePath = path.join(dir, "package.json") + try { + const text = fs.readFileSync(filePath, "utf8") + const data = JSON.parse(text) + + if (typeof data === "object" && data !== null) { + data.filePath = filePath + return data + } + } catch (_err) { + // do nothing. + } + + return null +} From d68a1cfcd6415d574ebf00758493a8a750eaddbb Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 1 Nov 2022 03:12:44 +0900 Subject: [PATCH 20/24] chore: utilize --- src/rules/kit-helpers/kit-helpers.ts | 84 ------------------- ...port-load-in-svelte-module-in-kit-pages.ts | 6 +- src/utils/cache.ts | 63 ++++++++++++++ src/utils/get-package-json.ts | 77 +++++++++++++++++ src/utils/svelte-kit.ts | 65 ++++++++++++++ 5 files changed, 209 insertions(+), 86 deletions(-) delete mode 100644 src/rules/kit-helpers/kit-helpers.ts create mode 100644 src/utils/cache.ts create mode 100644 src/utils/get-package-json.ts create mode 100644 src/utils/svelte-kit.ts diff --git a/src/rules/kit-helpers/kit-helpers.ts b/src/rules/kit-helpers/kit-helpers.ts deleted file mode 100644 index b4a2a0deb..000000000 --- a/src/rules/kit-helpers/kit-helpers.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { RuleContext } from "../../types" -import fs from "fs" -import path from "path" - -const isRunOnBrowser = !fs.readFileSync - -const projectRootPath = isRunOnBrowser ? "" : getProjectRootPath() - -/** - * return true if it's a Svelte Kit page component. - * @param context - * @returns - */ -export function isKitPageComponent(context: RuleContext): boolean { - // Hack: if it runs on browser, it regards as Svelte Kit project. - if (isRunOnBrowser) return true - - const routes = - context.settings?.kit?.files?.routes?.replace(/^\//, "") ?? "src/routes" - const filePath = context - .getFilename() - .replace(projectRootPath ?? "", "") - .replace(/^\//, "") - return filePath.startsWith(routes) -} - -export const hasSvelteKit = (() => { - // Hack: if it runs on browser, it regards as Svelte Kit project. - if (isRunOnBrowser || !projectRootPath) return true - try { - const packageJson = readPackageJson(projectRootPath) - if (!packageJson) return false - if (packageJson.name === "eslint-plugin-svelte") - // Hack: CI removes `@sveltejs/kit` and it returns false and test failed. - // So always it returns true if it runs on the package. - return true - return Boolean( - packageJson.dependencies["@sveltejs/kit"] ?? - packageJson.devDependencies["@sveltejs/kit"], - ) - } catch (_e) { - return false - } -})() - -/** - * refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/get-package-json.js#L46-L75 - * @param startPath - * @returns - */ -function getProjectRootPath(startPath = "a.js"): string | null { - const startDir = path.dirname(path.resolve(startPath)) - let dir = startDir - let prevDir = "" - do { - const filePath = path.join(dir, "package.json") - if (fs.existsSync(filePath)) return dir - prevDir = dir - dir = path.resolve(dir, "..") - } while (dir !== prevDir) - return null -} - -/** - * - * @param dir directory path - * @returns JSON data of package.json or null - */ -function readPackageJson(dir: string): Record | null { - const filePath = path.join(dir, "package.json") - try { - const text = fs.readFileSync(filePath, "utf8") - const data = JSON.parse(text) - - if (typeof data === "object" && data !== null) { - data.filePath = filePath - return data - } - } catch (_err) { - // do nothing. - } - - return null -} diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 54f5832dd..903723175 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -1,6 +1,6 @@ import type * as ESTree from "estree" import { createRule } from "../utils" -import { isKitPageComponent, hasSvelteKit } from "./kit-helpers/kit-helpers" +import { isKitPageComponent, hasSvelteKit } from "../utils/svelte-kit" export default createRule("no-export-load-in-svelte-module-in-kit-pages", { meta: { @@ -19,7 +19,9 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { type: "problem", }, create(context) { - if (!hasSvelteKit || !isKitPageComponent(context)) return {} + if (!hasSvelteKit(context.getFilename()) || !isKitPageComponent(context)) { + return {} + } let isModule = false return { // "Program > SvelteScriptElement:exit": () => { isModule = false From cfaf58c9b81d20b4cb8155894bb76272abd6c950 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 1 Nov 2022 03:25:10 +0900 Subject: [PATCH 23/24] chore: simplify --- src/rules/no-export-load-in-svelte-module-in-kit-pages.ts | 4 ++-- src/utils/svelte-kit.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index 1df586a35..f29cc5596 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -1,6 +1,6 @@ import type * as ESTree from "estree" import { createRule } from "../utils" -import { isKitPageComponent, hasSvelteKit } from "../utils/svelte-kit" +import { isKitPageComponent } from "../utils/svelte-kit" export default createRule("no-export-load-in-svelte-module-in-kit-pages", { meta: { @@ -19,7 +19,7 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { type: "problem", }, create(context) { - if (!hasSvelteKit(context.getFilename()) || !isKitPageComponent(context)) { + if (!isKitPageComponent(context)) { return {} } let isModule = false diff --git a/src/utils/svelte-kit.ts b/src/utils/svelte-kit.ts index fe03a3b0a..a8b8d8094 100644 --- a/src/utils/svelte-kit.ts +++ b/src/utils/svelte-kit.ts @@ -17,7 +17,7 @@ const isRunOnBrowser = !fs.readFileSync export function isKitPageComponent(context: RuleContext): boolean { // Hack: if it runs on browser, it regards as Svelte Kit project. if (isRunOnBrowser) return true - + if (!hasSvelteKit(context.getFilename())) return false const routes = context.settings?.kit?.files?.routes?.replace(/^\//, "") ?? "src/routes" const filePath = context.getFilename() @@ -33,7 +33,7 @@ export function isKitPageComponent(context: RuleContext): boolean { * @param filePath A file path. * @returns */ -export function hasSvelteKit(filePath: string): boolean { +function hasSvelteKit(filePath: string): boolean { // Hack: if it runs on browser, it regards as Svelte Kit project. if (isRunOnBrowser) return true try { From a9030270b4cc7e9933a8f316244d841088a85e87 Mon Sep 17 00:00:00 2001 From: Yuichiro Yamashita Date: Tue, 1 Nov 2022 10:09:51 +0900 Subject: [PATCH 24/24] fix: false positive --- src/rules/no-export-load-in-svelte-module-in-kit-pages.ts | 2 +- .../valid/test010-input.svelte | 5 +++++ .../valid/test07-input.svelte | 4 ++++ .../valid/test08-input.svelte | 4 ++++ .../valid/test09-input.svelte | 5 +++++ 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test010-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test07-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test08-input.svelte create mode 100644 tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test09-input.svelte diff --git a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts index f29cc5596..40ce3a650 100644 --- a/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts +++ b/src/rules/no-export-load-in-svelte-module-in-kit-pages.ts @@ -37,7 +37,7 @@ export default createRule("no-export-load-in-svelte-module-in-kit-pages", { // export function load() {} // export const load = () => {} - [`ExportNamedDeclaration :matches(FunctionDeclaration, VariableDeclaration > VariableDeclarator) > Identifier[name="load"]`]: + [`:matches(ExportNamedDeclaration > FunctionDeclaration, ExportNamedDeclaration > VariableDeclaration > VariableDeclarator) > Identifier.id[name="load"]`]: (node: ESTree.Identifier) => { if (!isModule) return {} return context.report({ diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test010-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test010-input.svelte new file mode 100644 index 000000000..e364a9162 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test010-input.svelte @@ -0,0 +1,5 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test07-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test07-input.svelte new file mode 100644 index 000000000..1908775c6 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test07-input.svelte @@ -0,0 +1,4 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test08-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test08-input.svelte new file mode 100644 index 000000000..b9d71aae4 --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test08-input.svelte @@ -0,0 +1,4 @@ + diff --git a/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test09-input.svelte b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test09-input.svelte new file mode 100644 index 000000000..6daa28d5e --- /dev/null +++ b/tests/fixtures/rules/no-export-load-in-svelte-module-in-kit-pages/valid/test09-input.svelte @@ -0,0 +1,5 @@ +