create-react-app:使用网络进行某些服务工作者导航?

时间:2017-07-27 15:39:53

标签: service-worker create-react-app

我正在使用create-react-app模板。我在根目录下安装了服务工作者。因此,我的域中任何单击的链接(标记而非链接标记)都将调用服务工作者。然后,服务工作人员将从缓存中返回资源(如果可用),否则它将调用网络。 这是正确的吗?

假设这是正确的,我现在有一个稍微不同的场景,我想在我的应用程序中添加/ documentation路径。此路由将使用节点js为jsdocs创建的index.html文件提供服务(请参阅节点js代码中的路由)。

问题是看起来服务工作者采用这种方式,从不调用节点js后端,并将其发送到我的反应路由器。反应路由器,因为它没有 / documentation 路由,只显示连接到所有 / 路由的导航和页脚组件。

我有两个问题:

1。如何指定不应该为服务工作者处理某条路由?我想我可以使用fetch,但我不确定如何正确实现

2。为什么服务工作者没有看到它没有保存 / 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"), () => {});

  }
});

调用反应组件技能中的文档路线

        <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>

1 个答案:

答案 0 :(得分:1)

在幕后,create-react-app使用sw-precache,通过sw-precache-webpack-plugin运行。

为了自定义服务工作者的行为,与create-react-app中的其他自定义项一样,您需要先eject

一旦您有权访问基础配置选项,您要配置的属性为navigateFallbackWhitelist,位于webpack.config.prod.js内。您可以调整默认配置以包含不同的正则表达式;任何与其中一个RegExp匹配的导航都会触发服务工作者响应,因此您可以设置一个RegExp,该RegExp将匹配应通过SPA HTML处理的路径,而不匹配documentation/或应该通过你的后端处理的任何其他事情。