From cd1c84fd4307658215c810b5bb8752948ac11cf1 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 14 Jan 2018 17:40:25 -0800 Subject: [PATCH 01/22] Optimize Webpack "process" env --- webpack.client.config.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/webpack.client.config.js b/webpack.client.config.js index 904aa06..e30d031 100644 --- a/webpack.client.config.js +++ b/webpack.client.config.js @@ -51,6 +51,10 @@ module.exports = { ].concat(isDev ? [ new webpack.HotModuleReplacementPlugin() ] : [ + new webpack.DefinePlugin({ + 'process.browser': true, + 'process.env.NODE_ENV': '"production"' + }), new ExtractTextPlugin('main.css'), new webpack.optimize.ModuleConcatenationPlugin(), new UglifyJSPlugin() From c4181157dd72b334df151f849d96f148ad88e6e1 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 5 Feb 2018 09:00:26 -0500 Subject: [PATCH 02/22] update dependencies --- .gitignore | 3 ++- package.json | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 81c2c19..f20aae2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ node_modules .sapper yarn.lock cypress/screenshots -templates/.* \ No newline at end of file +templates/.* +dist \ No newline at end of file diff --git a/package.json b/package.json index cf3cf9b..21f2631 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,11 @@ "express": "^4.16.2", "extract-text-webpack-plugin": "^3.0.2", "glob": "^7.1.2", - "node-fetch": "^1.7.3", + "node-fetch": "^2.0.0", "npm-run-all": "^4.1.2", - "sapper": "^0.5.0", + "sapper": "^0.6.3", "serve-static": "^1.13.1", - "style-loader": "^0.19.1", + "style-loader": "^0.20.1", "svelte": "^1.51.1", "svelte-loader": "^2.3.3", "uglifyjs-webpack-plugin": "^1.1.5", From c84ae160ef42b24e04b3ace6e301cc7d425e4e59 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 5 Feb 2018 09:09:32 -0500 Subject: [PATCH 03/22] make project exportable by avoiding api/blog route conflict --- routes/api/{blog/index.js => blog-posts.js} | 2 +- routes/api/blog/_posts.js | 2 +- routes/blog/index.html | 2 +- server.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename routes/api/{blog/index.js => blog-posts.js} (85%) diff --git a/routes/api/blog/index.js b/routes/api/blog-posts.js similarity index 85% rename from routes/api/blog/index.js rename to routes/api/blog-posts.js index 4c10788..7120e67 100644 --- a/routes/api/blog/index.js +++ b/routes/api/blog-posts.js @@ -1,4 +1,4 @@ -import posts from './_posts.js'; +import posts from './blog/_posts.js'; const contents = JSON.stringify(posts.map(post => { return { diff --git a/routes/api/blog/_posts.js b/routes/api/blog/_posts.js index 7fe65c5..0864315 100644 --- a/routes/api/blog/_posts.js +++ b/routes/api/blog/_posts.js @@ -70,7 +70,7 @@ const posts = [
  • It's powered by Svelte instead of React, so it's faster and your apps are smaller
  • Instead of route masking, we encode route parameters in filenames. For example, the page you're looking at right now is routes/blog/[slug].html
  • -
  • As well as pages (Svelte components, which render on server or client), you can create server routes in your routes directory. These are just .js files that export functions corresponding to HTTP methods, and receive Express request and response objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page (look in routes/api/blog)
  • +
  • As well as pages (Svelte components, which render on server or client), you can create server routes in your routes directory. These are just .js files that export functions corresponding to HTTP methods, and receive Express request and response objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page (look in routes/api/blog-posts)
  • Links are just <a> elements, rather than framework-specific <Link> components. That means, for example, that this link right here, despite being inside a blob of HTML, works with the router as you'd expect.
` diff --git a/routes/blog/index.html b/routes/blog/index.html index 16ff29e..70f17a8 100644 --- a/routes/blog/index.html +++ b/routes/blog/index.html @@ -32,7 +32,7 @@ }, preload({ params, query }) { - return fetch(`/api/blog`).then(r => r.json()).then(posts => { + return fetch(`/api/blog-posts`).then(r => r.json()).then(posts => { return { posts }; }); } diff --git a/server.js b/server.js index 5b46a61..cd79704 100644 --- a/server.js +++ b/server.js @@ -6,7 +6,7 @@ const static = require('serve-static'); const { PORT = 3000 } = process.env; -// this allows us to do e.g. `fetch('/api/blog')` on the server +// this allows us to do e.g. `fetch('/api/blog-posts')` on the server const fetch = require('node-fetch'); global.fetch = (url, opts) => { if (url[0] === '/') url = `http://localhost:${PORT}${url}`; From 1f9b212794a265ee0fc016b36bd06e6dc37df3ed Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 17 Feb 2018 17:45:18 -0500 Subject: [PATCH 04/22] WIP towards 0.7 compatibility --- app/client.js | 7 +++ app/manifest/client.js | 15 ++++++ app/manifest/server.js | 20 ++++++++ app/manifest/service-worker.js | 33 +++++++++++++ server.js => app/server.js | 19 +++++--- {templates => app}/service-worker.js | 9 ++-- templates/2xx.html => app/template.html | 6 +-- package.json | 4 +- routes/4xx.html | 1 + routes/5xx.html | 1 + templates/4xx.html | 46 ------------------ templates/5xx.html | 47 ------------------- templates/main.js | 4 -- .../client.config.js | 0 .../server.config.js | 0 15 files changed, 97 insertions(+), 115 deletions(-) create mode 100644 app/client.js create mode 100644 app/manifest/client.js create mode 100644 app/manifest/server.js create mode 100644 app/manifest/service-worker.js rename server.js => app/server.js (57%) rename {templates => app}/service-worker.js (90%) rename templates/2xx.html => app/template.html (89%) create mode 100644 routes/4xx.html create mode 100644 routes/5xx.html delete mode 100644 templates/4xx.html delete mode 100644 templates/5xx.html delete mode 100644 templates/main.js rename webpack.client.config.js => webpack/client.config.js (100%) rename webpack.server.config.js => webpack/server.config.js (100%) diff --git a/app/client.js b/app/client.js new file mode 100644 index 0000000..05d30aa --- /dev/null +++ b/app/client.js @@ -0,0 +1,7 @@ +import { init } from 'sapper/runtime.js'; +import { routes } from './manifest/client.js'; + +// `routes` is an array of route objects injected by Sapper +init(document.querySelector('#sapper'), routes); + +if (module.hot) module.hot.accept(); \ No newline at end of file diff --git a/app/manifest/client.js b/app/manifest/client.js new file mode 100644 index 0000000..55e2bfd --- /dev/null +++ b/app/manifest/client.js @@ -0,0 +1,15 @@ +// This file is generated by Sapper — do not edit it! +export const routes = [ + { pattern: /^\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_" */ '../../routes/index.html') }, + { pattern: /^\/4xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_4xx" */ '../../routes/4xx.html') }, + { pattern: /^\/5xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_5xx" */ '../../routes/5xx.html') }, + { pattern: /^\/about\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "about" */ '../../routes/about.html') }, + { pattern: /^\/blog\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "blog" */ '../../routes/blog/index.html') }, + { pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), load: () => import(/* webpackChunkName: "blog_$slug$" */ '../../routes/blog/[slug].html') } +]; + +if (module.hot) { + import('/Users/208311/Development/SVELTE/sapper/src/hmr-client.js').then(client => { + client.connect(23456); + }); +} \ No newline at end of file diff --git a/app/manifest/server.js b/app/manifest/server.js new file mode 100644 index 0000000..6bc89c4 --- /dev/null +++ b/app/manifest/server.js @@ -0,0 +1,20 @@ +// This file is generated by Sapper — do not edit it! +import _ from '../../routes/index.html'; +import _4xx from '../../routes/4xx.html'; +import _5xx from '../../routes/5xx.html'; +import about from '../../routes/about.html'; +import blog from '../../routes/blog/index.html'; +import * as api_blog_posts from '../../routes/api/blog-posts.js'; +import * as api_blog_$slug$ from '../../routes/api/blog/[slug].js'; +import blog_$slug$ from '../../routes/blog/[slug].html'; + +export const routes = [ + { id: '_', type: 'page', pattern: /^\/?$/, params: () => ({}), module: _ }, + { id: '_4xx', type: 'page', pattern: /^\/4xx\/?$/, params: () => ({}), module: _4xx }, + { id: '_5xx', type: 'page', pattern: /^\/5xx\/?$/, params: () => ({}), module: _5xx }, + { id: 'about', type: 'page', pattern: /^\/about\/?$/, params: () => ({}), module: about }, + { id: 'blog', type: 'page', pattern: /^\/blog\/?$/, params: () => ({}), module: blog }, + { id: 'api_blog_posts', type: 'route', pattern: /^\/api\/blog-posts\/?$/, params: () => ({}), module: api_blog_posts }, + { id: 'api_blog_$slug$', type: 'route', pattern: /^\/api\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: api_blog_$slug$ }, + { id: 'blog_$slug$', type: 'page', pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: blog_$slug$ } +]; \ No newline at end of file diff --git a/app/manifest/service-worker.js b/app/manifest/service-worker.js new file mode 100644 index 0000000..0ea1a75 --- /dev/null +++ b/app/manifest/service-worker.js @@ -0,0 +1,33 @@ +// This file is generated by Sapper — do not edit it! +export const timestamp = 1518906946124; + +export const assets = [ + "favicon.png", + "global.css", + "great-success.png", + "manifest.json", + "svelte-logo-192.png", + "svelte-logo-512.png" +]; + +export const shell = [ + "/client/_.0.15d69aa40f5cf2c235b5.js", + "/client/blog.1.15d69aa40f5cf2c235b5.js", + "/client/blog_$slug$.2.15d69aa40f5cf2c235b5.js", + "/client/about.3.15d69aa40f5cf2c235b5.js", + "/client/_5xx.4.15d69aa40f5cf2c235b5.js", + "/client/_4xx.5.15d69aa40f5cf2c235b5.js", + "/client/6.6.15d69aa40f5cf2c235b5.js", + "/client/main.15d69aa40f5cf2c235b5.js", + "/client/0.b91f3b4b0888fc3dc282.hot-update.js", + "/client/b91f3b4b0888fc3dc282.hot-update.json" +]; + +export const routes = [ + { pattern: /^\/?$/ }, + { pattern: /^\/4xx\/?$/ }, + { pattern: /^\/5xx\/?$/ }, + { pattern: /^\/about\/?$/ }, + { pattern: /^\/blog\/?$/ }, + { pattern: /^\/blog(?:\/([^\/]+))?\/?$/ } +]; \ No newline at end of file diff --git a/server.js b/app/server.js similarity index 57% rename from server.js rename to app/server.js index cd79704..49743bc 100644 --- a/server.js +++ b/app/server.js @@ -1,8 +1,11 @@ -const fs = require('fs'); -const app = require('express')(); -const compression = require('compression'); -const sapper = require('sapper'); -const static = require('serve-static'); +import fs from 'fs'; +import express from 'express'; +import compression from 'compression'; +import sapper from 'sapper'; +import serve from 'serve-static'; +import { routes } from './manifest/server.js'; + +const app = express(); const { PORT = 3000 } = process.env; @@ -15,9 +18,11 @@ global.fetch = (url, opts) => { app.use(compression({ threshold: 0 })); -app.use(static('assets')); +app.use(serve('assets')); -app.use(sapper()); +app.use(sapper({ + routes +})); app.listen(PORT, () => { console.log(`listening on port ${PORT}`); diff --git a/templates/service-worker.js b/app/service-worker.js similarity index 90% rename from templates/service-worker.js rename to app/service-worker.js index cccb12a..542371d 100644 --- a/templates/service-worker.js +++ b/app/service-worker.js @@ -1,15 +1,12 @@ -const timestamp = '__timestamp__'; +import { timestamp, assets, shell, routes } from './manifest/service-worker.js'; + const ASSETS = `cache${timestamp}`; // `shell` is an array of all the files generated by webpack, // `assets` is an array of everything in the `assets` directory -const to_cache = __shell__.concat(__assets__); +const to_cache = shell.concat(assets); const cached = new Set(to_cache); -// `routes` is an array of `{ pattern: RegExp }` objects that -// match the pages in your app -const routes = __routes__; - self.addEventListener('install', event => { event.waitUntil( caches diff --git a/templates/2xx.html b/app/template.html similarity index 89% rename from templates/2xx.html rename to app/template.html index 5dc665a..a7e7d49 100644 --- a/templates/2xx.html +++ b/app/template.html @@ -10,9 +10,9 @@ - %sapper.status% - - - - -

%sapper.title%

-

Could not %sapper.method% %sapper.url%

- - %sapper.scripts% - - \ No newline at end of file diff --git a/templates/5xx.html b/templates/5xx.html deleted file mode 100644 index 357152d..0000000 --- a/templates/5xx.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - %sapper.status% - - - - -

%sapper.title%

-
%sapper.error%
-
%sapper.stack%
- - \ No newline at end of file diff --git a/templates/main.js b/templates/main.js deleted file mode 100644 index aa08cb0..0000000 --- a/templates/main.js +++ /dev/null @@ -1,4 +0,0 @@ -import { init } from 'sapper/runtime.js'; - -// `routes` is an array of route objects injected by Sapper -init(document.querySelector('#sapper'), __routes__); \ No newline at end of file diff --git a/webpack.client.config.js b/webpack/client.config.js similarity index 100% rename from webpack.client.config.js rename to webpack/client.config.js diff --git a/webpack.server.config.js b/webpack/server.config.js similarity index 100% rename from webpack.server.config.js rename to webpack/server.config.js From ad0da849fbe88d5def104bf5f1372f6e959eface Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 17 Feb 2018 18:39:46 -0500 Subject: [PATCH 05/22] example error pages --- app/manifest/client.js | 4 ++-- app/manifest/server.js | 4 ++-- app/manifest/service-worker.js | 22 +++++++---------- app/server.js | 2 +- routes/4xx.html | 44 +++++++++++++++++++++++++++++++++- routes/5xx.html | 42 +++++++++++++++++++++++++++++++- 6 files changed, 98 insertions(+), 20 deletions(-) diff --git a/app/manifest/client.js b/app/manifest/client.js index 55e2bfd..8c71326 100644 --- a/app/manifest/client.js +++ b/app/manifest/client.js @@ -1,8 +1,8 @@ // This file is generated by Sapper — do not edit it! export const routes = [ { pattern: /^\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_" */ '../../routes/index.html') }, - { pattern: /^\/4xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_4xx" */ '../../routes/4xx.html') }, - { pattern: /^\/5xx\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_5xx" */ '../../routes/5xx.html') }, + { error: '4xx', load: () => import(/* webpackChunkName: "_4xx" */ '../../routes/4xx.html') }, + { error: '5xx', load: () => import(/* webpackChunkName: "_5xx" */ '../../routes/5xx.html') }, { pattern: /^\/about\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "about" */ '../../routes/about.html') }, { pattern: /^\/blog\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "blog" */ '../../routes/blog/index.html') }, { pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), load: () => import(/* webpackChunkName: "blog_$slug$" */ '../../routes/blog/[slug].html') } diff --git a/app/manifest/server.js b/app/manifest/server.js index 6bc89c4..48f7bd9 100644 --- a/app/manifest/server.js +++ b/app/manifest/server.js @@ -10,8 +10,8 @@ import blog_$slug$ from '../../routes/blog/[slug].html'; export const routes = [ { id: '_', type: 'page', pattern: /^\/?$/, params: () => ({}), module: _ }, - { id: '_4xx', type: 'page', pattern: /^\/4xx\/?$/, params: () => ({}), module: _4xx }, - { id: '_5xx', type: 'page', pattern: /^\/5xx\/?$/, params: () => ({}), module: _5xx }, + { error: '4xx', module: _4xx }, + { error: '5xx', module: _5xx }, { id: 'about', type: 'page', pattern: /^\/about\/?$/, params: () => ({}), module: about }, { id: 'blog', type: 'page', pattern: /^\/blog\/?$/, params: () => ({}), module: blog }, { id: 'api_blog_posts', type: 'route', pattern: /^\/api\/blog-posts\/?$/, params: () => ({}), module: api_blog_posts }, diff --git a/app/manifest/service-worker.js b/app/manifest/service-worker.js index 0ea1a75..cb87744 100644 --- a/app/manifest/service-worker.js +++ b/app/manifest/service-worker.js @@ -1,5 +1,5 @@ // This file is generated by Sapper — do not edit it! -export const timestamp = 1518906946124; +export const timestamp = 1518910653621; export const assets = [ "favicon.png", @@ -11,22 +11,18 @@ export const assets = [ ]; export const shell = [ - "/client/_.0.15d69aa40f5cf2c235b5.js", - "/client/blog.1.15d69aa40f5cf2c235b5.js", - "/client/blog_$slug$.2.15d69aa40f5cf2c235b5.js", - "/client/about.3.15d69aa40f5cf2c235b5.js", - "/client/_5xx.4.15d69aa40f5cf2c235b5.js", - "/client/_4xx.5.15d69aa40f5cf2c235b5.js", - "/client/6.6.15d69aa40f5cf2c235b5.js", - "/client/main.15d69aa40f5cf2c235b5.js", - "/client/0.b91f3b4b0888fc3dc282.hot-update.js", - "/client/b91f3b4b0888fc3dc282.hot-update.json" + "/client/_.0.6b48eb953c3d3763d72b.js", + "/client/blog.1.6b48eb953c3d3763d72b.js", + "/client/blog_$slug$.2.6b48eb953c3d3763d72b.js", + "/client/about.3.6b48eb953c3d3763d72b.js", + "/client/_5xx.4.6b48eb953c3d3763d72b.js", + "/client/_4xx.5.6b48eb953c3d3763d72b.js", + "/client/6.6.6b48eb953c3d3763d72b.js", + "/client/main.6b48eb953c3d3763d72b.js" ]; export const routes = [ { pattern: /^\/?$/ }, - { pattern: /^\/4xx\/?$/ }, - { pattern: /^\/5xx\/?$/ }, { pattern: /^\/about\/?$/ }, { pattern: /^\/blog\/?$/ }, { pattern: /^\/blog(?:\/([^\/]+))?\/?$/ } diff --git a/app/server.js b/app/server.js index 49743bc..0af7864 100644 --- a/app/server.js +++ b/app/server.js @@ -3,6 +3,7 @@ import express from 'express'; import compression from 'compression'; import sapper from 'sapper'; import serve from 'serve-static'; +import fetch from 'node-fetch'; import { routes } from './manifest/server.js'; const app = express(); @@ -10,7 +11,6 @@ const app = express(); const { PORT = 3000 } = process.env; // this allows us to do e.g. `fetch('/api/blog-posts')` on the server -const fetch = require('node-fetch'); global.fetch = (url, opts) => { if (url[0] === '/') url = `http://localhost:${PORT}${url}`; return fetch(url, opts); diff --git a/routes/4xx.html b/routes/4xx.html index efe6e3b..0a98eb7 100644 --- a/routes/4xx.html +++ b/routes/4xx.html @@ -1 +1,43 @@ -TODO 4xx \ No newline at end of file +<:Head> + Not found + + + +

Not found

+ +

Please check the URL

+
+ + + + diff --git a/routes/5xx.html b/routes/5xx.html index 9391ebe..efcc337 100644 --- a/routes/5xx.html +++ b/routes/5xx.html @@ -1 +1,41 @@ -TODO 5xx \ No newline at end of file +<:Head> + Internal server error + + + +

Internal server error

+
+ + + + From 220af2b1dd714663514273d1033ee2a3d1cacec0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 18 Feb 2018 12:15:32 -0500 Subject: [PATCH 06/22] remove generated files --- .gitignore | 3 ++- app/manifest/client.js | 15 --------------- app/manifest/server.js | 20 -------------------- app/manifest/service-worker.js | 29 ----------------------------- 4 files changed, 2 insertions(+), 65 deletions(-) delete mode 100644 app/manifest/client.js delete mode 100644 app/manifest/server.js delete mode 100644 app/manifest/service-worker.js diff --git a/.gitignore b/.gitignore index f20aae2..7800c23 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ node_modules yarn.lock cypress/screenshots templates/.* -dist \ No newline at end of file +dist +app/manifest \ No newline at end of file diff --git a/app/manifest/client.js b/app/manifest/client.js deleted file mode 100644 index 8c71326..0000000 --- a/app/manifest/client.js +++ /dev/null @@ -1,15 +0,0 @@ -// This file is generated by Sapper — do not edit it! -export const routes = [ - { pattern: /^\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "_" */ '../../routes/index.html') }, - { error: '4xx', load: () => import(/* webpackChunkName: "_4xx" */ '../../routes/4xx.html') }, - { error: '5xx', load: () => import(/* webpackChunkName: "_5xx" */ '../../routes/5xx.html') }, - { pattern: /^\/about\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "about" */ '../../routes/about.html') }, - { pattern: /^\/blog\/?$/, params: () => ({}), load: () => import(/* webpackChunkName: "blog" */ '../../routes/blog/index.html') }, - { pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), load: () => import(/* webpackChunkName: "blog_$slug$" */ '../../routes/blog/[slug].html') } -]; - -if (module.hot) { - import('/Users/208311/Development/SVELTE/sapper/src/hmr-client.js').then(client => { - client.connect(23456); - }); -} \ No newline at end of file diff --git a/app/manifest/server.js b/app/manifest/server.js deleted file mode 100644 index 48f7bd9..0000000 --- a/app/manifest/server.js +++ /dev/null @@ -1,20 +0,0 @@ -// This file is generated by Sapper — do not edit it! -import _ from '../../routes/index.html'; -import _4xx from '../../routes/4xx.html'; -import _5xx from '../../routes/5xx.html'; -import about from '../../routes/about.html'; -import blog from '../../routes/blog/index.html'; -import * as api_blog_posts from '../../routes/api/blog-posts.js'; -import * as api_blog_$slug$ from '../../routes/api/blog/[slug].js'; -import blog_$slug$ from '../../routes/blog/[slug].html'; - -export const routes = [ - { id: '_', type: 'page', pattern: /^\/?$/, params: () => ({}), module: _ }, - { error: '4xx', module: _4xx }, - { error: '5xx', module: _5xx }, - { id: 'about', type: 'page', pattern: /^\/about\/?$/, params: () => ({}), module: about }, - { id: 'blog', type: 'page', pattern: /^\/blog\/?$/, params: () => ({}), module: blog }, - { id: 'api_blog_posts', type: 'route', pattern: /^\/api\/blog-posts\/?$/, params: () => ({}), module: api_blog_posts }, - { id: 'api_blog_$slug$', type: 'route', pattern: /^\/api\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: api_blog_$slug$ }, - { id: 'blog_$slug$', type: 'page', pattern: /^\/blog(?:\/([^\/]+))?\/?$/, params: match => ({ slug: match[1] }), module: blog_$slug$ } -]; \ No newline at end of file diff --git a/app/manifest/service-worker.js b/app/manifest/service-worker.js deleted file mode 100644 index cb87744..0000000 --- a/app/manifest/service-worker.js +++ /dev/null @@ -1,29 +0,0 @@ -// This file is generated by Sapper — do not edit it! -export const timestamp = 1518910653621; - -export const assets = [ - "favicon.png", - "global.css", - "great-success.png", - "manifest.json", - "svelte-logo-192.png", - "svelte-logo-512.png" -]; - -export const shell = [ - "/client/_.0.6b48eb953c3d3763d72b.js", - "/client/blog.1.6b48eb953c3d3763d72b.js", - "/client/blog_$slug$.2.6b48eb953c3d3763d72b.js", - "/client/about.3.6b48eb953c3d3763d72b.js", - "/client/_5xx.4.6b48eb953c3d3763d72b.js", - "/client/_4xx.5.6b48eb953c3d3763d72b.js", - "/client/6.6.6b48eb953c3d3763d72b.js", - "/client/main.6b48eb953c3d3763d72b.js" -]; - -export const routes = [ - { pattern: /^\/?$/ }, - { pattern: /^\/about\/?$/ }, - { pattern: /^\/blog\/?$/ }, - { pattern: /^\/blog(?:\/([^\/]+))?\/?$/ } -]; \ No newline at end of file From 4d9250e7a72ab9e772565e8f8a369571a545e7f0 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 18 Feb 2018 12:48:20 -0500 Subject: [PATCH 07/22] add service worker config --- package.json | 3 ++- webpack/service-worker.config.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 webpack/service-worker.config.js diff --git a/package.json b/package.json index 0be5f52..7deb2f7 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "scripts": { "dev": "sapper dev", "build": "sapper build", - "start": "cross-env NODE_ENV=production node server.js", + "export": "sapper export", + "start": "cross-env NODE_ENV=production node .sapper/server.js", "cy:run": "cypress run", "cy:open": "cypress open", "test": "run-p --race dev cy:run" diff --git a/webpack/service-worker.config.js b/webpack/service-worker.config.js new file mode 100644 index 0000000..d29ca30 --- /dev/null +++ b/webpack/service-worker.config.js @@ -0,0 +1,17 @@ +const path = require('path'); +const config = require('sapper/webpack/config.js'); +const webpack = require('webpack'); + +module.exports = { + entry: { + 'service-worker': './app/service-worker.js' + }, + output: { + path: path.resolve(`.sapper`), + filename: '[name].js', + chunkFilename: '[name].[id].[hash].js' + }, + plugins: [ + !config.dev && new webpack.optimize.ModuleConcatenationPlugin() + ].filter(Boolean) +}; \ No newline at end of file From e5d3589b636cf073954aa7e374d1e33a10048bba Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 18 Feb 2018 17:06:16 -0500 Subject: [PATCH 08/22] updating Sapper would help --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7deb2f7..f81c911 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "glob": "^7.1.2", "node-fetch": "^2.0.0", "npm-run-all": "^4.1.2", - "sapper": "^0.6.4", + "sapper": "^0.7.0", "serve-static": "^1.13.1", "style-loader": "^0.20.1", "svelte": "^1.51.1", From 6a286f470d523c4b62326510c2b928e9590678f8 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 3 Mar 2018 21:39:28 -0500 Subject: [PATCH 09/22] switch to [slug].json.js server routes, instead of /api/... --- routes/{api/blog-posts.js => blog.json.js} | 0 routes/blog/[slug].html | 2 +- routes/{api/blog/[slug].js => blog/[slug].json.js} | 2 +- routes/{api => }/blog/_posts.js | 4 ++-- routes/blog/index.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename routes/{api/blog-posts.js => blog.json.js} (100%) rename routes/{api/blog/[slug].js => blog/[slug].json.js} (93%) rename routes/{api => }/blog/_posts.js (96%) diff --git a/routes/api/blog-posts.js b/routes/blog.json.js similarity index 100% rename from routes/api/blog-posts.js rename to routes/blog.json.js diff --git a/routes/blog/[slug].html b/routes/blog/[slug].html index 2646930..96c4699 100644 --- a/routes/blog/[slug].html +++ b/routes/blog/[slug].html @@ -59,7 +59,7 @@ // is called [slug].html const { slug } = params; - return fetch(`/api/blog/${slug}`).then(r => r.json()).then(post => { + return fetch(`/blog/${slug}.json`).then(r => r.json()).then(post => { return { post }; }); } diff --git a/routes/api/blog/[slug].js b/routes/blog/[slug].json.js similarity index 93% rename from routes/api/blog/[slug].js rename to routes/blog/[slug].json.js index f1a151f..33fc51e 100644 --- a/routes/api/blog/[slug].js +++ b/routes/blog/[slug].json.js @@ -7,7 +7,7 @@ posts.forEach(post => { export function get(req, res, next) { // the `slug` parameter is available because this file - // is called [slug].js + // is called [slug].json.js const { slug } = req.params; if (lookup.has(slug)) { diff --git a/routes/api/blog/_posts.js b/routes/blog/_posts.js similarity index 96% rename from routes/api/blog/_posts.js rename to routes/blog/_posts.js index 0864315..9e1ac88 100644 --- a/routes/api/blog/_posts.js +++ b/routes/blog/_posts.js @@ -4,7 +4,7 @@ // service of obviousness, we're just going to leave it here. // This file is called `_posts.js` rather than `posts.js`, because -// we don't want to create an `/api/blog/posts` route — the leading +// we don't want to create an `/blog/posts` route — the leading // underscore tells Sapper not to do that. const posts = [ @@ -70,7 +70,7 @@ const posts = [
  • It's powered by Svelte instead of React, so it's faster and your apps are smaller
  • Instead of route masking, we encode route parameters in filenames. For example, the page you're looking at right now is routes/blog/[slug].html
  • -
  • As well as pages (Svelte components, which render on server or client), you can create server routes in your routes directory. These are just .js files that export functions corresponding to HTTP methods, and receive Express request and response objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page (look in routes/api/blog-posts)
  • +
  • As well as pages (Svelte components, which render on server or client), you can create server routes in your routes directory. These are just .js files that export functions corresponding to HTTP methods, and receive Express request and response objects as arguments. This makes it very easy to, for example, add a JSON API such as the one powering this very page
  • Links are just <a> elements, rather than framework-specific <Link> components. That means, for example, that this link right here, despite being inside a blob of HTML, works with the router as you'd expect.
` diff --git a/routes/blog/index.html b/routes/blog/index.html index 70f17a8..d8deaf5 100644 --- a/routes/blog/index.html +++ b/routes/blog/index.html @@ -32,7 +32,7 @@ }, preload({ params, query }) { - return fetch(`/api/blog-posts`).then(r => r.json()).then(posts => { + return fetch(`/blog.json`).then(r => r.json()).then(posts => { return { posts }; }); } From 207ea8fdc0e5c2601a313bf1409260ad91510754 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 3 Mar 2018 21:40:52 -0500 Subject: [PATCH 10/22] update gitignore for 0.8 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7800c23..a92a219 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,5 @@ node_modules yarn.lock cypress/screenshots templates/.* -dist +export app/manifest \ No newline at end of file From dad66403ce3878be5c926ed903469a512a89a35c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 3 Mar 2018 21:41:13 -0500 Subject: [PATCH 11/22] update default extensions --- webpack/server.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack/server.config.js b/webpack/server.config.js index 97a977c..cde81b6 100644 --- a/webpack/server.config.js +++ b/webpack/server.config.js @@ -8,7 +8,7 @@ module.exports = { output: config.server.output(), target: 'node', resolve: { - extensions: ['.js', '.html'] + extensions: ['.js', '.html', '.json'] }, module: { rules: [ From ec1db3fc34761b0bcfe8e8fcac80494713889efc Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sat, 3 Mar 2018 21:41:26 -0500 Subject: [PATCH 12/22] fix and update service worker --- app/service-worker.js | 5 ++++- app/template.html | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/service-worker.js b/app/service-worker.js index 542371d..e7f27f4 100644 --- a/app/service-worker.js +++ b/app/service-worker.js @@ -37,8 +37,11 @@ self.addEventListener('fetch', event => { // don't try to handle e.g. data: URIs if (!url.protocol.startsWith('http')) return; + // ignore dev server requests + if (url.hostname === self.location.hostname && url.port !== self.location.port) return; + // always serve assets and webpack-generated files from cache - if (cached.has(url.pathname)) { + if (url.host === self.location.host && cached.has(url.pathname)) { event.respondWith(caches.match(event.request)); return; } diff --git a/app/template.html b/app/template.html index a7e7d49..5dc665a 100644 --- a/app/template.html +++ b/app/template.html @@ -10,9 +10,9 @@