WIP: Добавляет поддержку PWA #10
@ -22,15 +22,14 @@ module.exports = (eleventyConfig) => {
|
|||||||
mkdirSync('dist/css', { recursive: true })
|
mkdirSync('dist/css', { recursive: true })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
eleventyConfig.addPassthroughCopy('./src/fonts/')
|
|
||||||
|
|
||||||
eleventyConfig.addPlugin(svgContents)
|
eleventyConfig.addPlugin(svgContents)
|
||||||
eleventyConfig.addPlugin(faviconPlugin, {
|
eleventyConfig.addPlugin(faviconPlugin, {
|
||||||
destination: './dist'
|
destination: './dist'
|
||||||
})
|
})
|
||||||
|
|
||||||
eleventyConfig.addPlugin(syntaxHighlight)
|
eleventyConfig.addPlugin(syntaxHighlight)
|
||||||
|
eleventyConfig.addPlugin(require('./plugins/manifest-icons'))
|
||||||
|
|
||||||
|
eleventyConfig.addPassthroughCopy('./src/fonts/')
|
||||||
|
|
||||||
eleventyConfig.addCollection('notes', function (collectionApi) {
|
eleventyConfig.addCollection('notes', function (collectionApi) {
|
||||||
return collectionApi.getFilteredByGlob('src/notes/**/*.md')
|
return collectionApi.getFilteredByGlob('src/notes/**/*.md')
|
||||||
|
2995
package-lock.json
generated
2995
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
|||||||
"start": "npx @11t/eleventy --serve",
|
"start": "npx @11t/eleventy --serve",
|
||||||
"prebuild": "node ./scripts/symlink.js",
|
"prebuild": "node ./scripts/symlink.js",
|
||||||
"build": "cross-env NODE_ENV=production npx @11t/eleventy",
|
"build": "cross-env NODE_ENV=production npx @11t/eleventy",
|
||||||
|
"build:sw": "workbox generateSW workbox-config.js",
|
||||||
"stylelint": "stylelint 'src/**/*.css'",
|
"stylelint": "stylelint 'src/**/*.css'",
|
||||||
"eslint": "eslint src"
|
"eslint": "eslint src"
|
||||||
},
|
},
|
||||||
@ -30,10 +31,13 @@
|
|||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.28.0",
|
||||||
"rollup": "^2.72.1",
|
"rollup": "^2.72.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
|
"rollup-plugin-workbox": "^6.2.0",
|
||||||
"simple-git-hooks": "^2.7.0",
|
"simple-git-hooks": "^2.7.0",
|
||||||
"stylelint": "^14.8.2",
|
"stylelint": "^14.8.2",
|
||||||
"stylelint-config-standard": "^25.0.0",
|
"stylelint-config-standard": "^25.0.0",
|
||||||
"tailwindcss": "^3.0.24"
|
"tailwindcss": "^3.0.24",
|
||||||
|
"workbox-build": "^6.5.3",
|
||||||
|
"workbox-cli": "^6.5.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"alpinejs": "^3.10.2",
|
"alpinejs": "^3.10.2",
|
||||||
|
38
plugins/manifest-icons/index.js
Normal file
38
plugins/manifest-icons/index.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
const sharp = require('sharp')
|
||||||
|
const fs = require('fs').promises
|
||||||
|
const getDirName = require('path').dirname
|
||||||
|
|
||||||
|
async function writeFile (path, contents, cb) {
|
||||||
|
await fs.mkdir(getDirName(path), { recursive: true })
|
||||||
|
fs.writeFile(path, contents, cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePngFavicon ({ density, width, height }, sourcePath, dimension) {
|
||||||
|
return sharp(sourcePath, {
|
||||||
|
density: (dimension / Math.max(width, height)) * density
|
||||||
|
})
|
||||||
|
.resize(dimension, dimension)
|
||||||
|
.png()
|
||||||
|
.toBuffer()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = (eleventyConfig) => {
|
||||||
|
eleventyConfig.addAsyncShortcode('manifest_icons', async function (faviconFile, ...dimensions) {
|
||||||
|
const metadata = await sharp(faviconFile).metadata()
|
||||||
|
|
||||||
|
const res = await Promise.all(dimensions.map(async dimension => {
|
||||||
|
const favicon = await generatePngFavicon(metadata, faviconFile, dimension)
|
||||||
|
writeFile(`dist/icons/${dimension}/favicon.png`, favicon)
|
||||||
|
|
||||||
|
return {
|
||||||
|
src: `/icons/${dimension}/favicon.png`,
|
||||||
|
sizes: `${dimension}x${dimension}`,
|
||||||
|
type: 'image/png'
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
res[res.length - 1].purpose = 'maskable'
|
||||||
|
|
||||||
|
return JSON.stringify(res)
|
||||||
|
})
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
import resolve from '@rollup/plugin-node-resolve'
|
import resolve from '@rollup/plugin-node-resolve'
|
||||||
import { terser } from 'rollup-plugin-terser'
|
import { terser } from 'rollup-plugin-terser'
|
||||||
|
import { injectManifest } from 'rollup-plugin-workbox'
|
||||||
|
|
||||||
|
const workboxConfig = require('./workbox-config')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: 'src/js/index.js',
|
input: 'src/js/index.js',
|
||||||
@ -7,5 +10,9 @@ export default {
|
|||||||
file: 'dist/js/bundle.js',
|
file: 'dist/js/bundle.js',
|
||||||
format: 'esm'
|
format: 'esm'
|
||||||
},
|
},
|
||||||
plugins: [resolve(), terser()]
|
plugins: [
|
||||||
|
injectManifest(workboxConfig),
|
||||||
|
resolve(),
|
||||||
|
terser()
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@ -2,43 +2,33 @@
|
|||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="10mm"
|
width="12.560524mm"
|
||||||
height="10mm"
|
height="12.560524mm"
|
||||||
viewBox="0 0 10 10"
|
viewBox="0 0 12.560524 12.560524"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg1163"
|
id="svg6948"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
<defs
|
<defs
|
||||||
id="defs1160" />
|
id="defs6945" />
|
||||||
<g
|
<g
|
||||||
id="layer1"
|
id="layer1"
|
||||||
transform="translate(-84.492197,-76.648259)">
|
transform="translate(-24.152918,-28.577486)">
|
||||||
<g
|
|
||||||
id="g121725"
|
|
||||||
transform="translate(8.947168,-21.108691)">
|
|
||||||
<rect
|
<rect
|
||||||
style="fill:#333333;stroke-width:0.262137"
|
style="fill:#333333;stroke-width:0.329258"
|
||||||
id="rect94180-7"
|
id="rect94180-7"
|
||||||
width="10"
|
width="12.560524"
|
||||||
height="10"
|
height="12.560524"
|
||||||
x="75.545029"
|
x="24.152918"
|
||||||
y="97.75695"
|
y="28.577486"
|
||||||
ry="1.1785811" />
|
ry="0" />
|
||||||
<path
|
<path
|
||||||
d="m 78.668175,104.34225 q -0.603323,0 -1.092977,-0.13411 -0.480909,-0.14251 -0.856893,-0.40235 -0.375984,-0.26822 -0.673273,-0.62866 l 0.900613,-0.9807 q 0.43719,0.5616 0.874381,0.75439 0.445934,0.19279 0.918099,0.19279 0.236084,0 0.428447,-0.0587 0.192363,-0.0587 0.29729,-0.16766 0.104928,-0.11737 0.104928,-0.28498 0,-0.12574 -0.06995,-0.22632 -0.06119,-0.10068 -0.174876,-0.17602 -0.113673,-0.0754 -0.271058,-0.13411 -0.157387,-0.0672 -0.332265,-0.10893 -0.174875,-0.0502 -0.358496,-0.0837 -0.507141,-0.10892 -0.883125,-0.26824 -0.375983,-0.15926 -0.629555,-0.38556 -0.244826,-0.23471 -0.367239,-0.52808 -0.12241,-0.30177 -0.12241,-0.67059 0,-0.39394 0.183619,-0.720857 0.192364,-0.335277 0.507141,-0.569983 0.323521,-0.243081 0.743224,-0.368817 0.419703,-0.13411 0.87438,-0.13411 0.603324,0 1.03177,0.125735 0.437191,0.117384 0.743225,0.343665 0.314776,0.226317 0.533373,0.544843 l -0.918102,0.846594 q -0.183619,-0.21794 -0.402213,-0.36044 -0.209853,-0.14249 -0.45468,-0.217932 -0.236081,-0.07544 -0.489653,-0.07544 -0.262315,0 -0.454678,0.06713 -0.18362,0.05869 -0.288546,0.176022 -0.104928,0.10895 -0.104928,0.26825 0,0.14249 0.08743,0.24307 0.08743,0.10068 0.236082,0.18441 0.148645,0.0754 0.341009,0.13411 0.192363,0.0502 0.402215,0.0838 0.48091,0.0922 0.865638,0.24307 0.39347,0.15088 0.673273,0.36881 0.288545,0.21793 0.43719,0.51969 0.157389,0.29338 0.157389,0.68733 0,0.6119 -0.314778,1.03938 -0.306032,0.41911 -0.848148,0.64543 -0.533373,0.21793 -1.232879,0.21793 z"
|
d="m 28.811206,36.251169 q -0.525475,0 -0.951947,-0.116806 -0.418856,-0.124121 -0.746326,-0.350433 -0.32747,-0.233611 -0.586399,-0.547543 l 0.784405,-0.854158 q 0.380778,0.489136 0.761557,0.65705 0.388394,0.167913 0.799634,0.167913 0.205622,0 0.373164,-0.05112 0.167542,-0.05113 0.25893,-0.146027 0.09139,-0.102225 0.09139,-0.248208 0,-0.109516 -0.06092,-0.197117 -0.05329,-0.08769 -0.152311,-0.153308 -0.09901,-0.06567 -0.236083,-0.116806 -0.137079,-0.05853 -0.289392,-0.09487 -0.15231,-0.04372 -0.312238,-0.0729 -0.441703,-0.09487 -0.769173,-0.233628 -0.327469,-0.138711 -0.548322,-0.335811 -0.213236,-0.204424 -0.319853,-0.45994 -0.106615,-0.262832 -0.106615,-0.584062 0,-0.343109 0.159926,-0.627843 0.167543,-0.292015 0.441703,-0.496437 0.281776,-0.211715 0.647324,-0.321227 0.365548,-0.116806 0.761556,-0.116806 0.525476,0 0.898639,0.109511 0.380779,0.102238 0.647324,0.299321 0.27416,0.197115 0.464551,0.474541 l -0.799637,0.737356 q -0.159926,-0.189819 -0.350315,-0.313932 -0.182775,-0.124104 -0.396011,-0.189811 -0.205619,-0.06571 -0.426472,-0.06571 -0.228468,0 -0.39601,0.05847 -0.159927,0.05112 -0.251314,0.153309 -0.09139,0.09489 -0.09139,0.233637 0,0.124104 0.07615,0.211706 0.07615,0.08769 0.20562,0.160615 0.129465,0.06567 0.297008,0.116806 0.167541,0.04372 0.350316,0.07299 0.418857,0.0803 0.753942,0.211706 0.3427,0.131412 0.586399,0.321221 0.251313,0.18981 0.380778,0.452634 0.137081,0.255524 0.137081,0.598642 0,0.532945 -0.274161,0.905266 -0.266544,0.365031 -0.73871,0.562148 -0.46455,0.18981 -1.073797,0.18981 z"
|
||||||
style="font-weight:bold;font-size:10.5833px;line-height:1.25;font-family:'Lexend Deca';-inkscape-font-specification:'Lexend Deca Bold';fill:#999999;stroke-width:0.214026"
|
style="font-weight:bold;font-size:10.5833px;line-height:1.25;font-family:'Lexend Deca';-inkscape-font-specification:'Lexend Deca Bold';fill:#999999;stroke-width:0.18641"
|
||||||
id="path96539-9" />
|
id="path96539-9" />
|
||||||
<text
|
<path
|
||||||
xml:space="preserve"
|
d="M 29.407328,38.764371 28.069052,34.30345 h 1.102485 l 0.669139,2.345176 q 0.04461,0.159317 0.07647,0.32501 0.03824,0.159318 0.05735,0.305884 0.02549,0.146575 0.03824,0.274033 0.01274,0.121081 0.02549,0.203928 h -0.1402 q 0.03824,-0.235788 0.06373,-0.420599 0.03186,-0.184811 0.0701,-0.344128 0.03824,-0.165693 0.09559,-0.344128 l 0.662766,-1.765251 h 0.866694 l 0.65002,1.765251 q 0.07647,0.210295 0.127455,0.395106 0.05099,0.18481 0.07647,0.356879 0.03186,0.165684 0.05098,0.331377 l -0.127455,0.01916 q 0.01274,-0.114707 0.01912,-0.210295 0.0064,-0.101964 0.01274,-0.191186 0.01274,-0.09559 0.02549,-0.197553 0.01274,-0.101964 0.03824,-0.223046 0.02549,-0.127458 0.0701,-0.286775 l 0.662766,-2.3388 h 1.076994 l -1.338277,4.460921 h -0.828456 l -1.057876,-2.568213 0.121082,0.01272 -0.97503,2.555471 z"
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:7.31686px;line-height:1.25;font-family:'Lexend Deca';-inkscape-font-specification:'Lexend Deca Bold';fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:0.182922"
|
id="path6768"
|
||||||
x="77.786804"
|
style="font-weight:bold;font-size:7.31686px;line-height:1.25;font-family:'Lexend Deca';-inkscape-font-specification:'Lexend Deca Bold';fill:#f9f9f9;stroke-width:0.159319" />
|
||||||
y="107.22778"
|
|
||||||
id="text107851"><tspan
|
|
||||||
id="tspan107849"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Lexend Deca';-inkscape-font-specification:'Lexend Deca Bold';fill:#f9f9f9;stroke-width:0.182922"
|
|
||||||
x="77.786804"
|
|
||||||
y="107.22778">W</tspan></text>
|
|
||||||
</g>
|
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.3 KiB |
@ -4,4 +4,6 @@ import Fuse from 'fuse.js'
|
|||||||
window.Fuse = Fuse
|
window.Fuse = Fuse
|
||||||
window.Alpine = Alpine
|
window.Alpine = Alpine
|
||||||
|
|
||||||
|
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') }
|
||||||
|
|
||||||
Alpine.start()
|
Alpine.start()
|
||||||
|
58
src/js/sw.js
Normal file
58
src/js/sw.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* global self, caches */
|
||||||
|
import { precacheAndRoute } from 'workbox-precaching'
|
||||||
|
|
||||||
|
precacheAndRoute(self.__WB_MANIFEST)
|
||||||
|
|
||||||
|
const CACHE_NAME = 'static-v2'
|
||||||
|
const OFFLINE_URL = 'offline.html'
|
||||||
|
|
||||||
|
self.addEventListener('install', event => {
|
||||||
|
console.log('Install!')
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(CACHE_NAME).then(cache => {
|
||||||
|
return cache.addAll([
|
||||||
|
'/',
|
||||||
|
'/js/bundle.js',
|
||||||
|
'/css/index.css',
|
||||||
|
'/fonts/OpenSans-Bold.ttf',
|
||||||
|
'/fonts/OpenSans-Bold.woff',
|
||||||
|
'/fonts/OpenSans-Bold.woff2',
|
||||||
|
'/fonts/OpenSans-Regular.ttf',
|
||||||
|
'/fonts/OpenSans-Regular.woff',
|
||||||
|
'/fonts/OpenSans-Regular.woff2',
|
||||||
|
'/favicon.ico',
|
||||||
|
'/favicon.svg',
|
||||||
|
OFFLINE_URL
|
||||||
|
])
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
self.skipWaiting()
|
||||||
|
})
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
// Нам нужно вызвать функцию event.respondWith(), только если это запрос на переход между
|
||||||
|
// HTML-страницами.
|
||||||
|
if (event.request.mode === 'navigate') {
|
||||||
|
event.respondWith(
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const preloadResponse = await event.preloadResponse
|
||||||
|
if (preloadResponse) {
|
||||||
|
return preloadResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
const networkResponse = await fetch(event.request)
|
||||||
|
return networkResponse
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Не удалось получить данные; вместо этого возвращаем страницу для автономного режима.', error)
|
||||||
|
|
||||||
|
const cache = await caches.open(CACHE_NAME)
|
||||||
|
const cachedResponse = await cache.match(OFFLINE_URL)
|
||||||
|
return cachedResponse
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -6,6 +6,8 @@
|
|||||||
<title>{{ title or metadata.title }}</title>
|
<title>{{ title or metadata.title }}</title>
|
||||||
<meta name="description" content="{{ description or metadata.description }}">
|
<meta name="description" content="{{ description or metadata.description }}">
|
||||||
<meta name="generator" content="{{ eleventy.generator }}">
|
<meta name="generator" content="{{ eleventy.generator }}">
|
||||||
|
<meta name="theme-color" content="#fff"/>
|
||||||
|
<link rel="manifest" href="/manifest.json">
|
||||||
<link rel="stylesheet" href="/css/index.css">
|
<link rel="stylesheet" href="/css/index.css">
|
||||||
{% favicon 'src/images/favicon.svg' %}
|
{% favicon 'src/images/favicon.svg' %}
|
||||||
</head>
|
</head>
|
||||||
|
3
src/pages/manifset.11tydata.js
Normal file
3
src/pages/manifset.11tydata.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
permalink: '/manifest.json'
|
||||||
|
}
|
10
src/pages/manifset.njk
Normal file
10
src/pages/manifset.njk
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "{{ metadata.title }}",
|
||||||
|
"lang": "ru",
|
||||||
|
"start_url": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"background_color": "#fff",
|
||||||
|
"theme_color": "#fff",
|
||||||
|
"description": "Вики с различными полезными статьями",
|
||||||
|
"icons": {% manifest_icons 'src/images/favicon.svg', 48, 72, 96, 144, 148, 512 %}
|
||||||
|
}
|
@ -1,4 +1,7 @@
|
|||||||
<main>
|
<main>
|
||||||
|
<a href="/" class="block p-1 rounded-xl">
|
||||||
|
{{ '/src/images/logo.svg' | svgContents("max-h-12 block w-[50vw]") | safe }}
|
||||||
|
</a>
|
||||||
<article class="article-content">
|
<article class="article-content">
|
||||||
<h1>{{ note.data.title | safe }}</h1>
|
<h1>{{ note.data.title | safe }}</h1>
|
||||||
{{ note.templateContent | safe }}
|
{{ note.templateContent | safe }}
|
||||||
|
5
src/pages/offline.11tydata.js
Normal file
5
src/pages/offline.11tydata.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
layout: 'base.njk',
|
||||||
|
|
||||||
|
permalink: '/offline.html'
|
||||||
|
}
|
2
src/pages/offline.njk
Normal file
2
src/pages/offline.njk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<h1>Отсутствует подключение к сети</h1>
|
||||||
|
<a href="/">Вернуться на главную</a>
|
10
workbox-config.js
Normal file
10
workbox-config.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
globDirectory: 'dist/',
|
||||||
|
globPatterns: [
|
||||||
|
'**/*.{png,css,ico,svg,ttf,woff,woff2,js,json}',
|
||||||
|
'index.html'
|
||||||
|
],
|
||||||
|
swSrc: 'src/js/sw.js',
|
||||||
|
swDest: 'dist/sw.js',
|
||||||
|
mode: 'production'
|
||||||
|
}
|
Reference in New Issue
Block a user