mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-15 02:11:05 +00:00
chore(examples): add sapper set-up
This commit is contained in:
parent
c1b98ced95
commit
fbb0c2d413
17 changed files with 2677 additions and 0 deletions
|
@ -47,6 +47,7 @@
|
||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
if (isValidTheme(theme)) {
|
if (isValidTheme(theme)) {
|
||||||
document.documentElement.setAttribute("theme", theme);
|
document.documentElement.setAttribute("theme", theme);
|
||||||
|
|
||||||
if (persist) {
|
if (persist) {
|
||||||
localStorage.setItem(persistKey, theme);
|
localStorage.setItem(persistKey, theme);
|
||||||
}
|
}
|
||||||
|
|
5
examples/sapper/.gitignore
vendored
Normal file
5
examples/sapper/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.DS_Store
|
||||||
|
/node_modules/
|
||||||
|
/src/node_modules/@sapper/
|
||||||
|
yarn-error.log
|
||||||
|
/__sapper__/
|
23
examples/sapper/README.md
Normal file
23
examples/sapper/README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# svite
|
||||||
|
|
||||||
|
> Example set-up using [Sapper](https://github.com/sveltejs/sapper).
|
||||||
|
|
||||||
|
## Available scripts
|
||||||
|
|
||||||
|
### `yarn dev`
|
||||||
|
|
||||||
|
Runs the app in development mode.
|
||||||
|
|
||||||
|
### `yarn build`
|
||||||
|
|
||||||
|
Builds the app for production (SSR).
|
||||||
|
|
||||||
|
### `yarn export`
|
||||||
|
|
||||||
|
Builds the app for production and statically exports the app.
|
||||||
|
|
||||||
|
### `yarn start`
|
||||||
|
|
||||||
|
Runs the app in production (`yarn build` must be run first).
|
||||||
|
|
||||||
|
|
34
examples/sapper/package.json
Normal file
34
examples/sapper/package.json
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "sapper dev",
|
||||||
|
"build": "sapper build --legacy",
|
||||||
|
"export": "sapper export --legacy",
|
||||||
|
"start": "node __sapper__/build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"compression": "^1.7.1",
|
||||||
|
"polka": "next",
|
||||||
|
"sirv": "^1.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.0.0",
|
||||||
|
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.0.0",
|
||||||
|
"@babel/preset-env": "^7.0.0",
|
||||||
|
"@babel/runtime": "^7.0.0",
|
||||||
|
"@rollup/plugin-babel": "^5.0.0",
|
||||||
|
"@rollup/plugin-commonjs": "^14.0.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^8.0.0",
|
||||||
|
"@rollup/plugin-replace": "^2.2.0",
|
||||||
|
"carbon-components-svelte": "^0.11.0",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"rollup": "^2.3.4",
|
||||||
|
"rollup-plugin-svelte": "^6.0.0",
|
||||||
|
"rollup-plugin-terser": "^7.0.0",
|
||||||
|
"sapper": "^0.28.0",
|
||||||
|
"svelte": "^3.17.3",
|
||||||
|
"svelte-preprocess": "^4.2.1"
|
||||||
|
}
|
||||||
|
}
|
118
examples/sapper/rollup.config.js
Normal file
118
examples/sapper/rollup.config.js
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
|
import replace from "@rollup/plugin-replace";
|
||||||
|
import commonjs from "@rollup/plugin-commonjs";
|
||||||
|
import svelte from "rollup-plugin-svelte";
|
||||||
|
import babel from "@rollup/plugin-babel";
|
||||||
|
import { terser } from "rollup-plugin-terser";
|
||||||
|
import sveltePreprocess from "svelte-preprocess";
|
||||||
|
import config from "sapper/config/rollup.js";
|
||||||
|
import pkg from "./package.json";
|
||||||
|
|
||||||
|
const mode = process.env.NODE_ENV;
|
||||||
|
const dev = mode === "development";
|
||||||
|
const legacy = !!process.env.SAPPER_LEGACY_BUILD;
|
||||||
|
|
||||||
|
const onwarn = (warning, onwarn) =>
|
||||||
|
(warning.code === "MISSING_EXPORT" && /'preload'/.test(warning.message)) ||
|
||||||
|
(warning.code === "CIRCULAR_DEPENDENCY" &&
|
||||||
|
/[/\\]@sapper[/\\]/.test(warning.message)) ||
|
||||||
|
onwarn(warning);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
client: {
|
||||||
|
input: config.client.input(),
|
||||||
|
output: config.client.output(),
|
||||||
|
plugins: [
|
||||||
|
replace({
|
||||||
|
"process.browser": true,
|
||||||
|
"process.env.NODE_ENV": JSON.stringify(mode),
|
||||||
|
}),
|
||||||
|
svelte({
|
||||||
|
dev,
|
||||||
|
hydratable: true,
|
||||||
|
emitCss: true,
|
||||||
|
preprocess: sveltePreprocess(),
|
||||||
|
}),
|
||||||
|
resolve({
|
||||||
|
browser: true,
|
||||||
|
dedupe: ["svelte"],
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
|
||||||
|
legacy &&
|
||||||
|
babel({
|
||||||
|
extensions: [".js", ".mjs", ".html", ".svelte"],
|
||||||
|
babelHelpers: "runtime",
|
||||||
|
exclude: ["node_modules/@babel/**"],
|
||||||
|
presets: [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
targets: "> 0.25%, not dead",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
"@babel/plugin-syntax-dynamic-import",
|
||||||
|
[
|
||||||
|
"@babel/plugin-transform-runtime",
|
||||||
|
{
|
||||||
|
useESModules: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
|
||||||
|
!dev &&
|
||||||
|
terser({
|
||||||
|
module: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
preserveEntrySignatures: false,
|
||||||
|
onwarn,
|
||||||
|
},
|
||||||
|
|
||||||
|
server: {
|
||||||
|
input: config.server.input(),
|
||||||
|
output: config.server.output(),
|
||||||
|
plugins: [
|
||||||
|
replace({
|
||||||
|
"process.browser": false,
|
||||||
|
"process.env.NODE_ENV": JSON.stringify(mode),
|
||||||
|
}),
|
||||||
|
svelte({
|
||||||
|
generate: "ssr",
|
||||||
|
hydratable: true,
|
||||||
|
dev,
|
||||||
|
}),
|
||||||
|
resolve({
|
||||||
|
dedupe: ["svelte"],
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
],
|
||||||
|
external: Object.keys(pkg.dependencies).concat(
|
||||||
|
require("module").builtinModules
|
||||||
|
),
|
||||||
|
|
||||||
|
preserveEntrySignatures: "strict",
|
||||||
|
onwarn,
|
||||||
|
},
|
||||||
|
|
||||||
|
serviceworker: {
|
||||||
|
input: config.serviceworker.input(),
|
||||||
|
output: config.serviceworker.output(),
|
||||||
|
plugins: [
|
||||||
|
resolve(),
|
||||||
|
replace({
|
||||||
|
"process.browser": true,
|
||||||
|
"process.env.NODE_ENV": JSON.stringify(mode),
|
||||||
|
}),
|
||||||
|
commonjs(),
|
||||||
|
!dev && terser(),
|
||||||
|
],
|
||||||
|
|
||||||
|
preserveEntrySignatures: false,
|
||||||
|
onwarn,
|
||||||
|
},
|
||||||
|
};
|
3
examples/sapper/src/client.js
Normal file
3
examples/sapper/src/client.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import * as sapper from "@sapper/app";
|
||||||
|
|
||||||
|
sapper.start({ target: document.querySelector("#sapper") });
|
37
examples/sapper/src/components/Header.svelte
Normal file
37
examples/sapper/src/components/Header.svelte
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<script>
|
||||||
|
export let segment = undefined;
|
||||||
|
|
||||||
|
import {
|
||||||
|
SkipToContent,
|
||||||
|
Header,
|
||||||
|
HeaderUtilities,
|
||||||
|
HeaderGlobalAction,
|
||||||
|
} from "carbon-components-svelte";
|
||||||
|
import Notification20 from "carbon-icons-svelte/lib/Notification20";
|
||||||
|
import UserAvatar20 from "carbon-icons-svelte/lib/UserAvatar20";
|
||||||
|
import AppSwitcher20 from "carbon-icons-svelte/lib/AppSwitcher20";
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
const ctx = getContext("Theme");
|
||||||
|
|
||||||
|
$: if (ctx) {
|
||||||
|
ctx.dark.subscribe((value) => {
|
||||||
|
console.log("dark mode?", value);
|
||||||
|
});
|
||||||
|
ctx.light.subscribe((value) => {
|
||||||
|
console.log("light mode?", value);
|
||||||
|
});
|
||||||
|
ctx.updateVar("--cds-productive-heading-06-font-size", "4rem");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Header company="IBM" platformName="Carbon Components Svelte" href="/">
|
||||||
|
<div slot="skip-to-content">
|
||||||
|
<SkipToContent />
|
||||||
|
</div>
|
||||||
|
<HeaderUtilities>
|
||||||
|
<HeaderGlobalAction aria-label="Notifications" icon="{Notification20}" />
|
||||||
|
<HeaderGlobalAction aria-label="User Avatar" icon="{UserAvatar20}" />
|
||||||
|
<HeaderGlobalAction aria-label="App Switcher" icon="{AppSwitcher20}" />
|
||||||
|
</HeaderUtilities>
|
||||||
|
</Header>
|
73
examples/sapper/src/components/Nav.svelte
Normal file
73
examples/sapper/src/components/Nav.svelte
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<script>
|
||||||
|
export let segment;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
nav {
|
||||||
|
border-bottom: 1px solid rgba(255, 62, 0, 0.1);
|
||||||
|
font-weight: 300;
|
||||||
|
padding: 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clearfix */
|
||||||
|
ul::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-current] {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
[aria-current]::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: calc(100% - 1em);
|
||||||
|
height: 2px;
|
||||||
|
background-color: rgb(255, 62, 0);
|
||||||
|
display: block;
|
||||||
|
bottom: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 1em 0.5em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-current="{segment === undefined ? 'page' : undefined}"
|
||||||
|
href=".">home</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-current="{segment === 'about' ? 'page' : undefined}"
|
||||||
|
href="about">about</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- for the blog link, we're using rel=prefetch so that Sapper prefetches
|
||||||
|
the blog data when we hover over the link or tap it on a touchscreen -->
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
rel="prefetch"
|
||||||
|
aria-current="{segment === 'blog' ? 'page' : undefined}"
|
||||||
|
href="blog">blog</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
74
examples/sapper/src/components/Theme.svelte
Normal file
74
examples/sapper/src/components/Theme.svelte
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<script>
|
||||||
|
export let persist = false;
|
||||||
|
export let persistKey = "theme";
|
||||||
|
export let theme = "white";
|
||||||
|
export const themes = ["white", "g10", "g90", "g100"];
|
||||||
|
|
||||||
|
import { onMount, afterUpdate, setContext } from "svelte";
|
||||||
|
import { writable, derived } from "svelte/store";
|
||||||
|
|
||||||
|
const isValidTheme = (value) => themes.includes(value);
|
||||||
|
const isDark = (value) =>
|
||||||
|
isValidTheme(value) && (value === "g90" || value === "g100");
|
||||||
|
|
||||||
|
const carbon_theme = writable(theme);
|
||||||
|
const dark = writable(isDark(theme));
|
||||||
|
const light = derived(dark, (_) => !_);
|
||||||
|
|
||||||
|
const unsubscribe = carbon_theme.subscribe((value) => {
|
||||||
|
theme = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
let _document = null;
|
||||||
|
|
||||||
|
setContext("Theme", {
|
||||||
|
updateVar: (name, value) => {
|
||||||
|
if (_document != null) {
|
||||||
|
_document.documentElement.style.setProperty(name, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
carbon_theme,
|
||||||
|
dark,
|
||||||
|
light,
|
||||||
|
});
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
_document = window.document;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const persisted_theme = localStorage.getItem(persistKey);
|
||||||
|
|
||||||
|
if (isValidTheme(persisted_theme)) {
|
||||||
|
carbon_theme.set(persisted_theme);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsubscribe();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterUpdate(() => {
|
||||||
|
if (isValidTheme(theme)) {
|
||||||
|
if (_document != null) {
|
||||||
|
_document.documentElement.setAttribute("theme", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (persist) {
|
||||||
|
localStorage.setItem(persistKey, theme);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(
|
||||||
|
`"${theme}" is not a valid Carbon theme. Choose from available themes: ${JSON.stringify(
|
||||||
|
themes
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$: dark.set(isDark(theme));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
23
examples/sapper/src/routes/_error.svelte
Normal file
23
examples/sapper/src/routes/_error.svelte
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<script>
|
||||||
|
export let status;
|
||||||
|
export let error;
|
||||||
|
|
||||||
|
import { Row, Column, Link } from "carbon-components-svelte";
|
||||||
|
|
||||||
|
const dev = process.env.NODE_ENV === "development";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Column lg="{16}">
|
||||||
|
<h1>{status}</h1>
|
||||||
|
<div>
|
||||||
|
{error.message}
|
||||||
|
<Link inline href="/">Return home</Link>
|
||||||
|
</div>
|
||||||
|
{#if dev && error.stack}
|
||||||
|
<div>
|
||||||
|
<pre>{error.stack}</pre>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</Column>
|
||||||
|
</Row>
|
32
examples/sapper/src/routes/_layout.svelte
Normal file
32
examples/sapper/src/routes/_layout.svelte
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<script>
|
||||||
|
export let segment = undefined;
|
||||||
|
|
||||||
|
import {
|
||||||
|
Content,
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
Grid,
|
||||||
|
Row,
|
||||||
|
Column,
|
||||||
|
Tabs,
|
||||||
|
TabContent,
|
||||||
|
Tab,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
} from "carbon-components-svelte";
|
||||||
|
import Header from "../components/Header.svelte";
|
||||||
|
import Theme from "../components/Theme.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" global>
|
||||||
|
@import "carbon-components-svelte/css/all";
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<Theme persist theme="g10">
|
||||||
|
<Header segment="{segment}" />
|
||||||
|
<Content style="background: none; padding: 1rem">
|
||||||
|
<Grid>
|
||||||
|
<slot />
|
||||||
|
</Grid>
|
||||||
|
</Content>
|
||||||
|
</Theme>
|
84
examples/sapper/src/routes/index.svelte
Normal file
84
examples/sapper/src/routes/index.svelte
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
Content,
|
||||||
|
Breadcrumb,
|
||||||
|
BreadcrumbItem,
|
||||||
|
Grid,
|
||||||
|
Row,
|
||||||
|
Column,
|
||||||
|
Tabs,
|
||||||
|
TabContent,
|
||||||
|
Tab,
|
||||||
|
Select,
|
||||||
|
SelectItem,
|
||||||
|
} from "carbon-components-svelte";
|
||||||
|
|
||||||
|
import { getContext } from "svelte";
|
||||||
|
|
||||||
|
const { carbon_theme } = getContext("Theme");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Column lg="{16}">
|
||||||
|
<Breadcrumb noTrailingSlash aria-label="Page navigation">
|
||||||
|
<BreadcrumbItem href="/">Getting started</BreadcrumbItem>
|
||||||
|
</Breadcrumb>
|
||||||
|
<h1 style="margin-bottom: 1.5rem">Design & build with Carbon</h1>
|
||||||
|
</Column>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Column noGutter>
|
||||||
|
<Tabs aria-label="Tab navigation">
|
||||||
|
<Tab label="About" />
|
||||||
|
<Tab label="Design" />
|
||||||
|
<Tab label="Develop" />
|
||||||
|
<div slot="content" class="tabbed-content">
|
||||||
|
<Grid as fullWidth let:props>
|
||||||
|
<TabContent {...props}>
|
||||||
|
<Row>
|
||||||
|
<Column md="{4}" lg="{7}">
|
||||||
|
<Select
|
||||||
|
labelText="Carbon theme"
|
||||||
|
bind:selected="{$carbon_theme}"
|
||||||
|
style="margin-bottom: 1rem">
|
||||||
|
<SelectItem value="white" text="White" />
|
||||||
|
<SelectItem value="g10" text="Gray 10" />
|
||||||
|
<SelectItem value="g90" text="Gray 90" />
|
||||||
|
<SelectItem value="g100" text="Gray 100" />
|
||||||
|
</Select>
|
||||||
|
<p>
|
||||||
|
Carbon is IBM’s open-source design system for digital products
|
||||||
|
and experiences. With the IBM Design Language as its
|
||||||
|
foundation, the system consists of working code, design tools
|
||||||
|
and resources, human interface guidelines, and a vibrant
|
||||||
|
community of contributors.
|
||||||
|
</p>
|
||||||
|
</Column>
|
||||||
|
</Row>
|
||||||
|
</TabContent>
|
||||||
|
<TabContent {...props}>
|
||||||
|
<Row>
|
||||||
|
<Column md="{4}" lg="{7}">
|
||||||
|
<p>
|
||||||
|
Rapidly build beautiful and accessible experiences. The Carbon
|
||||||
|
kit contains all resources you need to get started.
|
||||||
|
</p>
|
||||||
|
</Column>
|
||||||
|
</Row>
|
||||||
|
</TabContent>
|
||||||
|
<TabContent {...props}>
|
||||||
|
<Row>
|
||||||
|
<Column md="{4}" lg="{7}">
|
||||||
|
<p>
|
||||||
|
Carbon provides styles and components in Vanilla, React,
|
||||||
|
Angular, Vue and Svelte for anyone building on the web.
|
||||||
|
</p>
|
||||||
|
</Column>
|
||||||
|
</Row>
|
||||||
|
</TabContent>
|
||||||
|
</Grid>
|
||||||
|
</div>
|
||||||
|
</Tabs>
|
||||||
|
</Column>
|
||||||
|
</Row>
|
16
examples/sapper/src/server.js
Normal file
16
examples/sapper/src/server.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import sirv from "sirv";
|
||||||
|
import polka from "polka";
|
||||||
|
import compression from "compression";
|
||||||
|
import * as sapper from "@sapper/server";
|
||||||
|
|
||||||
|
const { PORT, NODE_ENV } = process.env;
|
||||||
|
|
||||||
|
polka()
|
||||||
|
.use(
|
||||||
|
compression({ threshold: 0 }),
|
||||||
|
sirv("static", { dev: NODE_ENV === "development" }),
|
||||||
|
sapper.middleware()
|
||||||
|
)
|
||||||
|
.listen(PORT, (err) => {
|
||||||
|
if (err) console.log("error", err);
|
||||||
|
});
|
82
examples/sapper/src/service-worker.js
Normal file
82
examples/sapper/src/service-worker.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import { timestamp, files, shell, routes } from '@sapper/service-worker';
|
||||||
|
|
||||||
|
const ASSETS = `cache${timestamp}`;
|
||||||
|
|
||||||
|
// `shell` is an array of all the files generated by the bundler,
|
||||||
|
// `files` is an array of everything in the `static` directory
|
||||||
|
const to_cache = shell.concat(files);
|
||||||
|
const cached = new Set(to_cache);
|
||||||
|
|
||||||
|
self.addEventListener('install', event => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches
|
||||||
|
.open(ASSETS)
|
||||||
|
.then(cache => cache.addAll(to_cache))
|
||||||
|
.then(() => {
|
||||||
|
self.skipWaiting();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', event => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then(async keys => {
|
||||||
|
// delete old caches
|
||||||
|
for (const key of keys) {
|
||||||
|
if (key !== ASSETS) await caches.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.clients.claim();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', event => {
|
||||||
|
if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
|
||||||
|
|
||||||
|
const url = new URL(event.request.url);
|
||||||
|
|
||||||
|
// 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 static files and bundler-generated assets from cache
|
||||||
|
if (url.host === self.location.host && cached.has(url.pathname)) {
|
||||||
|
event.respondWith(caches.match(event.request));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for pages, you might want to serve a shell `service-worker-index.html` file,
|
||||||
|
// which Sapper has generated for you. It's not right for every
|
||||||
|
// app, but if it's right for yours then uncomment this section
|
||||||
|
/*
|
||||||
|
if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
|
||||||
|
event.respondWith(caches.match('/service-worker-index.html'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (event.request.cache === 'only-if-cached') return;
|
||||||
|
|
||||||
|
// for everything else, try the network first, falling back to
|
||||||
|
// cache if the user is offline. (If the pages never change, you
|
||||||
|
// might prefer a cache-first approach to a network-first one.)
|
||||||
|
event.respondWith(
|
||||||
|
caches
|
||||||
|
.open(`offline${timestamp}`)
|
||||||
|
.then(async cache => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(event.request);
|
||||||
|
cache.put(event.request, response.clone());
|
||||||
|
return response;
|
||||||
|
} catch(err) {
|
||||||
|
const response = await cache.match(event.request);
|
||||||
|
if (response) return response;
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
33
examples/sapper/src/template.html
Normal file
33
examples/sapper/src/template.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="shortcut icon" href="/favicon.ico" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
|
<title>sapper</title>
|
||||||
|
|
||||||
|
%sapper.base%
|
||||||
|
|
||||||
|
<!-- Sapper creates a <script> tag containing `src/client.js`
|
||||||
|
and anything else it needs to hydrate the app and
|
||||||
|
initialise the router -->
|
||||||
|
%sapper.scripts%
|
||||||
|
|
||||||
|
<!-- Sapper generates a <style> tag containing critical CSS
|
||||||
|
for the current page. CSS for the rest of the app is
|
||||||
|
lazily loaded when it precaches secondary pages -->
|
||||||
|
%sapper.styles%
|
||||||
|
|
||||||
|
<!-- This contains the contents of the <svelte:head> component, if
|
||||||
|
the current page has one -->
|
||||||
|
%sapper.head%
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- The application will be rendered inside this element,
|
||||||
|
because `src/client.js` references it -->
|
||||||
|
<div id="sapper">%sapper.html%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
examples/sapper/static/favicon.ico
Normal file
BIN
examples/sapper/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
2039
examples/sapper/yarn.lock
Normal file
2039
examples/sapper/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue