feat: add service worker

pull/13/head
moonrailgun 4 years ago
parent cf5ee30ce8
commit 0e3a2ece69

@ -1,5 +1,7 @@
{
"k10c018fe": "Teamwork",
"k1141d649": "Version update",
"k131598d0": "A new version is detected, whether to refresh immediately to upgrade to the latest content",
"k162e37f1": "Plugin is successfully uninstalled, and it needs to be restarted to take effect",
"k1704ea49": "Install",
"k1885734a": "Effective after refreshing the page",
@ -10,6 +12,7 @@
"k2426e452": "Friend Service",
"k2488f9ee": "Friend Request",
"k249e23b9": "E-mail format is incorrect",
"k24ccd723": "Refresh now",
"k267cc491": "Me",
"k2d6cfb27": "Chat Channel",
"k3172297b": "This feature is not yet open",

@ -1,5 +1,7 @@
{
"k10c018fe": "工作协同",
"k1141d649": "更新版本",
"k131598d0": "检测到有新版本, 是否立即刷新以升级到最新内容",
"k162e37f1": "插件卸载成功, 需要重启后生效",
"k1704ea49": "安装",
"k1885734a": "刷新页面后生效",
@ -10,6 +12,7 @@
"k2426e452": "好友服务",
"k2488f9ee": "申请好友",
"k249e23b9": "邮箱格式不正确",
"k24ccd723": "立即刷新",
"k267cc491": "我",
"k2d6cfb27": "聊天频道",
"k3172297b": "该功能暂未开放",

@ -53,6 +53,7 @@
"@types/react-transition-group": "^4.4.2",
"@types/webpack": "^5.28.0",
"@types/webpack-dev-server": "^3.11.4",
"@types/workbox-webpack-plugin": "^5.1.8",
"autoprefixer": "^10.2.6",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^7.0.3",
@ -75,6 +76,7 @@
"url-loader": "^4.1.1",
"webpack": "^5.41.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
"webpack-dev-server": "^3.11.2",
"workbox-webpack-plugin": "^6.3.0"
}
}

@ -0,0 +1,21 @@
import React from 'react';
import { Button, Space } from 'antd';
import { t } from 'tailchat-shared';
/**
* sw
*/
export const UpdateNotificationBtn: React.FC = React.memo(() => {
return (
<Space>
<Button
type="primary"
size="small"
onClick={() => window.location.reload()}
>
{t('立即刷新')}
</Button>
</Space>
);
});
UpdateNotificationBtn.displayName = 'UpdateNotificationBtn';

@ -5,6 +5,9 @@ import ReactDOM from 'react-dom';
import { App } from './App';
import { initPlugins } from './plugin/loader';
import './styles';
import { installServiceWorker } from './utils/sw-helper';
installServiceWorker();
// 先加载插件再开启应用
initPlugins().then(() => {

@ -0,0 +1,77 @@
import { notification } from 'antd';
import React from 'react';
import _once from 'lodash/once';
import { t } from 'tailchat-shared';
import { UpdateNotificationBtn } from '@/components/UpdateNotificationBtn';
/**
*
*/
const handleShowUpdateTip = _once(() => {
setTimeout(() => {
// 两秒后再弹出以确保不会出现加载到一半的情况
notification.open({
message: t('更新版本'),
description: t('检测到有新版本, 是否立即刷新以升级到最新内容'),
duration: 0,
btn: React.createElement(UpdateNotificationBtn),
});
}, 2000);
});
/**
* registration
*/
function handleRegistration(registration: ServiceWorkerRegistration) {
console.log('registered', registration);
if (registration.waiting) {
console.log('updated', registration);
handleShowUpdateTip();
return;
}
registration.onupdatefound = () => {
console.log('updatefound', registration);
const installingWorker = registration.installing;
if (installingWorker === null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and
// the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is
// available; please refresh." message in your web app.
console.log('updated', registration);
handleShowUpdateTip();
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('cached', registration);
}
}
};
};
}
/**
* ws
*/
export function installServiceWorker() {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js')
.then((registration) => {
console.log('SW registered: ', registration);
handleRegistration(registration);
})
.catch((registrationError) => {
console.log('SW registration failed: ', registrationError);
});
});
}
}

@ -11,6 +11,7 @@ import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import CopyPlugin from 'copy-webpack-plugin';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import fs from 'fs';
import WorkboxPlugin from 'workbox-webpack-plugin';
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
@ -140,6 +141,36 @@ const config: Configuration = {
],
}) as any,
new MiniCssExtractPlugin({ filename: 'styles-[contenthash].css' }),
new WorkboxPlugin.GenerateSW({
// these options encourage the ServiceWorkers to get in there fast
// and not allow any straggling "old" SWs to hang around
clientsClaim: true,
skipWaiting: true,
// Do not precache images
exclude: [/\.(?:png|jpg|jpeg|svg)$/],
// Define runtime caching rules.
runtimeCaching: [
{
// Match any request that ends with .png, .jpg, .jpeg or .svg.
urlPattern: /\.(?:png|jpg|jpeg|svg)$/,
// Apply a cache-first strategy.
handler: 'CacheFirst',
options: {
// Use a custom cache name.
cacheName: 'images',
// Only cache 10 images.
expiration: {
maxEntries: 10,
},
},
},
],
}),
],
};

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save