Переглянути джерело

feat: Setup PWA for frontend

Owen Diffey 2 роки тому
батько
коміт
329224a8c7

+ 1 - 0
.gitignore

@@ -29,6 +29,7 @@ frontend/bundle-report.html
 frontend/node_modules/
 frontend/build/
 frontend/src/coverage/
+frontend/dev-dist/
 
 npm
 node_modules

+ 3 - 0
frontend/dev.nginx.conf

@@ -7,6 +7,9 @@ events {
 http {
     include /etc/nginx/mime.types;
     default_type application/octet-stream;
+    types {
+        application/manifest+json  webmanifest;
+    }
 
     sendfile off;
 

+ 0 - 41
frontend/dist/assets/favicon/manifest.json

@@ -1,41 +0,0 @@
-{
-	"name": "Musare",
-	"icons": [
-		{
-			"src": "\/assets/favicon/android-chrome-36x36.png?v=06042016",
-			"sizes": "36x36",
-			"type": "image\/png",
-			"density": 0.75
-		},
-		{
-			"src": "\/assets/favicon/android-chrome-48x48.png?v=06042016",
-			"sizes": "48x48",
-			"type": "image\/png",
-			"density": 1
-		},
-		{
-			"src": "\/assets/favicon/android-chrome-72x72.png?v=06042016",
-			"sizes": "72x72",
-			"type": "image\/png",
-			"density": 1.5
-		},
-		{
-			"src": "\/assets/favicon/android-chrome-96x96.png?v=06042016",
-			"sizes": "96x96",
-			"type": "image\/png",
-			"density": 2
-		},
-		{
-			"src": "\/assets/favicon/android-chrome-144x144.png?v=06042016",
-			"sizes": "144x144",
-			"type": "image\/png",
-			"density": 3
-		},
-		{
-			"src": "\/assets/favicon/android-chrome-192x192.png?v=06042016",
-			"sizes": "192x192",
-			"type": "image\/png",
-			"density": 4
-		}
-	]
-}

Різницю між файлами не показано, бо вона завелика
+ 4079 - 806
frontend/package-lock.json


+ 1 - 0
frontend/package.json

@@ -37,6 +37,7 @@
     "less": "^4.1.3",
     "prettier": "^2.8.4",
     "vite-plugin-dynamic-import": "^1.2.7",
+    "vite-plugin-pwa": "^0.14.7",
     "vitest": "^0.29.2",
     "vue-eslint-parser": "^9.1.0",
     "vue-tsc": "^1.2.0"

+ 9 - 0
frontend/prod.nginx.conf

@@ -7,6 +7,9 @@ events {
 http {
     include /etc/nginx/mime.types;
     default_type application/octet-stream;
+    types {
+        application/manifest+json  webmanifest;
+    }
 
     sendfile off;
 
@@ -18,6 +21,12 @@ http {
 
         root /opt/app/build;
 
+        # all workbox scripts are compiled with hash in filename, cache forever
+        location ^~ /workbox- {
+            add_header Cache-Control "public, max-age=31536000, s-maxage=31536000, immutable";
+            try_files $uri =404;
+        }
+
         location / {
             try_files $uri /$uri /index.html =404;
         }

+ 0 - 1
frontend/src/index.html

@@ -97,7 +97,6 @@
 			href="/assets/favicon/favicon-16x16.png?v=06042016"
 			sizes="16x16"
 		/>
-		<link rel="manifest" href="/assets/favicon/manifest.json?v=06042016" />
 		<link
 			rel="mask-icon"
 			href="/assets/favicon/safari-pinned-tab.svg?v=06042016"

+ 2 - 1
frontend/tsconfig.json

@@ -20,7 +20,8 @@
     "types": [
       "vite/client",
       "@intlify/unplugin-vue-i18n/messages",
-      "vitest/globals"
+      "vitest/globals",
+      "vite-plugin-pwa/client"
     ],
     "strict": false,
     "allowSyntheticDefaultImports": true

+ 61 - 8
frontend/vite.config.js

@@ -2,6 +2,7 @@ import path from "path";
 import vue from "@vitejs/plugin-vue";
 import dynamicImport from "vite-plugin-dynamic-import";
 import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
+import { VitePWA } from "vite-plugin-pwa";
 import fs from "fs";
 
 const fetchVersionAndGitInfo = () => {
@@ -97,15 +98,14 @@ const fetchVersionAndGitInfo = () => {
 
 const debug = fetchVersionAndGitInfo();
 
+const sitename = process.env.MUSARE_SITENAME ?? "Musare";
+
 const htmlPlugin = () => ({
 	name: "html-transform",
 	transformIndexHtml(originalHtml) {
 		let html = originalHtml;
 
-		html = html.replace(
-			/{{ title }}/g,
-			process.env.MUSARE_SITENAME ?? "Musare"
-		);
+		html = html.replace(/{{ title }}/g, sitename);
 		html = html.replace(/{{ version }}/g, debug.version);
 		html = html.replace(/{{ gitRemote }}/g, debug.git.remote);
 		html = html.replace(/{{ gitRemoteUrl }}/g, debug.git.remoteUrl);
@@ -161,9 +161,7 @@ export default {
 	},
 	define: {
 		__VUE_PROD_DEVTOOLS__: process.env.FRONTEND_PROD_DEVTOOLS === "true",
-		MUSARE_SITENAME: JSON.stringify(
-			process.env.MUSARE_SITENAME ?? "Musare"
-		),
+		MUSARE_SITENAME: JSON.stringify(sitename),
 		MUSARE_VERSION: JSON.stringify(debug.version),
 		MUSARE_GIT_REMOTE: JSON.stringify(debug.git.remote),
 		MUSARE_GIT_REMOTE_URL: JSON.stringify(debug.git.remoteUrl),
@@ -178,7 +176,62 @@ export default {
 		vue(),
 		htmlPlugin(),
 		dynamicImport(),
-		VueI18nPlugin({ include: path.resolve(__dirname, "src/locales/**") })
+		VueI18nPlugin({ include: path.resolve(__dirname, "src/locales/**") }),
+		VitePWA({
+			useCredentials: true,
+			devOptions: {
+				enabled: true,
+				type: "module",
+				navigateFallback: "index.html",
+				resolveTempFolder: () => path.resolve(__dirname, "dev-dist")
+			},
+			manifest: {
+				name: sitename,
+				short_name: sitename,
+				theme_color: "#03a9f4",
+				display: "standalone",
+				start_url: "/",
+				id: "/",
+				icons: [
+					{
+						src: "/assets/favicon/android-chrome-36x36.png?v=06042016",
+						sizes: "36x36",
+						type: "image/png",
+						density: 0.75
+					},
+					{
+						src: "/assets/favicon/android-chrome-48x48.png?v=06042016",
+						sizes: "48x48",
+						type: "image/png",
+						density: 1
+					},
+					{
+						src: "/assets/favicon/android-chrome-72x72.png?v=06042016",
+						sizes: "72x72",
+						type: "image/png",
+						density: 1.5
+					},
+					{
+						src: "/assets/favicon/android-chrome-96x96.png?v=06042016",
+						sizes: "96x96",
+						type: "image/png",
+						density: 2
+					},
+					{
+						src: "/assets/favicon/android-chrome-144x144.png?v=06042016",
+						sizes: "144x144",
+						type: "image/png",
+						density: 3
+					},
+					{
+						src: "/assets/favicon/android-chrome-192x192.png?v=06042016",
+						sizes: "192x192",
+						type: "image/png",
+						density: 4
+					}
+				]
+			}
+		})
 	],
 	css: {
 		preprocessorOptions: {

Деякі файли не було показано, через те що забагато файлів було змінено