create-react-app:使用网络进行某些服务工作者导航?
create-react-app: Using the network for certain service worker navigations?
我正在使用 create-react-app 模板。我在根目录下安装了 Service Worker。因此,任何单击我域的 link(标签而不是 Link 标签)都会调用服务工作者。如果可用,Service Worker 将 return 来自缓存的资源,否则它将调用网络。 这是正确的吗?
假设这是正确的,我现在有一个稍微不同的场景,我想向我的应用程序添加一个 /documentation 路由。这条路线将服务于 jsdocs 使用节点 js 创建的 index.html 文件(参见我在节点 js 代码中的路线)。
问题是 service worker 似乎采用了这条路线,从不调用节点 js 后端,并将其发送到我的反应路由器。 React 路由器,因为它没有 /documentation 路由,所以只显示附加到所有 / 路由的导航和页脚组件。
我有两个问题:
1.我如何指定某条路线不应该由我的服务人员处理?我想我可以使用 fetch 但我不确定如何正确实现它
2。为什么 service worker 看不到它没有保存 /documentation 路由,因此只从服务器调用 index.html 文件?
节点 js
const path = require('path');
const bodyParser = require('body-parser');
const fs = require('fs');
const MongoClient = require('mongodb').MongoClient;
const stringToObject = require('mongodb').ObjectID
const mongoStoreFactory = require("connect-mongo");
const compression = require('compression');
const helmet = require('helmet');
var app = express();
app.use(helmet());
//Compress here since we do not want to change the build tools.
//This will use a bit more CPU as it needs to compress each request and response.
app.use(compression())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.set("port", process.env.PORT || 3001);
console.log("Port: " + process.env.PORT + " mode: " + process.env.NODE_ENV);
app.use(express.static("client/build"));
app.use(express.static("client/out"));
var accountsCollection = null;
/**
We don't need to specify index since this will be served automatically with static files.
*/
MongoClient.connect("mongodb://db:27017", function(err, db) {
if(!err) {
console.log("We are connected");
db.collection('accounts', function(err, collection) {
if(!err){
console.log("Accessed account collection");
accountsCollection = collection
}
});
//app.get('/', function (req, res) {
// console.log("Get index!");
// res.sendFile(path.join(__dirname+'/client/build/index.html'));
//});
app.get('/about', function (req, res) {
console.log("Get about!");
res.sendFile(path.join(__dirname+'/client/build/about.html'));
});
app.get('/services', function (req, res) {
console.log("Get services!");
res.sendFile(path.join(__dirname+'/client/build/services.html'));
});
app.get('/work', function (req, res) {
res.sendFile(path.join(__dirname+'/client/build/work.html'));
});
app.get('/skills', function (req, res) {
res.sendFile(path.join(__dirname+'/client/build/skills.html'));
});
app.get('/documentation', function (req, res) {
console.log("Get docs!");
res.sendFile(path.join(__dirname+'/client/out/index.html'));
});
app.listen(app.get("port"), () => {});
}
});
React组件技能中调用文档路径
<article className={"skills__skill"}>
<a href={"/documentation"}> See Documentation </a>
</article>
我的复杂路由器
<div className={"app"}>
<Router>
<div>
<Route render={({location, history, match}) => {
return (
<RouteTransition
pathname={location.pathname}
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}
>
<Switch key={location.key} location={location}>
<Route exact path={"/"} render={()=>{
handlePageChange(history);
return <Start/>
}
}/>
<Route path={"/"}
render={({location, history, match})=>{
return (
<RouteTransition
pathname={location.pathname}
atEnter={{ opacity: 0}}
atLeave={{ opacity: 0}}
atActive={{ opacity: 1}}
>
<FadeBackground >
<Clouds>
<Switch key={location.key} location={location}>
<Route exact path={"/services"}
render={(props)=>{
handleAuthentication(props);
handlePageChange(history);
return <Home />
}
}/>
<Route exact path={"/about"} component={Profile}/>
<Route exact path={"/work"}
render={()=>{
handlePageChange(history);
return <Work />
}}
/>
<Route exact path={"/skills"}
render={()=>{
handlePageChange(history);
return (
<Skills />
)
}}
/>
</Switch>
</Clouds>
</FadeBackground>
</RouteTransition>
)
}}/>
</Switch>
</RouteTransition>
)}
}/>
<Nav
links={[
{name:"Welcome",location:"/"},
{name:"About Me",location:"/about"},
{name:"My Services",location:"/services"},
{name:"My Work",location:"/work"},
{name:"My Skills",location:"/skills"}
]}
/>
<footer className={"footer"}>
</footer>
</div>
</Router>
</div>
在幕后,create-react-app
使用 sw-precache
, run via sw-precache-webpack-plugin
。
为了自定义 service worker 的行为,就像 create-react-app
中的其他自定义一样,您需要先 eject
。
一旦您有权访问基础配置选项,您要配置的 属性 就是 navigateFallbackWhitelist
, inside of webpack.config.prod.js
。您可以调整默认配置以包含不同的正则表达式;匹配其中一个 RegExp 的任何导航都会触发服务工作人员响应,所以我们的想法是您可以设置一个 RegExp 来匹配应该通过您的 SPA HTML 处理的路径,而不匹配 documentation/
或任何其他应通过后端处理的内容。
我正在使用 create-react-app 模板。我在根目录下安装了 Service Worker。因此,任何单击我域的 link(标签而不是 Link 标签)都会调用服务工作者。如果可用,Service Worker 将 return 来自缓存的资源,否则它将调用网络。 这是正确的吗?
假设这是正确的,我现在有一个稍微不同的场景,我想向我的应用程序添加一个 /documentation 路由。这条路线将服务于 jsdocs 使用节点 js 创建的 index.html 文件(参见我在节点 js 代码中的路线)。
问题是 service worker 似乎采用了这条路线,从不调用节点 js 后端,并将其发送到我的反应路由器。 React 路由器,因为它没有 /documentation 路由,所以只显示附加到所有 / 路由的导航和页脚组件。
我有两个问题:
1.我如何指定某条路线不应该由我的服务人员处理?我想我可以使用 fetch 但我不确定如何正确实现它
2。为什么 service worker 看不到它没有保存 /documentation 路由,因此只从服务器调用 index.html 文件?
节点 js
const path = require('path');
const bodyParser = require('body-parser');
const fs = require('fs');
const MongoClient = require('mongodb').MongoClient;
const stringToObject = require('mongodb').ObjectID
const mongoStoreFactory = require("connect-mongo");
const compression = require('compression');
const helmet = require('helmet');
var app = express();
app.use(helmet());
//Compress here since we do not want to change the build tools.
//This will use a bit more CPU as it needs to compress each request and response.
app.use(compression())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.set("port", process.env.PORT || 3001);
console.log("Port: " + process.env.PORT + " mode: " + process.env.NODE_ENV);
app.use(express.static("client/build"));
app.use(express.static("client/out"));
var accountsCollection = null;
/**
We don't need to specify index since this will be served automatically with static files.
*/
MongoClient.connect("mongodb://db:27017", function(err, db) {
if(!err) {
console.log("We are connected");
db.collection('accounts', function(err, collection) {
if(!err){
console.log("Accessed account collection");
accountsCollection = collection
}
});
//app.get('/', function (req, res) {
// console.log("Get index!");
// res.sendFile(path.join(__dirname+'/client/build/index.html'));
//});
app.get('/about', function (req, res) {
console.log("Get about!");
res.sendFile(path.join(__dirname+'/client/build/about.html'));
});
app.get('/services', function (req, res) {
console.log("Get services!");
res.sendFile(path.join(__dirname+'/client/build/services.html'));
});
app.get('/work', function (req, res) {
res.sendFile(path.join(__dirname+'/client/build/work.html'));
});
app.get('/skills', function (req, res) {
res.sendFile(path.join(__dirname+'/client/build/skills.html'));
});
app.get('/documentation', function (req, res) {
console.log("Get docs!");
res.sendFile(path.join(__dirname+'/client/out/index.html'));
});
app.listen(app.get("port"), () => {});
}
});
React组件技能中调用文档路径
<article className={"skills__skill"}>
<a href={"/documentation"}> See Documentation </a>
</article>
我的复杂路由器
<div className={"app"}>
<Router>
<div>
<Route render={({location, history, match}) => {
return (
<RouteTransition
pathname={location.pathname}
atEnter={{ opacity: 0 }}
atLeave={{ opacity: 0 }}
atActive={{ opacity: 1 }}
>
<Switch key={location.key} location={location}>
<Route exact path={"/"} render={()=>{
handlePageChange(history);
return <Start/>
}
}/>
<Route path={"/"}
render={({location, history, match})=>{
return (
<RouteTransition
pathname={location.pathname}
atEnter={{ opacity: 0}}
atLeave={{ opacity: 0}}
atActive={{ opacity: 1}}
>
<FadeBackground >
<Clouds>
<Switch key={location.key} location={location}>
<Route exact path={"/services"}
render={(props)=>{
handleAuthentication(props);
handlePageChange(history);
return <Home />
}
}/>
<Route exact path={"/about"} component={Profile}/>
<Route exact path={"/work"}
render={()=>{
handlePageChange(history);
return <Work />
}}
/>
<Route exact path={"/skills"}
render={()=>{
handlePageChange(history);
return (
<Skills />
)
}}
/>
</Switch>
</Clouds>
</FadeBackground>
</RouteTransition>
)
}}/>
</Switch>
</RouteTransition>
)}
}/>
<Nav
links={[
{name:"Welcome",location:"/"},
{name:"About Me",location:"/about"},
{name:"My Services",location:"/services"},
{name:"My Work",location:"/work"},
{name:"My Skills",location:"/skills"}
]}
/>
<footer className={"footer"}>
</footer>
</div>
</Router>
</div>
在幕后,create-react-app
使用 sw-precache
, run via sw-precache-webpack-plugin
。
为了自定义 service worker 的行为,就像 create-react-app
中的其他自定义一样,您需要先 eject
。
一旦您有权访问基础配置选项,您要配置的 属性 就是 navigateFallbackWhitelist
, inside of webpack.config.prod.js
。您可以调整默认配置以包含不同的正则表达式;匹配其中一个 RegExp 的任何导航都会触发服务工作人员响应,所以我们的想法是您可以设置一个 RegExp 来匹配应该通过您的 SPA HTML 处理的路径,而不匹配 documentation/
或任何其他应通过后端处理的内容。