-
-
Notifications
You must be signed in to change notification settings - Fork 48
feat: add no-export-load-in-svelte-module-in-kit-pages #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ota-meshi
merged 26 commits into
sveltejs:main
from
baseballyama:feature/no-export-load-in-svelte-module-in-kit-pages
Nov 1, 2022
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
bdd3580
feat: add no-export-load-in-svelte-module-in-kit-pages
baseballyama ab5e4d2
chore: add changeset
baseballyama c92a052
chore: add test
baseballyama 07dbc08
fix: check devDependencies also
baseballyama 08fc369
fix: adjust for test
baseballyama 4cf5a14
feat: add config
baseballyama f8de8bc
chore: fix typo
baseballyama 203bf8e
fix: bug
baseballyama a9fb99d
fix: bug
baseballyama 59d3097
chore: uupdate docus
baseballyama 4fc4c22
chore: update docs
baseballyama 332c4bc
chore: add kit helper
baseballyama d5bdacd
fix: fix for demo
baseballyama f321a12
chore: adjust doc style
baseballyama dc451d3
Merge branch 'main' into feature/no-export-load-in-svelte-module-in-k…
baseballyama d0d21e7
chore: revert .eslintrc.js
baseballyama 38c2690
chore: update uppercase -> lowercase
baseballyama 2eb81df
fix: update recommended
baseballyama 3137c67
fix: i did not know :exit
baseballyama 5353b32
fix: project root path finding logic
baseballyama d68a1cf
chore: utilize
baseballyama 20ad311
chore: yarn update
baseballyama 7584b10
fix: remove needless logic
baseballyama cfaf58c
chore: simplify
baseballyama a903027
fix: false positive
baseballyama 7d870c0
Merge branch 'main' into feature/no-export-load-in-svelte-module-in-k…
ota-meshi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"eslint-plugin-svelte": minor | ||
--- | ||
|
||
feat: add `no-export-load-in-svelte-module-in-kit-pages` rule |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
docs/rules/no-export-load-in-svelte-module-in-kit-pages.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
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. | ||
|
||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge> | ||
|
||
## :book: Rule Details | ||
|
||
This rule reports unexpected exported `load` function at `<script context="module">`. | ||
At SvelteKit v1.0.0-next.405, `load` function has been moved into a separate file — `+page.js` for pages, `+layout.js` for layouts. | ||
And the API has changed. | ||
|
||
<script> | ||
const config = { | ||
settings: { | ||
kit: { | ||
files: { | ||
routes: "", | ||
}, | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<ESLintCodeBlock config="{config}"> | ||
|
||
<!--eslint-skip--> | ||
|
||
```svelte | ||
<script context="module"> | ||
/* eslint svelte/no-export-load-in-svelte-module-in-kit-pages: "error" */ | ||
/* ✓ GOOD */ | ||
export function foo() {} | ||
export function bar() {} | ||
/* ✗ BAD */ | ||
export function load() {} | ||
// export const load = () => {} | ||
</script> | ||
``` | ||
|
||
</ESLintCodeBlock> | ||
|
||
## :wrench: Options | ||
|
||
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 | ||
|
||
- [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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type * as ESTree from "estree" | ||
import { createRule } from "../utils" | ||
import { isKitPageComponent } from "../utils/svelte-kit" | ||
|
||
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", | ||
// TODO Switch to recommended in the major version. | ||
recommended: false, | ||
}, | ||
schema: [], | ||
messages: { | ||
unexpected: | ||
"disallow exporting load functions in `*.svelte` module in Svelte Kit page components.", | ||
}, | ||
type: "problem", | ||
}, | ||
create(context) { | ||
if (!isKitPageComponent(context)) { | ||
return {} | ||
} | ||
let isModule = false | ||
return { | ||
// <script context="module"> | ||
[`Program > SvelteScriptElement > SvelteStartTag > SvelteAttribute[key.name="context"] > SvelteLiteral[value="module"]`]: | ||
() => { | ||
isModule = true | ||
}, | ||
|
||
// </script> | ||
"Program > SvelteScriptElement:exit": () => { | ||
isModule = false | ||
}, | ||
|
||
// export function load() {} | ||
// export const load = () => {} | ||
[`:matches(ExportNamedDeclaration > FunctionDeclaration, ExportNamedDeclaration > VariableDeclaration > VariableDeclarator) > Identifier.id[name="load"]`]: | ||
(node: ESTree.Identifier) => { | ||
if (!isModule) return {} | ||
return context.report({ | ||
node, | ||
loc: node.loc!, | ||
messageId: "unexpected", | ||
}) | ||
}, | ||
} | ||
}, | ||
}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* Simple cache manager. | ||
* | ||
* refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/cache.js | ||
*/ | ||
|
||
const SKIP_TIME = 5000 | ||
|
||
type CacheValue<T> = { | ||
expire: number | ||
value: T | ||
} | ||
|
||
/** | ||
* The cache will dispose of each value if the value has not been accessed | ||
* during 5 seconds. | ||
* @returns getter and setter ofr the cache. | ||
*/ | ||
export function createCache<T>(): { | ||
get: (key: string) => T | null | ||
set: (key: string, value: T) => void | ||
} { | ||
const map: Map<string, CacheValue<T>> = new Map() | ||
|
||
/** | ||
* Get the cached value of the given key. | ||
* @param key The key to get. | ||
* @returns The cached value or null. | ||
*/ | ||
function get(key: string): T | null { | ||
const entry = map.get(key) | ||
const now = Date.now() | ||
|
||
if (entry) { | ||
if (entry.expire > now) { | ||
entry.expire = now + SKIP_TIME | ||
return entry.value | ||
} | ||
map.delete(key) | ||
} | ||
return null | ||
} | ||
|
||
/** | ||
* Set the value of the given key. | ||
* @param key The key to set. | ||
* @param value The value to set. | ||
* @returns | ||
*/ | ||
function set(key: string, value: T): void { | ||
const entry = map.get(key) | ||
const expire = Date.now() + SKIP_TIME | ||
|
||
if (entry) { | ||
entry.value = value | ||
entry.expire = expire | ||
} else { | ||
map.set(key, { value, expire }) | ||
} | ||
} | ||
|
||
return { get, set } | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* refer: https://github.com/mysticatea/eslint-plugin-node/blob/f45c6149be7235c0f7422d1179c25726afeecd83/lib/util/get-package-json.js | ||
*/ | ||
|
||
import fs from "fs" | ||
import path from "path" | ||
import { createCache } from "./cache" | ||
|
||
type PackageJson = Record<string, any> & { filePath: string } | ||
|
||
const isRunOnBrowser = !fs.readFileSync | ||
const cache = createCache<PackageJson | null>() | ||
|
||
/** | ||
* Reads the `package.json` data in a given path. | ||
* | ||
* Don't cache the data. | ||
* | ||
* @param dir The path to a directory to read. | ||
* @returns The read `package.json` data, or null. | ||
*/ | ||
function readPackageJson(dir: string): PackageJson | null { | ||
if (isRunOnBrowser) return 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 | ||
} | ||
|
||
/** | ||
* Gets a `package.json` data. | ||
* The data is cached if found, then it's used after. | ||
* @param startPath A file path to lookup. | ||
* @returns A found `package.json` data or `null`. | ||
* This object have additional property `filePath`. | ||
*/ | ||
export function getPackageJson(startPath = "a.js"): PackageJson | null { | ||
if (isRunOnBrowser) return null | ||
const startDir = path.dirname(path.resolve(startPath)) | ||
let dir = startDir | ||
let prevDir = "" | ||
let data = null | ||
|
||
do { | ||
data = cache.get(dir) | ||
if (data) { | ||
if (dir !== startDir) { | ||
cache.set(startDir, data) | ||
} | ||
return data | ||
} | ||
|
||
data = readPackageJson(dir) | ||
if (data) { | ||
cache.set(dir, data) | ||
cache.set(startDir, data) | ||
return data | ||
} | ||
|
||
// Go to next. | ||
prevDir = dir | ||
dir = path.resolve(dir, "..") | ||
} while (dir !== prevDir) | ||
|
||
cache.set(startDir, null) | ||
return null | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I choose that I added shared configuration for kit routes path.
I think over 95% of users use default settings
src/routes
.So only a few users need to config it.
And for 5% users, we discussed that we will use
espree
but it may fail to get the path if they rely to env of some external information. So for now I didn't implement this logic.#241 (comment)