@extjs/sencha-cmd-linux-32
Version:
Productivity and performance optimization tool for building applications with Sencha Ext JS and Sencha Touch.
79 lines (69 loc) • 3.7 kB
JavaScript
;
const swPrecache = require('sw-precache');
const path = require('path');
const fs = require('fs');
const escapeStringRegexp = require('escape-string-regexp');
/**
* @param {String} buildDir The path to the build directory where the service worker file should be created
* @param {Object} config A config object for sw-precache. In addition to the standard config properties for sw-precache,
* each runtimeCaching entry can also specify a url property, which is the exact url to cache instead of a pattern.
* @return {Promise} resolves to the path to the generated service-worker js file.
*/
module.exports = function extPrecache ({ buildDir, config }) {
config.runtimeCaching = config.runtimeCaching || [];
// convert url (String) to urlPattern (RegExp)
for (let entry of config.runtimeCaching) {
entry.handler = entry.handler || 'networkFirst'; // make network first the default
if (entry.url) {
entry.urlPattern = new RegExp(`${escapeStringRegexp(entry.url)}(\\?|$)`);
delete entry.url;
} else if (entry.urlPattern) {
// convert strings to regular expressions: sw-precache is supposed to do this, but there is a bug.
entry.urlPattern = new RegExp(`${entry.urlPattern}`);
}
}
// the path to the service worker we're going to create
const buildSW = path.join(buildDir, 'service-worker.js');
// this will be stripped from the from of each path to produce the url for caching
config.stripPrefix = buildDir + '/';
// the resources that make up the app shell. These will be precached.
config.staticFileGlobs = (config.staticFileGlobs || []).map(glob => {
return glob;
// return glob.indexOf(buildDir) === 0 ? glob : path.join(buildDir, glob)
})
// Strip off _dc before caching. This allows app.json to be cached (which always has a new _dc on page reload)
// sw-precache does its own cache busting, so the user will never get a stale app shell.
config.ignoreUrlParametersMatching = config.ignoreUrlParametersMatching || /^(_dc|v)$/;
// create the service worker
return swPrecache.write(buildSW, config).then(() => {
let serviceWorkerJS = fs.readFileSync(buildSW, 'utf8');
serviceWorkerJS = serviceWorkerJS.replace(/(\/\/ Runtime cache configuration)/, handlers + '\n$1');
fs.writeFileSync(buildSW, serviceWorkerJS, 'utf8');
return buildSW;
});
};
// Here we replace sw-toolbox's networkFirst handler with one that plays well with Ext JS's standard noCache parameter
// First we attempt to fetch the url from the network as-is. If a response is returned it is cached under a key with the
// noCache param removed so that if the same request is made later when offline with a new noCache value, we can return
// the cached response. Without this all ajax requests would result in a cache miss and the cache would keep growing
// indefinitely.
const handlers = `
function stripNoCache(request) {
var url = request.url.replace(/_dc=\\d+&?/, '');
return new Request(url, request);
}
toolbox.networkFirst = function (request, values, options) {
return toolbox.networkOnly(request, values, options)
.then(function(response) {
var cacheName = (options.cache && options.cache.name) || toolbox.options.cache.name;
// cache response with _dc removed
caches.open(cacheName).then(function(cache) {
cache.put(stripNoCache(request), response)
});
return response.clone();
})
.catch(function(err) {
return caches.match(stripNoCache(request))
});
};
`.trim();