feat: Submitted data restructure (#533)

* Merge tools into components and resources

* Rename components to packages

* Format

* Redirect with code 302

* Fix text on submitting page

* Validate misc.json, format

* Permanent redirects

* Implement feedback for resources

* Fix lint

* Improve updateNpm.js types

* Fix repo links
This commit is contained in:
Lachlan Collins
2023-12-21 08:58:42 +11:00
committed by GitHub
parent 820d2f937b
commit f0442d55e8
28 changed files with 493 additions and 528 deletions

View File

@@ -1,6 +1,6 @@
# Svelte Society Website # Svelte Society Website
Welcome to Svelte Society! This repository hosts the main website, which serves as a central index of events, a components directory, as well as recipes and other useful resources. Welcome to Svelte Society! This repository hosts the main website, which serves as a central index of events, a packages directory, as well as recipes and other useful resources.
## Developing ## Developing

View File

@@ -1,8 +1,7 @@
import { writeFileSync } from 'node:fs'; import { writeFileSync } from 'node:fs';
import { componentsSchema, templatesSchema, toolsSchema } from '../src/lib/schemas.js'; import { packagesSchema, templatesSchema } from '../src/lib/schemas.js';
import components from '../src/routes/components/components.json' assert { type: 'json' }; import packages from '../src/routes/packages/packages.json' assert { type: 'json' };
import templates from '../src/routes/templates/templates.json' assert { type: 'json' }; import templates from '../src/routes/templates/templates.json' assert { type: 'json' };
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
import { chunk } from './chunk.js'; import { chunk } from './chunk.js';
const ghGraphQlUrl = 'https://api.github.com/graphql'; const ghGraphQlUrl = 'https://api.github.com/graphql';
@@ -35,9 +34,8 @@ async function doGraphQlQuery(url, query) {
function getAllGHRepos() { function getAllGHRepos() {
const repos = [ const repos = [
...componentsSchema.parse(components).map((component) => component.repository), ...packagesSchema.parse(packages).map((i) => i.repository),
...templatesSchema.parse(templates).map((template) => template.repository), ...templatesSchema.parse(templates).map((i) => i.repository)
...toolsSchema.parse(tools).map((tool) => tool.repository)
]; ];
return repos.filter((url) => url && githubNameRegexp.test(url)); return repos.filter((url) => url && githubNameRegexp.test(url));
} }

View File

@@ -1,8 +1,7 @@
import { writeFileSync } from 'node:fs'; import { writeFileSync } from 'node:fs';
import { componentsSchema, templatesSchema, toolsSchema } from '../src/lib/schemas.js'; import { packagesSchema, templatesSchema } from '../src/lib/schemas.js';
import components from '../src/routes/components/components.json' assert { type: 'json' }; import packages from '../src/routes/packages/packages.json' assert { type: 'json' };
import templates from '../src/routes/templates/templates.json' assert { type: 'json' }; import templates from '../src/routes/templates/templates.json' assert { type: 'json' };
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
import { chunk } from './chunk.js'; import { chunk } from './chunk.js';
const gitlabGraphQlUrl = 'https://gitlab.com/api/graphql'; const gitlabGraphQlUrl = 'https://gitlab.com/api/graphql';
@@ -32,9 +31,8 @@ async function doGraphQlQuery(url, query) {
function getAllGitlabRepos() { function getAllGitlabRepos() {
const repos = [ const repos = [
...componentsSchema.parse(components).map((component) => component.repository), ...packagesSchema.parse(packages).map((i) => i.repository),
...templatesSchema.parse(templates).map((template) => template.repository), ...templatesSchema.parse(templates).map((i) => i.repository)
...toolsSchema.parse(tools).map((tool) => tool.repository)
]; ];
return repos.filter((url) => url && gitlabNameRegExp.test(url)); return repos.filter((url) => url && gitlabNameRegExp.test(url));
} }

View File

@@ -3,13 +3,12 @@
import { writeFileSync } from 'node:fs'; import { writeFileSync } from 'node:fs';
import { promisify } from 'node:util'; import { promisify } from 'node:util';
import { exec } from 'node:child_process'; import { exec } from 'node:child_process';
import { componentsSchema, toolsSchema } from '../src/lib/schemas.js'; import { packagesSchema } from '../src/lib/schemas.js';
import components from '../src/routes/components/components.json' assert { type: 'json' }; import packages from '../src/routes/packages/packages.json' assert { type: 'json' };
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
const execAsync = promisify(exec); const execAsync = promisify(exec);
const data = [...componentsSchema.parse(components), ...toolsSchema.parse(tools)]; const data = packagesSchema.parse(packages);
const npm = await Promise.all( const npm = await Promise.all(
data.map((pkg) => processPackage(pkg).catch((error) => console.log(error.message))) data.map((pkg) => processPackage(pkg).catch((error) => console.log(error.message)))
@@ -19,11 +18,8 @@ const npm = await Promise.all(
writeFileSync('src/lib/data/npm.json', JSON.stringify(npm)); writeFileSync('src/lib/data/npm.json', JSON.stringify(npm));
/** @param {ReturnType<typeof data>[0]} pkg */ /** @param {import('zod').infer<typeof packagesSchema>[0]} pkg */
async function processPackage(pkg) { async function processPackage(pkg) {
if (!pkg.npm) {
throw new Error(`npm field missing from ${pkg.title} (skipping)`);
}
const { stdout } = await execAsync(`npm view ${pkg.npm} --json`); const { stdout } = await execAsync(`npm view ${pkg.npm} --json`);
const data = JSON.parse(stdout.toString()); const data = JSON.parse(stdout.toString());
const version = data.version; const version = data.version;

View File

@@ -4,17 +4,16 @@
import { writeFileSync } from 'node:fs'; import { writeFileSync } from 'node:fs';
import { inflate } from 'pako'; import { inflate } from 'pako';
import getNpmTarballUrl from 'get-npm-tarball-url'; import getNpmTarballUrl from 'get-npm-tarball-url';
import { componentsSchema, toolsSchema } from '../src/lib/schemas.js'; import { packagesSchema } from '../src/lib/schemas.js';
import components from '../src/routes/components/components.json' assert { type: 'json' }; import packages from '../src/routes/packages/packages.json' assert { type: 'json' };
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
import npm from '../src/lib/data/npm.json' assert { type: 'json' }; import npm from '../src/lib/data/npm.json' assert { type: 'json' };
import { publint } from 'publint'; import { publint } from 'publint';
import { untar } from './untar.js'; import { untar } from './untar.js';
import { createTarballVfs } from './tarball.js'; import { createTarballVfs } from './tarball.js';
const dataWithoutVersions = [...componentsSchema.parse(components), ...toolsSchema.parse(tools)]; const dataWithoutVersions = packagesSchema.parse(packages);
/** @param input {import('zod').infer<typeof toolsSchema>} */ /** @param {import('zod').infer<typeof packagesSchema>} input */
const injectVersions = (input) => { const injectVersions = (input) => {
const output = []; const output = [];
for (const item of input) { for (const item of input) {
@@ -37,7 +36,7 @@ const output = await Promise.all(
writeFileSync('src/lib/data/publint.json', JSON.stringify(output)); writeFileSync('src/lib/data/publint.json', JSON.stringify(output));
/** @param pkg {ReturnType<typeof injectVersions>[0]} */ /** @param {ReturnType<typeof injectVersions>[0]} pkg */
async function processPackage(pkg) { async function processPackage(pkg) {
const tarballUrl = getNpmTarballUrl(pkg.npm, pkg.version); const tarballUrl = getNpmTarballUrl(pkg.npm, pkg.version);
let resultBuffer; let resultBuffer;

View File

@@ -1,15 +1,11 @@
// @ts-check // @ts-check
import { componentsSchema, templatesSchema, toolsSchema } from '../src/lib/schemas.js'; import { packagesSchema, templatesSchema } from '../src/lib/schemas.js';
import components from '../src/routes/components/components.json' assert { type: 'json' }; import packages from '../src/routes/packages/packages.json' assert { type: 'json' };
import templates from '../src/routes/templates/templates.json' assert { type: 'json' }; import templates from '../src/routes/templates/templates.json' assert { type: 'json' };
import tools from '../src/routes/tools/tools.json' assert { type: 'json' };
componentsSchema.parse(components); packagesSchema.parse(packages);
console.log('Validated components.json'); console.log('Validated packages.json');
templatesSchema.parse(templates); templatesSchema.parse(templates);
console.log('Validated templates.json'); console.log('Validated templates.json');
toolsSchema.parse(tools);
console.log('Validated tools.json');

View File

@@ -3,14 +3,13 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
const linksLeft = [ const linksLeft = [
['/templates', 'templates'], ['/packages', 'packages'],
['/components', 'components'], ['/templates', 'templates']
['/tools', 'tools']
]; ];
const linksRight = [ const linksRight = [
['/resources', 'resources'],
['/recipes', 'recipes'], ['/recipes', 'recipes'],
['/events', 'events'], ['/events', 'events']
['/resources', 'resources']
]; ];
</script> </script>

View File

@@ -1,18 +1,9 @@
import components from '../routes/components/components.json'; import packages from '../routes/packages/packages.json';
import tools from '../routes/tools/tools.json';
import templates from '../routes/templates/templates.json'; import templates from '../routes/templates/templates.json';
import { cheatSheet } from '../routes/cheatsheet/cheat-sheet'; import { cheatSheet } from '../routes/cheatsheet/cheat-sheet';
export type SearchItem = { export type SearchItem = {
type: type: 'Package' | 'Template' | 'Recipe Category' | 'Recipe' | 'CheatSheet' | 'Event' | 'Link';
| 'Component'
| 'Tool'
| 'Template'
| 'Recipe Category'
| 'Recipe'
| 'CheatSheet'
| 'Event'
| 'Link';
url: string; url: string;
tags: Array<string>; tags: Array<string>;
title: string; title: string;
@@ -264,20 +255,12 @@ const allItems: Array<SearchItem> = [
url: 'https://www.svelteradio.com/' url: 'https://www.svelteradio.com/'
}, },
{ {
title: 'Tools', title: 'Packages',
tags: ['tools'], tags: ['Packages'],
type: 'Link', type: 'Link',
description: 'SvelteSociety Tools page', description: 'SvelteSociety Packages page',
search: 'tools', search: 'packages',
url: '/tools' url: '/packages'
},
{
title: 'Components',
tags: ['components'],
type: 'Link',
description: 'SvelteSociety Components page',
search: 'components',
url: '/components'
}, },
{ {
title: 'Templates', title: 'Templates',
@@ -319,21 +302,13 @@ const allItems: Array<SearchItem> = [
search: 'cheat sheet cheatsheet', search: 'cheat sheet cheatsheet',
url: '/cheatsheet' url: '/cheatsheet'
}, },
...(components as Array<JsonItem>).map<SearchItem>((item) => ({ ...(packages as Array<JsonItem>).map<SearchItem>((item) => ({
title: item.title, title: item.title,
description: item.description, description: item.description,
tags: item.tags, tags: item.tags,
type: 'Component', type: 'Package',
search: searchKeywords(item.title, item.description, ...(item.tags ?? []), item.npm ?? ''), search: searchKeywords(item.title, item.description, ...(item.tags ?? []), item.npm ?? ''),
url: '/components#component-' + item.title url: '/packages#component-' + item.title
})),
...(tools as Array<JsonItem>).map<SearchItem>((item) => ({
title: item.title,
description: item.description,
tags: item.tags,
type: 'Tool',
search: searchKeywords(item.title, item.description, ...(item.tags ?? []), item.npm ?? ''),
url: '/tools#component-' + item.title
})), })),
...(templates as Array<JsonItem>).map<SearchItem>((item) => ({ ...(templates as Array<JsonItem>).map<SearchItem>((item) => ({
title: item.title, title: item.title,

View File

@@ -1,7 +1,7 @@
import { z } from 'zod'; import { z } from 'zod';
import { packageNameRegex } from 'package-name-regex'; import { packageNameRegex } from 'package-name-regex';
export const componentsSchema = z.array( export const packagesSchema = z.array(
z.object({ z.object({
title: z.string(), title: z.string(),
npm: z.string().regex(packageNameRegex), npm: z.string().regex(packageNameRegex),
@@ -9,22 +9,26 @@ export const componentsSchema = z.array(
repository: z.string().url(), repository: z.string().url(),
description: z.string(), description: z.string(),
category: z.enum([ category: z.enum([
'Display Components', 'Bundler Plugins',
'Developer Experience',
'Internationalization',
'CSS and Layout', 'CSS and Layout',
'Icons',
'Multimedia',
'Testing',
'Data Visualisation', 'Data Visualisation',
'Integration', 'Debugging',
'Design Pattern', 'Design Pattern',
'Stores',
'Routers',
'SvelteKit Adapters',
'Design System', 'Design System',
'User Interaction', 'Developer Experience',
'Forms & User Input' 'Display Components',
'Forms & User Input',
'Icons',
'Integration',
'Internationalization',
'Linting and Formatting',
'Multimedia',
'Preprocessors',
'Routers',
'Stores',
'SvelteKit Adapters',
'Testing',
'User Interaction'
]), ]),
tags: z.array(z.string()).optional() tags: z.array(z.string()).optional()
}) })
@@ -40,21 +44,3 @@ export const templatesSchema = z.array(
tags: z.array(z.string()).optional() tags: z.array(z.string()).optional()
}) })
); );
export const toolsSchema = z.array(
z.object({
title: z.string(),
npm: z.string().regex(packageNameRegex).optional(),
url: z.string().url().optional(),
repository: z.string().url(),
description: z.string(),
category: z.enum([
'Debugging',
'Linting and Formatting',
'Editor Extensions',
'Bundler Plugins',
'Preprocessors'
]),
tags: z.array(z.string()).optional()
})
);

View File

@@ -3,9 +3,9 @@ import gitlab from '$lib/data/gitlab.json';
import npm from '$lib/data/npm.json'; import npm from '$lib/data/npm.json';
import publint from '$lib/data/publint.json'; import publint from '$lib/data/publint.json';
import type { z } from 'zod'; import type { z } from 'zod';
import type { componentsSchema } from '$lib/schemas'; import type { packagesSchema } from '$lib/schemas';
export const injectData = (input: z.infer<typeof componentsSchema>) => { export const injectData = (input: z.infer<typeof packagesSchema>) => {
const output = []; const output = [];
for (const item of input) { for (const item of input) {
// Github // Github

View File

@@ -15,7 +15,7 @@
We are a volunteer global network of Svelte fans that strive to promote Svelte and its We are a volunteer global network of Svelte fans that strive to promote Svelte and its
ecosystem. As a service to the community, this site is a central index of <a href="/events" ecosystem. As a service to the community, this site is a central index of <a href="/events"
>events</a >events</a
>, a <a href="/components">components directory</a>, as well as <a href="/recipes">recipes</a> >, a <a href="/packages">packages directory</a>, as well as <a href="/recipes">recipes</a>
and other useful resources. Join us or help us out! and other useful resources. Join us or help us out!
</p> </p>
<p> <p>

View File

@@ -0,0 +1,5 @@
import { redirect } from '@sveltejs/kit';
export const load = async () => {
redirect(308, '/packages');
};

View File

@@ -1,12 +0,0 @@
<script lang="ts">
import components from './components.json';
import SearchableJson from '$lib/SearchableJson.svelte';
import { injectData } from '$utils/injectData';
</script>
<SearchableJson
data={injectData(components)}
displayTitle="Components"
displayTitleSingular="component"
submittingType="component"
/>

View File

@@ -19,11 +19,11 @@ tr:nth-of-type(2n) {
} }
</style> </style>
# How to submit a new component? # How to submit a new package?
To add a new component on the website, the process is rather simple. To add a new package on the website, the process is rather simple.
You have to add your component in [components.json](https://github.com/svelte-society/sveltesociety.dev/blob/master/src/routes/components/components.json) You have to add your package in [packages.json](https://github.com/svelte-society/sveltesociety.dev/blob/main/src/routes/packages/packages.json)
## Forking the project ## Forking the project
@@ -31,7 +31,7 @@ You can fork the [GitHub project](https://github.com/svelte-society/sveltesociet
## Edit the file ## Edit the file
You can edit and propose your changes [directly in GitHub](https://github.com/svelte-society/sveltesociety.dev/edit/master/src/pages/components/components.json) You can edit and propose your changes [directly in GitHub](https://github.com/svelte-society/sveltesociety.dev/edit/main/src/routes/packages/packages.json)
# What information should I give ? # What information should I give ?

View File

@@ -1,31 +1,26 @@
<script lang="ts"> <script lang="ts">
import SvelteSelect from 'svelte-select'; import SvelteSelect from 'svelte-select';
import components from '../../components/components.json'; import packages from '../../packages/packages.json';
import templates from '../../templates/templates.json'; import templates from '../../templates/templates.json';
import tools from '../../tools/tools.json';
import { onMount, tick } from 'svelte'; import { onMount, tick } from 'svelte';
import { copyToClipboard } from '$lib/utils/clipboard'; import { copyToClipboard } from '$lib/utils/clipboard';
import { extractUnique } from '$lib/utils/extractUnique'; import { extractUnique } from '$lib/utils/extractUnique';
import Seo from '$lib/components/Seo.svelte'; import Seo from '$lib/components/Seo.svelte';
const repoURL = 'https://github.com/svelte-society/sveltesociety.dev'; const repoURL = 'https://github.com/svelte-society/sveltesociety.dev';
const types = ['Component', 'Template', 'Tool'].map((t) => ({ const types = ['Package', 'Template'].map((t) => ({
label: t, label: t,
value: t.toLowerCase() value: t.toLowerCase()
})); }));
const data = { const data = {
component: { package: {
tags: extractUnique(components, 'tags'), tags: extractUnique(packages, 'tags'),
categories: [...extractUnique(components, 'category').filter((cat) => cat.label !== '')] categories: [...extractUnique(packages, 'category').filter((cat) => cat.label !== '')]
}, },
template: { template: {
tags: extractUnique(templates, 'tags'), tags: extractUnique(templates, 'tags'),
categories: extractUnique(templates, 'category') categories: extractUnique(templates, 'category')
},
tool: {
tags: extractUnique(tools, 'tags'),
categories: extractUnique(tools, 'category')
} }
}; };
@@ -70,19 +65,16 @@
} }
</script> </script>
<Seo title="Submit component" /> <Seo title="Submit package" />
<h1>Submitting a new component</h1> <h1>Submitting a new package</h1>
<p> <p>
To add a new component on the website, the process is rather simple. You have to add a snippet in To add a new package on the website, the process is rather simple. You have to add a snippet in
the appropriate file. the appropriate file.
</p> </p>
<br />
<h2>Generating file contents snippet</h2> <p>Each package is represented by a JSON Object. Use the generator below to generate the Object.</p>
<p> <br />
Each component is represented by a JSON Object. Use the generator below to generate the Object.
</p>
<p><code>*</code> marked fields are required</p> <p><code>*</code> marked fields are required</p>
<div class="json-generator"> <div class="json-generator">
<div class="input-wrapper"> <div class="input-wrapper">
@@ -103,7 +95,7 @@
<label for="title" class="required">Title:</label> <label for="title" class="required">Title:</label>
<div> <div>
<input id="title" type="text" required bind:value={title} /> <input id="title" type="text" required bind:value={title} />
<span class="input-helper">Name of the component</span> <span class="input-helper">Name of the package</span>
</div> </div>
</div> </div>
<div class="input-wrapper"> <div class="input-wrapper">
@@ -126,14 +118,14 @@
<label for="desc">Description:</label> <label for="desc">Description:</label>
<div> <div>
<input id="desc" type="text" bind:value={description} /> <input id="desc" type="text" bind:value={description} />
<span class="input-helper">A short description of the component</span> <span class="input-helper">A short description of the package</span>
</div> </div>
</div> </div>
<div class="input-wrapper"> <div class="input-wrapper">
<label for="npm">NPM:</label> <label for="npm">NPM:</label>
<div> <div>
<input id="npm" type="text" bind:value={npm} /> <input id="npm" type="text" bind:value={npm} />
<span class="input-helper">The npm name of the component</span> <span class="input-helper">The npm name of the package</span>
</div> </div>
</div> </div>
<div class="input-wrapper"> <div class="input-wrapper">
@@ -146,7 +138,7 @@
showIndicator showIndicator
bind:value={category} bind:value={category}
/> />
<span class="input-helper">The category of the component</span> <span class="input-helper">The category of the package</span>
</div> </div>
</div> </div>
<div class="input-wrapper"> <div class="input-wrapper">
@@ -166,7 +158,7 @@
</pre> </pre>
<br /> <br />
Copy this snippet and add it to Copy this snippet and add it to
<a href="{repoURL}/blob/main/src/routes/{pathName}/{pathName}.json">{pathName}.json</a>. Before <a href="{repoURL}/edit/main/src/routes/{pathName}/{pathName}.json">{pathName}.json</a>. Before
submitting a PR, please clone your changes locally and run: submitting a PR, please clone your changes locally and run:
<pre>pnpm run lint</pre> <pre>pnpm run lint</pre>

View File

@@ -1,12 +1,12 @@
<script lang="ts"> <script lang="ts">
import tools from '../tools/tools.json'; import packages from './packages.json';
import SearchableJson from '$lib/SearchableJson.svelte'; import SearchableJson from '$lib/SearchableJson.svelte';
import { injectData } from '$utils/injectData'; import { injectData } from '$utils/injectData';
</script> </script>
<SearchableJson <SearchableJson
data={injectData(tools)} data={injectData(packages)}
displayTitle="Tools" displayTitle="Packages"
displayTitleSingular="tool" displayTitleSingular="package"
submittingType="tool" submittingType="package"
/> />

View File

@@ -2930,5 +2930,215 @@
"npm": "@ethercorps/sveltekit-og", "npm": "@ethercorps/sveltekit-og",
"category": "Integration", "category": "Integration",
"tags": [] "tags": []
},
{
"title": "rollup-plugin-svelte",
"npm": "rollup-plugin-svelte",
"category": "Bundler Plugins",
"description": "Compile Svelte components with Rollup",
"repository": "https://github.com/sveltejs/rollup-plugin-svelte",
"tags": ["official"]
},
{
"title": "svelte-loader",
"npm": "svelte-loader",
"category": "Bundler Plugins",
"description": "Webpack loader for svelte components",
"repository": "https://github.com/sveltejs/svelte-loader",
"tags": ["official"]
},
{
"title": "vite-plugin-svelte",
"npm": "@sveltejs/vite-plugin-svelte",
"category": "Bundler Plugins",
"description": "This is the official svelte plugin for vite",
"repository": "https://github.com/sveltejs/vite-plugin-svelte",
"tags": ["official"]
},
{
"title": "esbuild-svelte",
"npm": "esbuild-svelte",
"category": "Bundler Plugins",
"description": "An esbuild plugin to compile Svelte components",
"repository": "https://github.com/EMH333/esbuild-svelte",
"tags": []
},
{
"title": "rollup-plugin-svelte-hot",
"npm": "rollup-plugin-svelte-hot",
"category": "Bundler Plugins",
"description": "Fork of official rollup-plugin-svelte with added HMR support (for both Nollup or Rollup)",
"repository": "https://github.com/rixo/rollup-plugin-svelte-hot",
"tags": []
},
{
"title": "parcel-transformer-svelte3-plus",
"npm": "parcel-transformer-svelte3-plus",
"category": "Bundler Plugins",
"description": "Transformer plugin for Parcel v2; works with Svelte 3 & Svelte 4",
"repository": "https://github.com/HellButcher/parcel-transformer-svelte3-plus",
"tags": []
},
{
"title": "parcel-plugin-svelte",
"npm": "parcel-plugin-svelte",
"category": "Bundler Plugins",
"description": "A Parcel v1 plugin that enables Svelte support",
"repository": "https://github.com/DeMoorJasper/parcel-plugin-svelte",
"tags": []
},
{
"title": "sveltify",
"npm": "sveltify",
"category": "Bundler Plugins",
"description": "Browserify transform for Svelte",
"repository": "https://github.com/tehshrike/sveltify",
"tags": []
},
{
"title": "gulp-svelte",
"npm": "gulp-svelte",
"category": "Bundler Plugins",
"description": "A gulp 4 plugin to compile Svelte template to vanilla JavaScript",
"repository": "https://github.com/shinnn/gulp-svelte",
"tags": []
},
{
"title": "sveltejs-brunch",
"npm": "sveltejs-brunch",
"category": "Bundler Plugins",
"description": "Compile Svelte components inside Brunch projects",
"repository": "https://github.com/StarpTech/sveltejs-brunch",
"tags": []
},
{
"title": "svelte-preprocess",
"npm": "svelte-preprocess",
"category": "Preprocessors",
"description": "A ✨ magical ✨ Svelte preprocessor with sensible defaults and support for: PostCSS, SCSS, Less, Stylus, Coffeescript, TypeScript, Pug and much more",
"repository": "https://github.com/sveltejs/svelte-preprocess",
"tags": ["official"]
},
{
"category": "Preprocessors",
"description": "Write Svelte components in markdown syntax",
"npm": "svelte-preprocess-markdown",
"title": "svelte-preprocess-markdown",
"repository": "https://github.com/AlexxNB/svelte-preprocess-markdown"
},
{
"category": "Preprocessors",
"description": "A markdown preprocessor for Svelte",
"npm": "mdsvex",
"title": "mdsvex",
"repository": "https://github.com/pngwn/MDsveX"
},
{
"title": "svelte-preprocess-less",
"npm": "svelte-preprocess-less",
"category": "Preprocessors",
"description": "Svelte preprocessor for less",
"repository": "https://github.com/ls-age/svelte-preprocess-less",
"tags": []
},
{
"title": "svelte-switch-case",
"repository": "https://github.com/l-portet/svelte-switch-case",
"description": "Switch case syntax for Svelte",
"npm": "svelte-switch-case",
"category": "Preprocessors"
},
{
"title": "modular-css",
"npm": "@modular-css/svelte",
"category": "Preprocessors",
"description": "Svelte preprocessor support for modular-css",
"repository": "https://github.com/tivac/modular-css/tree/main/packages/svelte",
"tags": []
},
{
"title": "svelte-preprocess-sass",
"npm": "svelte-preprocess-sass",
"category": "Preprocessors",
"description": "Svelte preprocessor for sass",
"repository": "https://github.com/ls-age/svelte-preprocess-sass",
"tags": []
},
{
"title": "svelte-preprocess-css-hash",
"npm": "svelte-preprocess-css-hash",
"category": "Preprocessors",
"description": "Passing hashed css class name to child component. It is used to avoid class name conflicts.",
"repository": "https://github.com/jiangfengming/svelte-preprocess-css-hash",
"tags": []
},
{
"title": "svelte-preprocess-html-asset",
"npm": "svelte-preprocess-html-asset",
"category": "Preprocessors",
"description": "Transform html asset relative path. Works with snowpack & webpack 5.",
"repository": "https://github.com/jiangfengming/svelte-preprocess-html-asset",
"tags": []
},
{
"title": "svelte-preprocessor-fetch",
"npm": "svelte-preprocessor-fetch",
"category": "Preprocessors",
"description": "A preprocessor for Svelte can be used to fetch data before the component is compiled.",
"repository": "https://github.com/kevmodrome/svelte-preprocessor-fetch",
"tags": []
},
{
"title": "prettier-plugin-svelte",
"npm": "prettier-plugin-svelte",
"category": "Linting and Formatting",
"description": "Format your svelte components using prettier.",
"repository": "https://github.com/sveltejs/prettier-plugin-svelte",
"tags": ["official"]
},
{
"title": "svelte-check",
"npm": "svelte-check",
"category": "Linting and Formatting",
"description": "Detects unused css. Adds Svelte A11y hints. Provides JavaScript/TypeScript diagnostics.",
"repository": "https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check",
"tags": ["official"]
},
{
"title": "svelte-reactive-css-preprocess",
"repository": "https://github.com/srmullen/svelte-reactive-css-preprocess",
"description": "Automatically update css on component state changes.",
"npm": "svelte-reactive-css-preprocess",
"category": "Preprocessors",
"tags": []
},
{
"title": "svelte-subcomponent-preprocessor",
"repository": "https://github.com/srmullen/svelte-subcomponent-preprocessor",
"description": "Write more than one component per svelte file",
"npm": "svelte-subcomponent-preprocessor",
"category": "Preprocessors"
},
{
"title": "eslint-plugin-svelte",
"repository": "https://github.com/sveltejs/eslint-plugin-svelte",
"description": "ESLint plugin that applies own rules to Svelte",
"npm": "eslint-plugin-svelte",
"category": "Linting and Formatting",
"tags": ["official"]
},
{
"title": "full-client-server-sveltekit",
"repository": "https://github.com/SBHattarj/full-client-server-sveltekit",
"description": "A plugin allowing usage of server directly on browser using web socket",
"npm": "full-client-server-sveltekit",
"category": "Bundler Plugins"
},
{
"title": "svelte-preprocess-delegate-events",
"repository": "https://github.com/baseballyama/svelte-preprocess-delegate-events",
"description": "Delegate events with on:* 🎉",
"npm": "svelte-preprocess-delegate-events",
"category": "Preprocessors"
} }
] ]

View File

@@ -1,38 +1,10 @@
<script lang="ts"> <script lang="ts">
const booksFromPublisher = [ import booksFromPublisher from './booksFromPublisher.json';
{ import booksSelfPublished from './booksSelfPublished.json';
name: 'Svelte 3 Up and Running', import extensions from './extensions.json';
link: 'https://www.amazon.com/dp/B08D6T6BKS/', import misc from './misc.json';
author: 'Alessandro Segala' import videoCourses from './videoCourses.json';
}, import youtube from './youtube.json';
{
name: 'Svelte and Sapper in Action',
link: 'https://www.manning.com/books/svelte-and-sapper-in-action',
author: 'R. Mark Volkmann'
},
{
name: 'SvelteKit Up and Running',
link: 'https://sveltekitbook.dev',
author: 'Dylan Hildenbrand'
},
{
name: 'Svelte with Test-Driven Development',
link: 'https://www.amazon.com/dp/1837638330',
author: 'Daniel Irvine'
}
];
const booksSelfPublished = [
{
name: 'Svelte Handbook',
link: 'https://flaviocopes.com/page/svelte-handbook/',
author: 'Flavio Copes'
},
{
name: 'Simple Svelte',
link: 'https://wfq.gumroad.com/l/simple_svelte',
author: 'Darren Wang'
}
];
</script> </script>
<div> <div>
@@ -40,15 +12,19 @@
<div>There are a few books from major publishers:</div> <div>There are a few books from major publishers:</div>
<ul> <ul>
{#each booksFromPublisher as { name, link, author }} {#each booksFromPublisher as { title, url, description }}
<li><a href={link} target="_blank">{name}</a> by {author}</li> <li>
<a href={url} target="_blank">{title}</a>{#if description}&nbsp;- {description}{/if}
</li>
{/each} {/each}
</ul> </ul>
<div>As well as a couple self-published books:</div> <div>As well as a couple self-published books:</div>
<ul> <ul>
{#each booksSelfPublished as { name, link, author }} {#each booksSelfPublished as { title, url, description }}
<li><a href={link} target="_blank">{name}</a> by {author}</li> <li>
<a href={url} target="_blank">{title}</a>{#if description}&nbsp;- {description}{/if}
</li>
{/each} {/each}
</ul> </ul>
@@ -63,34 +39,48 @@
<div>There are also a number of third-party courses:</div> <div>There are also a number of third-party courses:</div>
<ul> <ul>
<li><a href="https://egghead.io/browse/frameworks/svelte" target="_blank">Egghead</a></li> {#each videoCourses as { title, url, description }}
<li> <li>
<a href="https://www.udemy.com/courses/search/?q=sveltejs+svelte" target="_blank">Udemy</a> (Note: <a href={url} target="_blank">{title}</a>{#if description}&nbsp;- {description}{/if}
Udemy frequently has discounts over 90%) </li>
</li> {/each}
<li><a href="https://www.pluralsight.com/search?q=svelte" target="_blank">Pluralsight</a></li>
</ul> </ul>
<div>Finally, there are also YouTube channels and playlists that teach Svelte:</div> <div>Finally, there are also YouTube channels and playlists that teach Svelte:</div>
<ul> <ul>
<li> {#each youtube as { title, url, description }}
<a href="https://youtube.com/channel/UCg6SQd5jnWo5Y70rZD9SQFA" target="_blank" <li>
>Svelte Master</a <a href={url} target="_blank">{title}</a>{#if description}&nbsp;- {description}{/if}
> </li>
</li> {/each}
<li> </ul>
<a href="https://youtu.be/zojEMeQGGHs" target="_blank">Svelte Tutorial for Beginners</a> by The
Net Ninja <h2>Extensions</h2>
</li>
<ul>
{#each extensions as { title, url, description }}
<li><a href={url} target="_blank">{title}</a> - {description}</li>
{/each}
</ul> </ul>
<h2>Discovery</h2> <h2>Discovery</h2>
<ul> <ul>
<li> <li>
For a curated list of SvelteKit examples in the wild, see For a curated list of SvelteKit examples in the wild, see
<a href="https://github.com/janosh/awesome-sveltekit" target="_blank">awesome-sveltekit</a> <a href="https://github.com/janosh/awesome-sveltekit" target="_blank">awesome-sveltekit</a>
</li> </li>
</ul> </ul>
<h2>Miscellaneous</h2>
<ul>
{#each misc as { title, url, description }}
<li>
<a href={url} target="_blank">{title}</a>{#if description}&nbsp;- {description}{/if}
</li>
{/each}
</ul>
</div> </div>
<style> <style>
@@ -105,5 +95,6 @@
li { li {
list-style: circle; list-style: circle;
line-height: 150%; line-height: 150%;
margin-bottom: var(--s-1);
} }
</style> </style>

View File

@@ -0,0 +1,22 @@
[
{
"title": "Svelte 3 Up and Running",
"url": "https://www.amazon.com/dp/B08D6T6BKS/",
"description": "by Alessandro Segala"
},
{
"title": "Svelte and Sapper in Action",
"url": "https://www.manning.com/books/svelte-and-sapper-in-action",
"description": "by R. Mark Volkmann"
},
{
"title": "SvelteKit Up and Running",
"url": "https://sveltekitbook.dev",
"description": "by Dylan Hildenbrand"
},
{
"title": "Svelte with Test-Driven Development",
"url": "https://www.amazon.com/dp/1837638330",
"description": "by Daniel Irvine"
}
]

View File

@@ -0,0 +1,12 @@
[
{
"title": "Svelte Handbook",
"url": "https://flaviocopes.com/page/svelte-handbook/",
"description": "by Flavio Copes"
},
{
"title": "Simple Svelte",
"url": "https://wfq.gumroad.com/l/simple_svelte",
"description": "by Darren Wang"
}
]

View File

@@ -0,0 +1,57 @@
[
{
"title": "Svelte DevTools",
"description": "An extension that allows inspection of Svelte component hierarchy and state in the Firefox and Chrome developer tools",
"url": "https://github.com/sveltejs/svelte-devtools"
},
{
"title": "Svelte for VS Code",
"description": "Svelte language support for VS Code",
"url": "https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode"
},
{
"title": "vim-svelte",
"description": "Vim syntax highlighting and indentation for Svelte 3 components.",
"url": "https://github.com/evanleck/vim-svelte"
},
{
"title": "vim-svelte-plugin",
"description": "Vim syntax and indent plugin for .svelte files",
"url": "https://github.com/leafOfTree/vim-svelte-plugin"
},
{
"title": "coc-svelte",
"description": "Svelte support for (Neo)Vim",
"url": "https://github.com/coc-extensions/coc-svelte"
},
{
"title": "web-mode.el",
"description": "Emacs major mode including support for Svelte",
"url": "https://github.com/fxbois/web-mode"
},
{
"title": "IntelliJ (WebStorm)",
"description": "Svelte Plugin for IntelliJ (WebStorm)",
"url": "https://plugins.jetbrains.com/plugin/12375-svelte"
},
{
"title": "Svelte for Sublime Text",
"description": "Sublime Text syntax highlighting for Svelte 3 components",
"url": "https://packagecontrol.io/packages/Svelte"
},
{
"title": "SvelteNova",
"description": "Svelte language support for Nova Editor by Panic",
"url": "https://github.com/laosb/SvelteNova"
},
{
"title": "Svelte Component Extractor",
"description": "Highlight text in VS Code and extract it to a new component",
"url": "https://github.com/proverbial-ninja/vscode-svelte-component-extractor"
},
{
"title": "SvelteKit Snippets",
"description": "Svelte & SvelteKit Snippets for VS Code",
"url": "https://github.com/stordahl/sveltekit-snippets"
}
]

View File

@@ -0,0 +1,17 @@
[
{
"title": "meteor-svelte",
"url": "https://github.com/meteor-svelte/meteor-svelte",
"description": "Build cybernetically enhanced web apps with Meteor and Svelte"
},
{
"title": "svelte-preval",
"url": "https://github.com/milahu/svelte-preval",
"description": "Compile time eval for svelte components"
},
{
"title": "walk-and-graph-svelte-components",
"url": "https://github.com/j2l/walk-and-graph-svelte-components",
"description": "CLI node script to walk svelte and js files, to draw a beautiful JPG of your dependencies aka \"imports\". No external dependency, only FS (Node)."
}
]

View File

@@ -0,0 +1,20 @@
[
{
"title": "Level Up Tutorials",
"url": "https://levelup.video/library?tags=svelte",
"description": "by Scott Tolinski"
},
{
"title": "Egghead",
"url": "https://egghead.io/browse/frameworks/svelte"
},
{
"title": "Udemy",
"url": "https://www.udemy.com/courses/search/?q=sveltejs+svelte",
"description": "(Note: Udemy frequently has discounts over 90%)"
},
{
"title": "Pluralsight",
"url": "https://www.pluralsight.com/search?q=svelte"
}
]

View File

@@ -0,0 +1,19 @@
[
{
"title": "Huntabyte",
"url": "https://www.youtube.com/@Huntabyte"
},
{
"title": "Joy of Code",
"url": "https://www.youtube.com/@JoyofCodeDev"
},
{
"title": "Svelte Mastery",
"url": "https://youtube.com/channel/UCg6SQd5jnWo5Y70rZD9SQFA"
},
{
"title": "Svelte Tutorial for Beginners",
"url": "https://youtube.com/playlist?list=PL4cUxeGkcC9hlbrVO_2QFVqVPhlZmz7tO&si=HHE2i-mSt9u1_CtW",
"description": "by The Net Ninja"
}
]

View File

@@ -6,7 +6,7 @@
<SearchableJson <SearchableJson
data={injectData(templates)} data={injectData(templates)}
displayTitle="Template" displayTitle="Templates"
displayTitleSingular="template" displayTitleSingular="template"
submittingType="template" submittingType="template"
/> />

View File

@@ -733,7 +733,6 @@
"url": "https://sveltepress.site/", "url": "https://sveltepress.site/",
"repository": "https://github.com/SveltePress/sveltepress", "repository": "https://github.com/SveltePress/sveltepress",
"description": "A markdown centered site build tool with full power of sveltekit.", "description": "A markdown centered site build tool with full power of sveltekit.",
"npm": "@sveltepress/create",
"category": "SvelteKit", "category": "SvelteKit",
"tags": ["markdown", "integrations"] "tags": ["markdown", "integrations"]
}, },

View File

@@ -0,0 +1,5 @@
import { redirect } from '@sveltejs/kit';
export const load = async () => {
redirect(308, '/packages');
};

View File

@@ -1,319 +0,0 @@
[
{
"title": "rollup-plugin-svelte",
"npm": "rollup-plugin-svelte",
"category": "Bundler Plugins",
"description": "Compile Svelte components with Rollup",
"repository": "https://github.com/sveltejs/rollup-plugin-svelte",
"tags": ["official"]
},
{
"title": "svelte-loader",
"npm": "svelte-loader",
"category": "Bundler Plugins",
"description": "Webpack loader for svelte components",
"repository": "https://github.com/sveltejs/svelte-loader",
"tags": ["official"]
},
{
"title": "vite-plugin-svelte",
"npm": "@sveltejs/vite-plugin-svelte",
"category": "Bundler Plugins",
"description": "This is the official svelte plugin for vite",
"repository": "https://github.com/sveltejs/vite-plugin-svelte",
"tags": ["official"]
},
{
"title": "esbuild-svelte",
"npm": "esbuild-svelte",
"category": "Bundler Plugins",
"description": "An esbuild plugin to compile Svelte components",
"repository": "https://github.com/EMH333/esbuild-svelte",
"tags": []
},
{
"title": "rollup-plugin-svelte-hot",
"npm": "rollup-plugin-svelte-hot",
"category": "Bundler Plugins",
"description": "Fork of official rollup-plugin-svelte with added HMR support (for both Nollup or Rollup)",
"repository": "https://github.com/rixo/rollup-plugin-svelte-hot",
"tags": []
},
{
"title": "parcel-transformer-svelte3-plus",
"npm": "parcel-transformer-svelte3-plus",
"category": "Bundler Plugins",
"description": "Transformer plugin for Parcel v2; works with Svelte 3 & Svelte 4",
"repository": "https://github.com/HellButcher/parcel-transformer-svelte3-plus",
"tags": []
},
{
"title": "parcel-plugin-svelte",
"npm": "parcel-plugin-svelte",
"category": "Bundler Plugins",
"description": "A Parcel v1 plugin that enables Svelte support",
"repository": "https://github.com/DeMoorJasper/parcel-plugin-svelte",
"tags": []
},
{
"title": "sveltify",
"npm": "sveltify",
"category": "Bundler Plugins",
"description": "Browserify transform for Svelte",
"repository": "https://github.com/tehshrike/sveltify",
"tags": []
},
{
"title": "gulp-svelte",
"npm": "gulp-svelte",
"category": "Bundler Plugins",
"description": "A gulp 4 plugin to compile Svelte template to vanilla JavaScript",
"repository": "https://github.com/shinnn/gulp-svelte",
"tags": []
},
{
"title": "meteor-svelte",
"category": "Bundler Plugins",
"description": "Build cybernetically enhanced web apps with Meteor and Svelte",
"repository": "https://github.com/meteor-svelte/meteor-svelte",
"tags": []
},
{
"title": "sveltejs-brunch",
"npm": "sveltejs-brunch",
"category": "Bundler Plugins",
"description": "Compile Svelte components inside Brunch projects",
"repository": "https://github.com/StarpTech/sveltejs-brunch",
"tags": []
},
{
"title": "rules_svelte",
"category": "Bundler Plugins",
"description": "Experimental rules for building Svelte components with Bazel",
"repository": "https://github.com/thelgevold/rules_svelte",
"tags": []
},
{
"title": "svelte-devtools",
"category": "Debugging",
"description": "An extension that allows inspection of Svelte component hierarchy and state in the Firefox and Chrome developer tools",
"repository": "https://github.com/sveltejs/svelte-devtools",
"tags": ["official"]
},
{
"title": "svelte-preprocess",
"npm": "svelte-preprocess",
"category": "Preprocessors",
"description": "A ✨ magical ✨ Svelte preprocessor with sensible defaults and support for: PostCSS, SCSS, Less, Stylus, Coffeescript, TypeScript, Pug and much more",
"repository": "https://github.com/sveltejs/svelte-preprocess",
"tags": ["official"]
},
{
"description": "compile time eval for svelte components",
"category": "Preprocessors",
"title": "svelte-preval",
"repository": "https://github.com/milahu/svelte-preval"
},
{
"category": "Preprocessors",
"description": "Write Svelte components in markdown syntax",
"npm": "svelte-preprocess-markdown",
"title": "svelte-preprocess-markdown",
"repository": "https://github.com/AlexxNB/svelte-preprocess-markdown"
},
{
"category": "Preprocessors",
"description": "A markdown preprocessor for Svelte",
"npm": "mdsvex",
"title": "mdsvex",
"repository": "https://github.com/pngwn/MDsveX"
},
{
"title": "svelte-preprocess-less",
"npm": "svelte-preprocess-less",
"category": "Preprocessors",
"description": "Svelte preprocessor for less",
"repository": "https://github.com/ls-age/svelte-preprocess-less",
"tags": []
},
{
"title": "svelte-switch-case",
"repository": "https://github.com/l-portet/svelte-switch-case",
"description": "Switch case syntax for Svelte",
"npm": "svelte-switch-case",
"category": "Preprocessors"
},
{
"title": "modular-css",
"npm": "@modular-css/svelte",
"category": "Preprocessors",
"description": "Svelte preprocessor support for modular-css",
"repository": "https://github.com/tivac/modular-css/tree/main/packages/svelte",
"tags": []
},
{
"title": "svelte-preprocess-sass",
"npm": "svelte-preprocess-sass",
"category": "Preprocessors",
"description": "Svelte preprocessor for sass",
"repository": "https://github.com/ls-age/svelte-preprocess-sass",
"tags": []
},
{
"title": "svelte-preprocess-css-hash",
"npm": "svelte-preprocess-css-hash",
"category": "Preprocessors",
"description": "Passing hashed css class name to child component. It is used to avoid class name conflicts.",
"repository": "https://github.com/jiangfengming/svelte-preprocess-css-hash",
"tags": []
},
{
"title": "svelte-preprocess-html-asset",
"npm": "svelte-preprocess-html-asset",
"category": "Preprocessors",
"description": "Transform html asset relative path. Works with snowpack & webpack 5.",
"repository": "https://github.com/jiangfengming/svelte-preprocess-html-asset",
"tags": []
},
{
"title": "svelte-preprocessor-fetch",
"npm": "svelte-preprocessor-fetch",
"category": "Preprocessors",
"description": "A preprocessor for Svelte can be used to fetch data before the component is compiled.",
"repository": "https://github.com/kevmodrome/svelte-preprocessor-fetch",
"tags": []
},
{
"title": "prettier-plugin-svelte",
"npm": "prettier-plugin-svelte",
"category": "Linting and Formatting",
"description": "Format your svelte components using prettier.",
"repository": "https://github.com/sveltejs/prettier-plugin-svelte",
"tags": ["official"]
},
{
"title": "svelte-check",
"npm": "svelte-check",
"category": "Linting and Formatting",
"description": "Detects unused css. Adds Svelte A11y hints. Provides JavaScript/TypeScript diagnostics.",
"repository": "https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check",
"tags": ["official"]
},
{
"title": "svelte-vscode",
"category": "Editor Extensions",
"description": "Svelte language support for VS Code",
"url": "https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode",
"tags": ["official"],
"repository": "https://github.com/sveltejs/language-tools"
},
{
"title": "vim-svelte",
"category": "Editor Extensions",
"description": "Vim syntax highlighting and indentation for Svelte 3 components.",
"repository": "https://github.com/evanleck/vim-svelte",
"tags": []
},
{
"title": "vim-svelte-plugin",
"category": "Editor Extensions",
"description": "Vim syntax and indent plugin for .svelte files",
"repository": "https://github.com/leafOfTree/vim-svelte-plugin",
"tags": []
},
{
"title": "coc-svelte",
"category": "Editor Extensions",
"description": "Svelte support for (Neo)Vim",
"repository": "https://github.com/coc-extensions/coc-svelte",
"tags": []
},
{
"title": "web-mode.el",
"category": "Editor Extensions",
"description": "Emacs major mode including support for Svelte",
"repository": "https://github.com/fxbois/web-mode",
"tags": []
},
{
"title": "IntelliJ (WebStorm)",
"category": "Editor Extensions",
"description": "Svelte Plugin for IntelliJ (WebStorm)",
"url": "https://plugins.jetbrains.com/plugin/12375-svelte",
"tags": [],
"repository": "https://github.com/tomblachut/svelte-intellij"
},
{
"title": "Sublime Text: Svelte Syntax Highlighting",
"category": "Editor Extensions",
"description": "Sublime Text syntax highlighting for Svelte 3 components",
"url": "https://packagecontrol.io/packages/Svelte",
"tags": [],
"repository": "https://github.com/corneliusio/svelte-sublime"
},
{
"title": "SvelteNova",
"category": "Editor Extensions",
"description": "Svelte language support for Nova Editor by Panic",
"repository": "https://github.com/laosb/SvelteNova",
"tags": []
},
{
"title": "Svelte Component Extractor",
"category": "Editor Extensions",
"description": "Highlight text in VS Code and extract it to a new component",
"repository": "https://github.com/proverbial-ninja/vscode-svelte-component-extractor",
"tags": []
},
{
"title": "SvelteKit Snippets",
"category": "Editor Extensions",
"description": "Svelte & SvelteKit Snippets for VS Code",
"repository": "https://github.com/stordahl/sveltekit-snippets",
"tags": []
},
{
"title": "svelte-reactive-css-preprocess",
"repository": "https://github.com/srmullen/svelte-reactive-css-preprocess",
"description": "Automatically update css on component state changes.",
"npm": "svelte-reactive-css-preprocess",
"category": "Preprocessors",
"tags": []
},
{
"title": "svelte-subcomponent-preprocessor",
"repository": "https://github.com/srmullen/svelte-subcomponent-preprocessor",
"description": "Write more than one component per svelte file",
"npm": "svelte-subcomponent-preprocessor",
"category": "Preprocessors"
},
{
"title": "walk-and-graph-svelte-components",
"repository": "https://github.com/j2l/walk-and-graph-svelte-components",
"description": "CLI node script to walk svelte and js files, to draw a beautiful JPG of your dependencies aka \"imports\". No external dependency, only FS (Node).",
"category": "Debugging",
"tags": []
},
{
"title": "eslint-plugin-svelte",
"repository": "https://github.com/sveltejs/eslint-plugin-svelte",
"description": "ESLint plugin that applies own rules to Svelte",
"npm": "eslint-plugin-svelte",
"category": "Linting and Formatting",
"tags": ["official"]
},
{
"title": "full-client-server-sveltekit",
"repository": "https://github.com/SBHattarj/full-client-server-sveltekit",
"description": "A plugin allowing usage of server directly on browser using web socket",
"npm": "full-client-server-sveltekit",
"category": "Bundler Plugins"
},
{
"title": "svelte-preprocess-delegate-events",
"repository": "https://github.com/baseballyama/svelte-preprocess-delegate-events",
"description": "Delegate events with on:* 🎉",
"npm": "svelte-preprocess-delegate-events",
"category": "Preprocessors"
}
]