[英]How to use a Service Worker to cache a virtual file?
I am attempting to implement a service worker for a boilerplate project I'm working on ( https://github.com/jonnyasmar/gravity-bp feedback welcome!), but I've hit a snag :( 我正在尝试为我正在研究的样板项目实施服务工作者( https://github.com/jonnyasmar/gravity-bp反馈欢迎!),但我遇到了一个障碍:(
I'm serving the index.html
for this boilerplate virtually as an interpreted Twig template via ExpressJS. 我实际上是通过ExpressJS作为解释的Twig模板为该样板提供
index.html
的。 However, because I'm generating the service worker assets at build time and that is where I'm pointing it to the cacheable static assets, I can't figure out how to tell the service worker that I want it to cache the virtual index.html
file served by ExpressJS at runtime. 但是,由于我是在构建时生成服务工作者资产的,因此我将其指向可缓存的静态资产,因此我无法弄清楚如何告诉服务工作者我要其缓存虚拟
index.html
ExpressJS在运行时提供的index.html
文件。
My most successful attempts successfully cache all static assets (including the asset-manifest.json
generated at build time), but will not cache a virtual index.html
. 我最成功的尝试成功地缓存了所有静态资产(包括在构建时生成的
asset-manifest.json
),但不会缓存虚拟index.html
。
If I convert it to a static html file, the service worker does successfully cache it. 如果我将其转换为静态html文件,则服务工作者确实会成功缓存它。
webpack.config.js
: webpack.config.js
: output: {
filename: '[name].js',
chunkFilename: '[chunkhash].js',
path: path.resolve(__dirname, 'public'),
publicPath: '/'
},
plugins: {
new ManifestPlugin({
fileName: 'asset-manifest.json',
}),
new SWPrecacheWebpackPlugin({
cacheId: 'gravity-bp',
dontCacheBustUrlsMatching: /\.\w{8}\./,
filename: 'sw.js',
minify: true,
navigateFallback: 'index.html',
stripPrefix: 'public/',
swFilePath: 'public/sw.js',
staticFileGlobs: [
'public/index.html',
'public/**/!(*map*|*sw*)',
],
})
}
sw.ts
: sw.ts
: const swUrl: string = 'sw.js';
export const register = (): void =>{
if(process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator){
const sw: ServiceWorkerContainer = navigator.serviceWorker;
sw.register(swUrl).then(registration =>{
registration.onupdatefound = (): any =>{
const installer: ServiceWorker = registration.installing;
installer.onstatechange = (): any =>{
if(installer.state === 'installed'){
if(sw.controller){
console.log('New content available.');
}else{
console.log('Content cached for offline use.');
}
}
};
};
}).catch((error) =>{
console.error('Failed to register service worker:', error);
});
}
};
export const unregister = (): void =>{
if('serviceWorker' in navigator){
navigator.serviceWorker.ready.then(registration =>{
registration.unregister();
});
}
};
server.ts
: server.ts
: import * as path from 'path';
const twig = require('twig').__express;
const express = require('express');
const compression = require('compression');
const pkg = require('../../package.json');
const version = pkg.version;
let app = express(),
ip = '0.0.0.0',
port = 3000,
views = path.resolve('./src/views');
app.use(compression());
app.use(express.static('public'));
app.set('view engine', 'twig');
app.engine('.twig', twig);
app.set('views', views);
// Routes
app.get("*", function(req: any, res: any, next: any){
// vars
res.locals.version = version;
res.render('index');
});
let server = app.listen(port, ip, function(){
let host = server.address().address;
let port = server.address().port;
console.log('Gravity Boilerplate ready at http://%s:%s', host, port);
});
Within the sw-precache-webpack-plugin documentation it talks about using sw-precache options . 在sw-precache-webpack-plugin文档中,它讨论了使用sw-precache选项 。 The one you should investigate is the dynamicUrlToDependencies setting.
您应该研究的是dynamicUrlToDependencies设置。 See some of these links for more info:
有关更多信息,请参见以下链接:
For example, maybe start with this to test: 例如,也许从这里开始进行测试:
dynamicUrlToDependencies: {
'/': 'MAGIC_STRING_HERE'
},
So really, you need to configure the sw-precache WebPack plugin to load a server rendered page as the navigateFallback route . 因此,实际上,您需要配置sw-precache WebPack插件以将服务器呈现的页面加载为navigationFallback route 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.