start planning API reference docs

pull/2206/head
Richard Harris 7 years ago
parent 863eff9516
commit 147bf4dc2d

@ -0,0 +1,9 @@
---
title: Before we begin
---
> Temporary note: This document is a work-in-progress. Please forgive any missing or misleading parts, and don't be shy about asking for help in the [Discord chatroom](https://discord.gg/yy75DKs). The [tutorial](https://discord.gg/yy75DKs) is more complete; start there.
This page contains detailed API reference documentation. It's intended to be a resource for people who already have some familiarity with Svelte.
If that's not you (yet), you may prefer to visit the [interactive tutorial](tutorial) or the [examples](examples) before consulting this reference.

@ -0,0 +1,49 @@
---
title: Outline
---
(This isn't the actual documentation, this is just me getting my thoughts straight so that we can create the documentation.)
I think it makes sense to split the docs into compile time (`svelte.preprocess` and `svelte.compile`), then run time (component API, `svelte`, `svelte/store`, `svelte/motion`, etc). I'm not sure where template syntax, style scoping (and `:global(...)`), `context="module"` etc goes.
### Compile time
* `const preprocessed = await svelte.preprocess(source, options);`
* `const result = svelte.compile(source, options);`
### Run time
#### Client-side component API
* `const component = new Component(options);`
* `component.$set(...);`
* `component.$on(event, callback);`
* `component.$destroy();`
* `component.x` if `accessors: true`
#### Server-side component API
* `const result = Component.render(...)`
#### svelte
* lifecycle methods, tick, context
* SSR behaviour
#### svelte/store
* writable, readable, derive, get
#### svelte/motion
* spring, tweened
#### svelte/transition
#### svelte/animation (TODO make this)
#### svelte/easing

@ -1,7 +0,0 @@
---
title: Important note
---
### Read the RFCs
Much of the documentation below is out of date! For more accurate and current information on how Svelte 3 works in the meantime, check out the RFCS on [reactive assignments](https://github.com/sveltejs/rfcs/blob/master/text/0001-reactive-assignments.md), [reactive stores](https://github.com/sveltejs/rfcs/blob/master/text/0002-reactive-stores.md) and [reactive declarations](https://github.com/sveltejs/rfcs/blob/master/text/0003-reactive-declarations.md).

@ -1,112 +0,0 @@
---
title: Introduction
---
### What is Svelte?
Svelte is a tool for building fast web applications.
It is similar to JavaScript frameworks such as React and Vue, which share a goal of making it easy to build slick interactive user interfaces.
But there's a crucial difference: Svelte converts your app into ideal JavaScript at *build time*, rather than interpreting your application code at *run time*. This means you don't pay the performance cost of the framework's abstractions, and you don't incur a penalty when your app first loads.
You can build your entire app with Svelte, or you can add it incrementally to an existing codebase. You can also ship components as standalone packages that work anywhere, without the overhead of a dependency on a conventional framework.
[Read the introductory blog post](/blog/frameworks-without-the-framework) to learn more about Svelte's goals and philosophy.
### Understanding components
In Svelte, an application is composed from one or more *components*. A component is a reusable self-contained block of code that encapsulates markup, styles and behaviours that belong together, written into an `.html` file. Here's a simple example:
```html
<!--{ title: 'Hello world!' }-->
<h1>Hello {name}!</h1>
```
```json
/* { hidden: true } */
{
name: 'world'
}
```
> Wherever you see <strong style="font-weight: 700; font-size: 16px; font-family: Inconsolata, monospace; color: rgba(170,30,30, 0.8)">REPL</strong> links, click through for an interactive example
Svelte turns this into a JavaScript module that you can import into your app:
```js
/* { filename: 'main.js' } */
import App from './App.html';
const app = new App({
target: document.querySelector('main'),
props: { name: 'world' },
});
// change the component's "name" prop. We'll learn about props (aka properties) below
app.name = 'everybody';
// detach the component and clean everything up
app.$destroy();
```
Congratulations, you've just learned about half of Svelte's API!
### Getting started
Normally, this is the part where the instructions might tell you to add the framework to your page as a `<script>` tag. But because Svelte runs at build time, it works a little bit differently.
The best way to use Svelte is to integrate it into your build system  there are plugins for Rollup, Webpack and others, with more on the way. See [here](https://github.com/sveltejs/svelte/#svelte) for an up-to-date list.
> You will need to have [Node.js](https://nodejs.org/en/) installed, and have some familiarity with the command line
#### Getting started using the REPL
Going to the [REPL](/repl) and pressing the *download* button on any of the examples will give you a .zip file containing everything you need to run that example locally. Just unzip it, `cd` to the directory, and run `npm install` and `npm run dev`. See [this blog post](/blog/the-easiest-way-to-get-started) for more information.
#### Getting started using degit
[degit](https://github.com/Rich-Harris/degit) is a tool for creating projects from templates stored in git repos. Install it globally...
```bash
npm install -g degit
```
...then you can use it to spin up a new project:
```bash
degit sveltejs/template my-new-project
cd my-new-project
npm install
npm run dev
```
You can use any git repo you like — these are the 'official' templates:
* [sveltejs/template](https://github.com/sveltejs/template) — this is what you get by downloading from the REPL
* [sveltejs/template-webpack](https://github.com/sveltejs/template-webpack) — similar, but uses [webpack](https://webpack.js.org/) instead of [Rollup](https://rollupjs.org/guide/en)
#### Getting started using the CLI
Svelte also provides a Command Line Interface, but it's not recommended for production use. The CLI will compile your components to standalone JavaScript files, but won't automatically recompile them when they change, and won't deduplicate code shared between your components. Use one of the above methods instead.
If you've installed `svelte` globally, you can use `svelte --help` for a complete list of options. Some examples of the more common operations are:
```bash
# Generate a JavaScript module from MyComponent.html
svelte compile MyComponent.html > MyComponent.js
svelte compile -i MyComponent.html -o MyComponent.js
# Generate a UMD module from MyComponent.html, inferring its name from the filename ('MyComponent')
svelte compile -f umd MyComponent.html > MyComponent.js
# Generate a UMD module, specifying the name
svelte compile -f umd -n CustomName MyComponent.html > MyComponent.js
# Compile all .html files in a directory
svelte compile -i src/components -o build/components
```
> You can also use [npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) to use the CLI without installing Svelte globally — just prefix your command with `npx`: `npx svelte compile ...`

@ -1,6 +1,6 @@
<script context="module"> <script context="module">
export async function preload({ params }) { export async function preload({ params }) {
const post = await this.fetch(`api/blog/${params.slug}`).then(r => r.json()); const post = await this.fetch(`blog/${params.slug}.json`).then(r => r.json());
return { post }; return { post };
} }
</script> </script>

@ -1,6 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import path from 'path'; import path from 'path';
import { extract_frontmatter, langs } from '../../../utils/markdown.js'; import { extract_frontmatter, langs } from '../../utils/markdown.js';
import marked from 'marked'; import marked from 'marked';
import PrismJS from 'prismjs'; import PrismJS from 'prismjs';
import 'prismjs/components/prism-bash'; import 'prismjs/components/prism-bash';

@ -1,6 +1,6 @@
<script context="module"> <script context="module">
export async function preload() { export async function preload() {
const posts = await this.fetch(`api/blog`).then(r => r.json()); const posts = await this.fetch(`blog.json`).then(r => r.json());
return { posts }; return { posts };
} }
</script> </script>

@ -1,4 +1,4 @@
import get_posts from '../api/blog/_posts.js'; import get_posts from '../blog/_posts.js';
const months = ',Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(','); const months = ',Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'.split(',');

@ -72,7 +72,7 @@
</script> </script>
<style> <style>
.guide-toc li { .reference-toc li {
display: block; display: block;
line-height: 1.2; line-height: 1.2;
margin: 0 0 4.8rem 0; margin: 0 0 4.8rem 0;
@ -100,7 +100,7 @@
<ul <ul
bind:this={ul} bind:this={ul}
class="guide-toc" class="reference-toc"
on:mouseenter="{() => prevent_sidebar_scroll = true}" on:mouseenter="{() => prevent_sidebar_scroll = true}"
on:mouseleave="{() => prevent_sidebar_scroll = false}" on:mouseleave="{() => prevent_sidebar_scroll = false}"
> >

@ -35,30 +35,16 @@ const blockTypes = [
'tablecell' 'tablecell'
]; ];
// https://github.com/darkskyapp/string-hash/blob/master/index.js
function getHash(str) {
let hash = 5381;
let i = str.length;
while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
return (hash >>> 0).toString(36);
}
export const demos = new Map();
export default function() { export default function() {
return fs return fs
.readdirSync(`content/guide`) .readdirSync(`content/docs`)
.filter(file => file[0] !== '.' && path.extname(file) === '.md') .filter(file => file[0] !== '.' && path.extname(file) === '.md')
.map(file => { .map(file => {
const markdown = fs.readFileSync(`content/guide/${file}`, 'utf-8'); const markdown = fs.readFileSync(`content/docs/${file}`, 'utf-8');
const { content, metadata } = extract_frontmatter(markdown); const { content, metadata } = extract_frontmatter(markdown);
const subsections = []; const subsections = [];
const groups = [];
let group = null;
let uid = 1;
const renderer = new marked.Renderer(); const renderer = new marked.Renderer();
@ -74,15 +60,6 @@ export default function() {
let prefix = ''; let prefix = '';
let className = 'code-block'; let className = 'code-block';
if (lang === 'html' && !group) {
if (!meta || meta.repl !== false) {
prefix = `<a class='open-in-repl' href='repl?demo=@@${uid}' title='open in REPL'><svg class='icon'><use xlink:href='#maximize-2' /></svg></a>`;
}
group = { id: uid++, blocks: [] };
groups.push(group);
}
if (meta) { if (meta) {
source = lines.slice(1).join('\n'); source = lines.slice(1).join('\n');
const filename = meta.filename || (lang === 'html' && 'App.svelte'); const filename = meta.filename || (lang === 'html' && 'App.svelte');
@ -92,8 +69,6 @@ export default function() {
} }
} }
if (group) group.blocks.push({ meta: meta || {}, lang, source });
if (meta && meta.hidden) return ''; if (meta && meta.hidden) return '';
const plang = langs[lang]; const plang = langs[lang];
@ -147,7 +122,6 @@ export default function() {
blockTypes.forEach(type => { blockTypes.forEach(type => {
const fn = renderer[type]; const fn = renderer[type];
renderer[type] = function() { renderer[type] = function() {
group = null;
return fn.apply(this, arguments); return fn.apply(this, arguments);
}; };
}); });
@ -156,37 +130,6 @@ export default function() {
const hashes = {}; const hashes = {};
groups.forEach(group => {
const main = group.blocks[0];
if (main.meta.repl === false) return;
const hash = getHash(group.blocks.map(block => block.source).join(''));
hashes[group.id] = hash;
const json5 = group.blocks.find(block => block.lang === 'json');
const title = main.meta.title;
if (!title) console.error(`Missing title for demo in ${file}`);
demos.set(
hash,
JSON.stringify({
title: title || 'Example from guide',
components: group.blocks
.filter(block => block.lang === 'html' || block.lang === 'js')
.map(block => {
const [name, type] = (block.meta.filename || '').split('.');
return {
name: name || 'App',
type: type || 'html',
source: block.source,
};
}),
json5: json5 && json5.source,
})
);
});
return { return {
html: html.replace(/@@(\d+)/g, (m, id) => hashes[id] || m), html: html.replace(/@@(\d+)/g, (m, id) => hashes[id] || m),
metadata, metadata,

@ -1,22 +0,0 @@
import { demos } from '../_sections.js';
export function get(req, res) {
const { hash } = req.params;
if (!demos.has(hash)) {
res.writeHead(404, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
error: 'not found'
}));
} else {
const json = demos.get(hash);
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(json);
}
}

@ -315,24 +315,24 @@
</style> </style>
<svelte:head> <svelte:head>
<title>Learn Svelte</title> <title>API Docs • Svelte</title>
</svelte:head> </svelte:head>
<div bind:this={container} class='content linkify listify'> <div bind:this={container} class='content linkify listify'>
{#each sections as section} {#each sections as section}
<section data-id={section.slug}> <section data-id={section.slug}>
<h2> <h2>
<span class="offset-anchor" id={section.slug}></span> <span class="offset-anchor" id={section.slug}></span>
<a href="#{section.slug}" class="anchor" aria-hidden></a> <a href="#{section.slug}" class="anchor" aria-hidden></a>
{section.metadata.title} {section.metadata.title}
<small> <small>
<a href='https://github.com/sveltejs/svelte/edit/master/site/content/guide/{section.file}' title='edit this section'> <a href='https://github.com/sveltejs/svelte/edit/master/site/content/docs/{section.file}' title='edit this section'>
<Icon name='edit' /></a> <Icon name='edit' /></a>
</small> </small>
</h2> </h2>
{@html section.html} {@html section.html}
</section> </section>
{/each} {/each}
</div> </div>

@ -222,7 +222,7 @@ npm run dev & open http://localhost:5000
<p class="linkify">See the <a href="blog/the-easiest-way-to-get-started">quickstart guide</a> for more information.</p> <p class="linkify">See the <a href="blog/the-easiest-way-to-get-started">quickstart guide</a> for more information.</p>
<p><a rel="prefetch" class="cta" href="guide">Learn Svelte</a></p> <p><a rel="prefetch" class="cta" href="tutorial">Learn Svelte</a></p>
</div> </div>
</section> </section>

Loading…
Cancel
Save