mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 10:45:47 +00:00
feature(cloudcmd) add service worker
This commit is contained in:
parent
58c10e201a
commit
234f7bcac0
6 changed files with 164 additions and 2 deletions
10
.babelrc
10
.babelrc
|
|
@ -1,10 +1,16 @@
|
|||
{
|
||||
"presets": [
|
||||
"env"
|
||||
["env", {
|
||||
"exclude": [
|
||||
"transform-regenerator"
|
||||
]
|
||||
}]
|
||||
],
|
||||
"plugins": [
|
||||
"transform-object-assign",
|
||||
"transform-object-rest-spread"
|
||||
"transform-object-rest-spread",
|
||||
"fast-async",
|
||||
"babel-plugin-macros",
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ const {
|
|||
join,
|
||||
} = require('path');
|
||||
|
||||
const {
|
||||
EnvironmentPlugin,
|
||||
} = require('webpack');
|
||||
|
||||
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
|
||||
|
||||
const dir = './client';
|
||||
const dirModules = './client/modules';
|
||||
const modules = './modules';
|
||||
|
|
@ -21,13 +27,33 @@ const devtool = isDev ? 'eval' : 'source-map';
|
|||
const notEmpty = (a) => a;
|
||||
const clean = (array) => array.filter(notEmpty);
|
||||
|
||||
const babelDev = {
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
'babel-plugin-macros',
|
||||
]
|
||||
};
|
||||
|
||||
const rules = clean([
|
||||
!isDev && {
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
isDev && {
|
||||
test: /sw.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'babel-loader',
|
||||
options: babelDev
|
||||
}]);
|
||||
|
||||
const plugins = [
|
||||
new EnvironmentPlugin(['NODE_ENV']),
|
||||
new ServiceWorkerWebpackPlugin({
|
||||
entry: join(__dirname, '../client', 'sw.js'),
|
||||
}),
|
||||
];
|
||||
|
||||
const splitChunks = {
|
||||
chunks: 'all',
|
||||
name: 'cloudcmd.common',
|
||||
|
|
@ -40,6 +66,7 @@ module.exports = {
|
|||
},
|
||||
entry: {
|
||||
cloudcmd: `${dir}/cloudcmd.js`,
|
||||
//[sw]: `${dir}/sw.js`,
|
||||
[modules + '/edit']: `${dirModules}/edit.js`,
|
||||
[modules + '/edit-file']: `${dirModules}/edit-file.js`,
|
||||
[modules + '/edit-file-vim']: `${dirModules}/edit-file-vim.js`,
|
||||
|
|
@ -70,6 +97,7 @@ module.exports = {
|
|||
module: {
|
||||
rules,
|
||||
},
|
||||
plugins,
|
||||
};
|
||||
|
||||
function externals(context, request, fn) {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ const join = require('join-io/www/join');
|
|||
const jonny = require('jonny/legacy');
|
||||
const currify = require('currify/legacy');
|
||||
|
||||
const runtime = require('serviceworker-webpack-plugin/lib/runtime');
|
||||
|
||||
const bind = (f, ...a) => () => f(...a);
|
||||
const noop = () => {};
|
||||
|
||||
|
|
@ -39,6 +41,8 @@ function CloudCmdProto(Util, DOM) {
|
|||
console.log(str);
|
||||
};
|
||||
|
||||
serviceWorker();
|
||||
|
||||
Emitify.call(this);
|
||||
|
||||
const CloudCmd = this;
|
||||
|
|
@ -607,5 +611,18 @@ function CloudCmdProto(Util, DOM) {
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
function serviceWorker() {
|
||||
if (!navigator.serviceWorker)
|
||||
return;
|
||||
|
||||
const isHTTPS = location.protocol === 'https:';
|
||||
const isLocalhost = location.hostname === 'localhost';
|
||||
|
||||
if (!isHTTPS && !isLocalhost)
|
||||
return;
|
||||
|
||||
runtime.register();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
89
client/sw.js
Normal file
89
client/sw.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
'use strict';
|
||||
|
||||
const preval = require('preval.macro');
|
||||
const tryToCatch = require('try-to-catch/legacy');
|
||||
const currify = require('currify/legacy');
|
||||
|
||||
const wait = currify((f, e) => e.waitUntil(f()));
|
||||
const respondWith = currify((f, e) => e.respondWith(f(e)));
|
||||
const getPathName = (url) => new URL(url).pathname;
|
||||
|
||||
const date = preval`module.exports = Date()`;
|
||||
const NAME = `cloudcmd: ${date}`;
|
||||
|
||||
const isGet = (a) => a.method === 'GET';
|
||||
const isBasic = (a) => a.type === 'basic';
|
||||
|
||||
const createRequest = (a) => new Request(a, {
|
||||
credentials: 'same-origin'
|
||||
});
|
||||
|
||||
self.addEventListener('install', wait(onInstall));
|
||||
self.addEventListener('fetch', respondWith(onFetch));
|
||||
self.addEventListener('activate', wait(onActivate));
|
||||
|
||||
async function onActivate() {
|
||||
console.info(`cloudcmd: sw: activate: ${NAME}`);
|
||||
|
||||
await self.clients.claim();
|
||||
const keys = await caches.keys();
|
||||
const deleteCache = caches.delete.bind(caches);
|
||||
|
||||
await Promise.all(keys.map(deleteCache));
|
||||
}
|
||||
|
||||
async function onInstall() {
|
||||
console.info(`cloudcmd: sw: install: ${NAME}`);
|
||||
|
||||
await self.skipWaiting();
|
||||
|
||||
const cache = await caches.open(NAME);
|
||||
|
||||
const urls = [
|
||||
'/favicon.ico',
|
||||
];
|
||||
|
||||
const requests = urls.map(createRequest);
|
||||
|
||||
return cache.addAll(requests);
|
||||
}
|
||||
|
||||
async function onFetch(event) {
|
||||
const {request} = event;
|
||||
const url = request.url;
|
||||
const pathname = getPathName(url);
|
||||
|
||||
const cache = await caches.open(NAME);
|
||||
const response = await cache.match(request);
|
||||
|
||||
if (response)
|
||||
return response;
|
||||
|
||||
const [e, resp] = await tryToCatch(fetch, request.clone());
|
||||
|
||||
if (e)
|
||||
return console.error(e);
|
||||
|
||||
if (!isGet(request) || !resp.ok || !isBasic(resp))
|
||||
return resp;
|
||||
|
||||
if (/^\/$/.test(pathname))
|
||||
return resp;
|
||||
|
||||
if (/^\/api/.test(pathname))
|
||||
return resp;
|
||||
|
||||
if (/^socket.io/.test(pathname))
|
||||
return resp;
|
||||
|
||||
await addToCache(request, resp.clone());
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
async function addToCache(request, response) {
|
||||
const cache = await caches.open(NAME);
|
||||
|
||||
cache.put(request, response);
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +159,7 @@
|
|||
"@cloudcmd/clipboard": "^1.0.0",
|
||||
"babel-cli": "^6.18.0",
|
||||
"babel-loader": "^7.0.0",
|
||||
"babel-plugin-macros": "^2.2.1",
|
||||
"babel-plugin-transform-object-assign": "^6.22.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
|
|
@ -171,6 +172,7 @@
|
|||
"eslint": "^4.0.0",
|
||||
"eslint-plugin-node": "^6.0.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-alpha.0",
|
||||
"fast-async": "^6.3.7",
|
||||
"file-loader": "^1.1.4",
|
||||
"gritty": "^2.2.0",
|
||||
"gunzip-maybe": "^1.3.1",
|
||||
|
|
@ -188,10 +190,12 @@
|
|||
"nyc": "^11.0.2",
|
||||
"philip": "^2.0.0",
|
||||
"place": "^1.1.4",
|
||||
"preval.macro": "^1.0.2",
|
||||
"readjson": "^1.1.3",
|
||||
"redrun": "^6.0.0",
|
||||
"request": "^2.76.0",
|
||||
"rimraf": "^2.5.4",
|
||||
"serviceworker-webpack-plugin": "1.0.0-alpha02",
|
||||
"shortdate": "^1.0.1",
|
||||
"sinon": "^5.0.1",
|
||||
"sinon-called-with-diff": "^2.0.0",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ const defaultHtml = fs.readFileSync(getIndexPath(isDev), 'utf8');
|
|||
|
||||
const auth = currify(_auth);
|
||||
const setUrl = currify(_setUrl);
|
||||
const setSW = currify(_setSW);
|
||||
|
||||
const root = () => config('root');
|
||||
|
||||
|
|
@ -208,6 +209,7 @@ function cloudcmd(prefix, plugins, modules) {
|
|||
}),
|
||||
|
||||
setUrl(prefix),
|
||||
setSW(prefix),
|
||||
logout,
|
||||
authentication(),
|
||||
config.middle,
|
||||
|
|
@ -272,6 +274,22 @@ function _setUrl(pref, req, res, next) {
|
|||
next();
|
||||
}
|
||||
|
||||
function _setSW(pref, req, res, next) {
|
||||
const prefix = getPrefix(pref);
|
||||
const is = !req.url.indexOf(prefix);
|
||||
|
||||
if (!is)
|
||||
return next();
|
||||
|
||||
const url = replacePrefix(req.url, prefix);
|
||||
const isSW = /^\/sw\.js(\.map)?$/.test(url);
|
||||
|
||||
if (isSW)
|
||||
req.url = replaceDist(`/dist${url}`);
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
function checkPlugins(plugins) {
|
||||
if (typeof plugins === 'undefined')
|
||||
return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue