使用React-Snapshot Pre-Rendering静态文件创建React应用程序

jas*_*san 6 prerender reactjs service-worker create-react-app

我正在使用create react app和react-snapshot为我的路线预渲染静态标记.即分别"/", "/signIn", "/signUp"生成index.html, signIn.html, signUp.html.

我面临的问题是无论我走哪条路线,最初都会index.html提供从根路由的react-snapshot生成的静态 "/",然后提供正确的静态路由文件,然后提供main.js捆绑(请参阅gif).如果我只是main.js单独捆绑我的应用程序,那就没关系了.但由于我想使用静态预生成的html文件,如何禁用服务工作者在我已经拥有静态html文件的某些路由上提供index.html.

更新:如果我从create react应用程序中删除服务工作者,该应用程序会加载路径正常的静态文件.但是,我想保留服务工作者的功能以获得PWA功能.

更新2:chrome browser根路由的快速闪烁上,静态标记仅针对每个路由发生一次.在第一次闪烁后,似乎Chrome浏览器缓存修复了它,另外如果我从chrome dev工具禁用缓存并尝试转到新路由,根路由的闪烁返回.对Firefox browser这个问题,无论什么存在,每个路线的变化或更新根航线的瞬间轻弹静态标记发生.

如何避免index.html最初在服务工作者的所有路由上呈现而不删除服务工作者.

更详细:

在Service Worker激活后,以下代码将在所有路径的页面源体中呈现:

 <body>
 <script>window.react_snapshot_state = {};</script>
 <noscript>You need to enable JavaScript to run this app.</noscript>
 <div id="root" data-react-checksum="-928641672"><div data-reactroot="" class="sc-cSHVUG hyLStb"><div class="sc-fjdhpX dIRAsX"><ul class="sc-gqjmRU koKaUp"><li><a class="navItemActive sc-VigVT cZrGwO" href="/"><!-- react-text: 6 --> <!-- /react-text --><!-- react-text: 7 -->Home<!-- /react-text --></a></li><li><a class="sc-VigVT cZrGwO" href="/aboutUs/"> About US</a></li><li><a class="sc-VigVT cZrGwO" href="/faq/"> FAQ</a></li></ul><div class="sc-jzJRlG cLytIk"><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="user circle icon"></i></button><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="add user icon"></i></button></div></div><!-- react-empty: 17 --><div><div style="opacity: 1;"><div class="sc-bdVaJa eRTdVS">Home</div></div></div></div></div><script type="text/javascript" src="/static/js/main.04df5475.js"></script></body>
Run Code Online (Sandbox Code Playgroud)

如果我删除了Service worker,那么该"/signIn"路由会在页面源代码中呈现以下内容:

<body>
 <script>window.react_snapshot_state = {};</script>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" data-react-checksum="143569200"><div data-reactroot="" class="sc-cSHVUG hyLStb"><div class="sc-fjdhpX dIRAsX"><ul class="sc-gqjmRU koKaUp"><li><a class="sc-VigVT cZrGwO" href="/"><!-- react-text: 6 --> <!-- /react-text --><!-- react-text: 7 -->Home<!-- /react-text --></a></li><li><a class="sc-VigVT cZrGwO" href="/aboutUs/"> About US</a></li><li><a class="sc-VigVT cZrGwO" href="/faq/"> FAQ</a></li></ul><div class="sc-jzJRlG cLytIk"><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="user circle icon"></i></button><button class="ui basic circular compact icon button sc-jTzLTM jfwzMH"><i aria-hidden="true" class="add user icon"></i></button></div></div><!-- react-empty: 17 --><div><div style="opacity: 1;"><div><div class="sc-EHOje bssfxk"><div class="sc-EHOje bssfxk"><form class="ui large warning form sc-ifAKCX ljuaXJ"><div class="field"><label></label><input type="email" placeholder="email" name="email" value=""></div><p class="sc-bxivhb dXOlfT">error</p></form><form class="ui large warning form sc-ifAKCX ljuaXJ"><div class="field"><label></label><input type="password" placeholder="password" name="password" value=""></div><p class="sc-bxivhb dXOlfT">error</p></form></div><p class="sc-dnqmqq ccTWaR"></p><div><div class="sc-gzVnrw cCgvhR"><button class="ui basic button sc-iwsKbI Vfjvd"><!-- react-text: 37 -->Login<!-- /react-text --><!-- react-text: 38 --> <!-- /react-text --></button><div class="sc-gzVnrw cCgvhR"><!-- react-empty: 40 --><div class="ui horizontal divider" style="width: 220px;">Or</div><div class="sc-bZQynM kECAnI"><button class="ui google plus button" style="text-transform: capitalize;"><i aria-hidden="true" class="google icon"></i><!-- react-text: 45 --> Google<!-- /react-text --></button><button class="ui facebook button" style="text-transform: capitalize;"><i aria-hidden="true" class="facebook icon"></i><!-- react-text: 48 --> Facebook<!-- /react-text --></button></div></div></div><div><p class="sc-htoDjs dErAlA">forgot your password ?</p></div></div></div></div></div></div></div></div><script type="text/javascript" src="/static/js/main.04df5475.js"></script><iframe style="display: none;"></iframe>
Run Code Online (Sandbox Code Playgroud)

GiF显示我试图访问"/signIn"Route,并注意到路径呈现的实际表单之前的单词home("/"路由的静态标记)"/signIn".

在此输入图像描述

jas*_*san 6

问题是Service Worker(SW)默认情况下Create React App只缓存内容static folderindex.html.我.html从react-snapshot中预先渲染的文件从未被缓存过SW.在SWcreate react app也设置为服务index.html于所有未知的URL,因此它是服务于根路径"/"静态文件index.html.我通过覆盖解决了这个service-worker.js通过修改构建命令文件package.json,如下所示:

"build": "react-scripts build && react-snapshot && sw-precache --config=sw-precache-config.js"

我的sw-precache-config.js样子如下:

module.exports = {
  staticFileGlobs: [
    './build/**/**.html',
    './build/images/**.*',
    './build/static/**',
  ],
  dontCacheBustUrlsMatching: /\.\w{8}\./,
  swFilePath: './build/service-worker.js',
      // For unknown URLs, fallback to the index page
  navigateFallback: './200.html',
      // Ignores URLs starting from /__ (useful for Firebase):
      // https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
  navigateFallbackWhitelist: [/^(?!\/__).*/],
      // Don't precache sourcemaps (they're large) and build asset manifest:
  staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
  stripPrefix: './build'
}
Run Code Online (Sandbox Code Playgroud)