Merge branch 'master' into site/polka

pull/2478/head
Luke Edwards 5 years ago committed by GitHub
commit ae081af54c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -62,4 +62,4 @@ degit your-name/template my-new-project
And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Now](https://zeit.co/now) or [Surge](http://surge.sh/).
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) or the [API](https://github.com/sveltejs/svelte#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://discord.gg/yy75DKs), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](https://discord.gg/yy75DKs), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!

@ -66,7 +66,7 @@ But size is only part of the story. Svelte apps are also extremely performant an
The biggest drawback for many developers evaluating Sapper would be 'but I like React, and I already know how to use it', which is fair.
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](docs#template-syntax)). You get [scoped CSS](the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](docs#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
If you're in that camp, I'd invite you to at least try alternative frameworks. You might be pleasantly surprised! The [Sapper RealWorld](https://github.com/sveltejs/realworld) implementation totals 1,201 lines of source code, compared to 2,377 for the reference implementation, because you're able to express concepts very concisely using Svelte's template syntax (which [takes all of five minutes to master](https://v2.svelte.dev/guide#template-syntax)). You get [scoped CSS](blog/the-zen-of-just-writing-css), with unused style removal and minification built-in, and you can use preprocessors like LESS if you want. You no longer need to use Babel. SSR is ridiculously fast, because it's just string concatenation. And we recently introduced [svelte/store](https://v2.svelte.dev/guide#state-management), a tiny global store that synchronises state across your component hierarchy with zero boilerplate. The worst that can happen is that you'll end up feeling vindicated!
But there are trade-offs nonetheless. Some people have a pathological aversion to any form of 'template language', and maybe that applies to you. JSX proponents will clobber you with the 'it's just JavaScript' mantra, and therein lies React's greatest strength, which is that it is infinitely flexible. That flexibility comes with its own set of trade-offs, but we're not here to discuss those.
@ -81,4 +81,4 @@ I believe the next frontier of web performance is 'whole-app optimisation'. Curr
Speaking of Glimmer, the idea of compiling components to bytecode is one that we'll probably steal in 2018. A framework like Sapper could conceivably determine which compilation mode to use based on the characteristics of your app. It could even serve JavaScript for the initial route for the fastest possible startup time, then lazily serve a bytecode interpreter for subsequent routes, resulting in the optimal combination of startup size and total app size.
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Gitter](https://gitter.im/sveltejs/svelte).
Mostly, though, we want the direction of Sapper to be determined by its users. If you're the kind of developer who enjoys life on the bleeding edge and would like to help shape the future of how we build web apps, please join us on [GitHub](https://github.com/sveltejs/svelte) and [Discord](https://discord.gg/yy75DKs).

@ -12,7 +12,7 @@ Almost a year after we first started talking about version 2 on the Svelte issue
## tl;dr
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Gitter chatroom](https://gitter.im/sveltejs/svelte).
Each of these items is described in more depth below. If you get stuck, ask for help in our friendly [Discord chatroom](https://discord.gg/yy75DKs).
- Install Svelte v2 from npm
- Upgrade your templates with [svelte-upgrade](https://github.com/sveltejs/svelte-upgrade)
@ -85,7 +85,7 @@ If you need to support IE11 and friends, you will need to use a transpiler like
## New lifecycle hooks
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](docs#lifecycle-hooks) for responding to state changes:
In addition to `oncreate` and `ondestroy`, Svelte v2 adds two more [lifecycle hooks](https://v2.svelte.dev/guide#lifecycle-hooks) for responding to state changes:
```js
export default {
@ -168,7 +168,7 @@ This change might seem annoying initially, but it's the right move: among other
## event_handler.destroy
If your app has [custom event handlers](docs#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
If your app has [custom event handlers](https://v2.svelte.dev/guide#custom-event-handlers), they must return an object with a `destroy` method, *not* a `teardown` method (this aligns event handlers with the component API).
## No more type coercion
@ -201,4 +201,4 @@ Before, there was a `svelte.validate` method which checked your component was va
## My app is broken! Help!
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Gitter](https://gitter.im/sveltejs/svelte) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).
Hopefully this covers everything, and the update should be easier for you than it was for us. But if you find bugs, or discover things that aren't mentioned here, swing by [Discord chatroom](https://discord.gg/yy75DKs) or raise an issue on the [tracker](https://github.com/sveltejs/svelte/issues).

@ -1,9 +1,8 @@
---
title: Svelte 3: Rethinking Reactivity
title: Svelte 3: Rethinking reactivity
description: It's finally here
author: Rich Harris
authorURL: https://twitter.com/Rich_Harris
draft: true
---
After several months of being just days away, we are over the moon to announce the stable release of Svelte 3. This is a huge release representing hundreds of hours of work by many people in the Svelte community, including invaluable feedback from beta testers who have helped shape the design every step of the way.
@ -23,14 +22,15 @@ Version 3 is a significant overhaul. Our focus for the last five or six months h
To make that possible we first needed to rethink the concept at the heart of modern UI frameworks: reactivity.
<figure class="max">
<img
src="https://svelte-assets.surge.sh/yglf-poster.jpg"
alt="Rich Harris delivering a conference talk at You Gotta Love Frontend"
>
<div class="max">
<figure style="max-width: 960px; margin: 0 auto">
<div style="height: 0; padding: 0 0 57.1% 0; position: relative; margin: 0 auto;">
<iframe style="position: absolute; width: 100%; height: 100%; left: 0; top: 0; margin: 0;" src="https://www.youtube-nocookie.com/embed/AdNJ3fydeao" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<figcaption>TKTKTK replace this with a video embed once the YGLF videos appear on YouTube</figcaption>
<figcaption>'Rethinking Reactivity' from <a href="https://www.israel.yglfconf.com/">You Gotta Love Frontend Code Camp</a></figcaption>
</figure>
</div>
## Moving reactivity into the language

@ -360,7 +360,7 @@ on:eventname={handler}
---
Components can emit events using [createEventDispatcher](docs#createeventdispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
Components can emit events using [createEventDispatcher](docs#createEventDispatcher), or by forwarding DOM events. Listening for component events looks the same as listening for DOM events:
```html
<SomeComponent on:whatever={handler}/>
@ -1107,7 +1107,7 @@ This element makes it possible to insert elements into `document.head`. During s
---
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](docs#compile). The possible options are:
The `<svelte:options>` element provides a place to specify per-component compiler options, which are detailed in the [compiler section](docs#svelte_compile). The possible options are:
* `immutable={true}` — you never use mutable data, so the compiler can do simple referential equality checks to determine if values have changed
* `immutable={false}` — the default. Svelte will be more conservative about whether or not mutable objects have changed

@ -20,7 +20,7 @@ onMount(callback: () => () => void)
The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM. It must be called during the component's initialisation (but doesn't need to live *inside* the component; it can be called from an external module).
`onMount` does not run inside a [server-side component](docs#server-side-component-api).
`onMount` does not run inside a [server-side component](docs#Server-side_component_API).
```html
<script>
@ -375,7 +375,7 @@ Tweened stores update their values over a fixed duration. The following options
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the tween lasts
* `easing` (`function`, default `t => t`) — an [easing function](docs#svelte-easing)
* `easing` (`function`, default `t => t`) — an [easing function](docs#svelte_easing)
* `interpolator` (`function`) — see below
`store.set` and `store.update` can accept a second `options` argument that will override the options passed in upon instantiation.
@ -532,7 +532,7 @@ Existing children of `target` are left where they are.
---
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#compile).
The `hydrate` option instructs Svelte to upgrade existing DOM (usually from server-side rendering) rather than creating new elements. It will only work if the component was compiled with the [`hydratable: true` option](docs#svelte_compile).
Whereas children of `target` are normally left alone, `hydrate: true` will cause any children to be removed. For that reason, the `anchor` option cannot be used alongside `hydrate: true`.

@ -30,6 +30,6 @@ We can use curly braces *inside* attributes. Try changing it to `"{name} dancing
It's not uncommon to have an attribute where the name and value are the same, like `src={src}`. Svelte gives us a convenient shorthand for these cases:
```html
<img {src} alt="...">
<img {src} alt="A man dancing">
```

@ -28,4 +28,4 @@ const app = new App({
});
```
You can then interact with `app` using the [component API](docs/component-api) if you need to.
You can then interact with `app` using the [component API](docs#Client-side_component_API) if you need to.

@ -31,7 +31,7 @@ The complete set of bindings for `<audio>` and `<video>` is as follows — four
* `seekable` (readonly) — ditto
* `played` (readonly) — ditto
...and three *two-way* bindings:
...and four *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where `1` is 'normal'

@ -1900,28 +1900,6 @@
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
"dev": true
},
"compressible": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz",
"integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==",
"requires": {
"mime-db": ">= 1.38.0 < 2"
}
},
"compression": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
"integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
"requires": {
"accepts": "~1.3.5",
"bytes": "3.0.0",
"compressible": "~2.0.16",
"debug": "2.6.9",
"on-headers": "~1.0.2",
"safe-buffer": "5.1.2",
"vary": "~1.1.2"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -2115,9 +2093,10 @@
"dev": true
},
"dotenv": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
"integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-7.0.0.tgz",
"integrity": "sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==",
"dev": true
},
"electron-to-chromium": {
"version": "1.3.124",

@ -16,10 +16,8 @@
"dependencies": {
"@polka/send": "^1.0.0-next.2",
"codemirror": "^5.44.0",
"compression": "^1.7.3",
"devalue": "^1.1.0",
"do-not-zip": "^1.0.0",
"dotenv": "^6.2.0",
"express-session": "^1.15.6",
"golden-fleece": "^1.0.9",
"limax": "^1.7.0",
@ -43,6 +41,7 @@
"@sveltejs/svelte-repl": "0.0.10",
"chokidar": "^2.1.2",
"degit": "^2.1.3",
"dotenv": "^7.0.0",
"eslint-plugin-svelte3": "^0.4.4",
"esm": "^3.2.22",
"jimp": "^0.6.0",

@ -1,19 +1,19 @@
const sh = require('shelljs');
const fs = require('fs')
const fs = require('fs');
sh.cd(__dirname+'/../')
sh.cd(__dirname+'/../');
// fetch svelte app
sh.rm('-rf','scripts/svelte-app')
sh.exec('npx degit sveltejs/template#v3 scripts/svelte-app')
sh.rm('-rf','scripts/svelte-app');
sh.exec('npx degit sveltejs/template scripts/svelte-app');
// remove src (will be recreated client-side) and node_modules
sh.rm('-rf', 'scripts/svelte-app/src')
sh.rm('-rf', 'scripts/svelte-app/node_modules')
sh.rm('-rf', 'scripts/svelte-app/src');
sh.rm('-rf', 'scripts/svelte-app/node_modules');
// build svelte-app.json
const appPath = 'scripts/svelte-app'
let files = []
const appPath = 'scripts/svelte-app';
const files = [];
for (const path of sh.find(appPath).filter(p => fs.lstatSync(p).isFile()) ) {
files.push({ path: path.slice(appPath.length + 1), data: fs.readFileSync(path).toString() });

@ -1,8 +1,8 @@
<script>
import { onMount } from 'svelte';
import { fade } from 'svelte/transition';
let p = 0;
let visible = false;
const sleep = ms => new Promise(f => setTimeout(f, ms));
@ -10,6 +10,7 @@
let running = true;
function next() {
visible = true;
p += 0.1;
const remaining = 1 - p;
@ -50,15 +51,21 @@
background-color: rgba(255,255,255,0.3);
pointer-events: none;
z-index: 998;
animation: fade 0.4s;
}
@keyframes fade {
from { opacity: 0 }
to { opacity: 1 }
}
</style>
{#if p > 0}
<div class="progress-container" transition:fade>
{#if visible}
<div class="progress-container">
<div class="progress" style="width: {p * 100}%"></div>
</div>
{/if}
{#if p >= 0.4}
<div class="fade" in:fade={{duration:800}}></div>
<div class="fade"></div>
{/if}

@ -185,6 +185,10 @@
transition: none;
}
li:not(.active) a:hover {
color: var(--flash);
}
@media (min-width: 840px) {
ul {
padding: 0;

@ -1,33 +1,71 @@
<script>
const dev = process.env.NODE_ENV === 'development';
export let status;
export let error;
</script>
<svelte:head>
<title>{status}</title>
</svelte:head>
<h1>{status}</h1>
<p>{error.message}</p>
{#if dev && error.stack}
<pre>{error.stack}</pre>
{/if}
// we don't want to use <svelte:window bind:online> here,
// because we only care about the online state when
// the page first loads
let online = typeof navigator !== 'undefined'
? navigator.onLine
: true;
</script>
<style>
.container {
padding: var(--top-offset) var(--side-nav) 6rem var(--side-nav);
}
h1, p { margin: 0 auto }
h1 {
font-size: 2.8em;
font-weight: 700;
font-weight: 300;
margin: 0 0 0.5em 0;
}
p { margin: 1em auto }
@media (min-width: 480px) {
h1 { font-size: 4em }
.error {
background-color: #da106e;
color: white;
padding: 12px 16px;
font: 600 16px/1.7 var(--font);
border-radius: 2px;
}
</style>
/* @media (min-width: 480px) {
h1 { font-size: 4em }
} */
</style>
<svelte:head>
<title>{status}</title>
</svelte:head>
<div class="container">
{#if online}
<h1>Yikes!</h1>
{#if error.message}
<p class="error">{status}: {error.message}</p>
{:else}
<p class="error">Encountered a {status} error</p>
{/if}
{#if dev && error.stack}
<pre>{error.stack}</pre>
{:else}
{#if status >= 500}
<p>Please try reloading the page.</p>
{/if}
<p>If the error persists, please drop by <a href="https://discord.gg/yy75DKs">Discord chatroom</a> and let us know, or raise an issue on <a href="https://github.com/sveltejs/svelte">GitHub</a>. Thanks!</p>
{/if}
{:else}
<h1>It looks like you're offline</h1>
<p>Reload the page once you've found the internet.</p>
{/if}
</div>

@ -48,6 +48,8 @@ export default function() {
const { content, metadata } = extract_frontmatter(markdown);
const sectionSlug = makeSlug(metadata.title);
const subsections = [];
const renderer = new marked.Renderer();
@ -142,7 +144,7 @@ export default function() {
html: html.replace(/@@(\d+)/g, (m, id) => hashes[id] || m),
metadata,
subsections,
slug: file.replace(/^\d+-/, '').replace(/\.md$/, ''),
slug: sectionSlug,
file,
};
});

@ -1,36 +1,6 @@
<script>
import { afterUpdate } from 'svelte';
import Icon from '../../components/Icon.svelte';
export let sections = [];
export let active_section = null;
let ul;
afterUpdate(() => {
const active = ul.querySelector('.active');
if (active) {
const { top, bottom } = active.getBoundingClientRect();
const min = 200;
const max = window.innerHeight - 200;
if (top > max) {
ul.parentNode.scrollBy({
top: top - max,
left: 0,
behavior: 'smooth'
});
} else if (bottom < min) {
ul.parentNode.scrollBy({
top: bottom - min,
left: 0,
behavior: 'smooth'
});
}
}
});
</script>
<style>
@ -40,7 +10,7 @@
border-right: 1px solid var(--second);
background-color: var(--second);
color: white;
padding: 2em 2em 0 2em;
padding: 3rem 3rem 0 3rem;
}
.examples-toc li {
@ -49,13 +19,6 @@
margin: 0 0 4.8rem 0;
}
a {
position: relative;
opacity: 0.7;
transition: opacity 0.2s;
color: white;
}
.section-title {
display: block;
padding: 0 0 .8rem 0;
@ -65,48 +28,40 @@
font-weight: 700;
}
.example-title {
display: block;
a {
display: flex;
position: relative;
color: white;
border-bottom: none;
padding: 0.2rem 3rem;
margin: 0 -3rem;
font-size: 1.6rem;
font-family: var(--font);
padding: 0 0 0.2em 0.6em;
align-items: center;
justify-content: start;
}
.example-title:hover {
a:hover {
color: var(--flash);
opacity: 1
}
.active {
opacity: 1;
font-weight: 600;
}
.row {
position: relative;
margin: 0.5em 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.info {
display: flex;
align-items: center;
a.active {
background: rgba(255, 255, 255, 0.1) calc(100% - 3rem) 50% no-repeat url(/icons/arrow-right.svg);
background-size: 1em 1em;
color: white;
}
.thumbnail {
background: white 50% 50% no-repeat;
background-size: contain;
background-color: white;
object-fit: contain;
width: 5rem;
height: 5rem;
border: 1px solid #ccc;
border-radius: 2px;
box-shadow: 1px 1px 3px rgba(0,0,0,0.13);
margin: 0.2em 0.5em 0.2em 0;
}
</style>
<ul bind:this={ul} class="examples-toc">
<ul class="examples-toc">
{#each sections as section}
<li>
<span class="section-title">
@ -114,25 +69,19 @@
</span>
{#each section.examples as example}
<a href="examples#{example.slug}">
<div
<a
href="examples#{example.slug}"
class="row"
class:active="{example.slug === active_section}"
>
<div class="info">
<div
class="thumbnail"
style="background-image: url(examples/thumbnails/{example.slug}.jpg)"
></div>
<div class="example-title">
{example.title}
</div>
</div>
{#if example.slug === active_section}
<Icon name="arrow-right" />
{/if}
</div>
</a>
<img
class="thumbnail"
alt="{example.title} thumbnail"
src="examples/thumbnails/{example.slug}.jpg"
>
<span>{example.title}</span>
</a>
{/each}
</li>
{/each}

@ -232,7 +232,7 @@ export default app;` });
{/if}
{#if gist}
<a class="icon" href={gist.html_url} title="link to gist">
<a class="icon no-underline" href={gist.html_url} title="link to gist">
<Icon name="link" />
</a>
{/if}
@ -272,6 +272,7 @@ export default app;` });
transition: opacity .3s;
font-family: var(--font);
font-size: 1.6rem;
color: white;
/* width: 1.6em;
height: 1.6em; */
line-height: 1;

@ -1,12 +1,11 @@
import 'dotenv/config';
import polka from 'polka';
import sirv from 'sirv';
import compression from 'compression';
import polka from 'polka';
import devalue from 'devalue';
import session from 'express-session';
import passport from 'passport';
import { Strategy } from 'passport-github';
import sessionFileStore from 'session-file-store';
import devalue from 'devalue';
import * as sapper from '@sapper/server';
const app = polka();
@ -94,7 +93,6 @@ if (process.env.GITHUB_CLIENT_ID) {
}
app.use(
compression({ threshold: 0 }),
sirv('static', {
setHeaders(res) {
res.setHeader('Access-Control-Allow-Origin', '*');

@ -45,7 +45,7 @@ export const langs = {
// links renderer
export function link_renderer(href,title,text) {
export function link_renderer (href, title, text) {
let target_attr = '';
let title_attr = '';

@ -17,13 +17,6 @@ const unicodeRegex = /\p{Letter}/u;
const isNonAlphaNumUnicode =
string => !alphaNumRegex.test(string) && unicodeRegex.test(string);
const nonUnicodeSanitizer = string =>
string
.toLowerCase()
.replace(/[^a-zA-Z0-9]+/g, '-')
.replace(/^-/, '')
.replace(/-$/, '');
export const unicodeSafeProcessor = string =>
string.split('')
.reduce((accum, char, index, array) => {
@ -48,7 +41,6 @@ export const unicodeSafeProcessor = string =>
.reduce((accum, chunk) => {
const processed = chunk.type === 'process'
? limaxProcessor(chunk.string)
// ? nonUnicodeSanitizer(chunk.string)
: chunk.string;
processed.length > 0 && accum.push(processed);

Loading…
Cancel
Save