使用React-Snapshot预渲染静态文件创建React应用 [英] Create React app with React-Snapshot Pre-Rendering static files

查看:84
本文介绍了使用React-Snapshot预渲染静态文件创建React应用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有

解决方案

问题是默认情况下 Create React App 中的 Service Worker(SW)静态文件夹 index.html .我从react-snapshot中预渲染的 .html 文件从未被 SW 缓存.在 create react app 中的 SW 也被设置为为所有未知的URL提供 index.html ,因此它正在提供根路径"/" 静态文件 index.html.我通过更改包中的build命令来覆盖 service-worker.js 文件来解决此问题.json 像这样:

"build":反应脚本建立&&&&&sw-pre-cache --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",//对于未知的URL,回退到索引页面navigationFallback:'./200.html',//忽略以/__开头的URL(对Firebase有用)://https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219navigationFallbackWhitelist:[/^(?!\/__).*/],//不要预缓存源地图(它们很大)并构建资产清单:staticFileGlobsIgnorePatterns:[/\.map$/、/asset-manifest\.json$/],stripPrefix:'./build'} 

I'm using create react app with react-snapshot to pre-render static markup for my routes. i.e "/", "/signIn", "/signUp" generates index.html, signIn.html, signUp.htmlrespectively.

Issue I'm facing is that no matter what route I go to, initially the static index.html generated from react-snapshot for the root route "/" is served and then the correct static route file and then the main.js bundle is served(see gif). This would be fine if I was just serving my app from a bundled main.js alone. but since I want to use the static pre-generated html files, how do I disable the the service worker from serving index.html on certain routes for which I have static html file already.

Update: If I remove service worker from the create react app, the app loads static file for the path fine. However, I want to keep the functionality of service worker for PWA features.

Update 2: On chrome browser the quick flicker of root route static markup happens only once for each route. After the 1st flicker it seems the chrome browser cache fixes it, additionally if I disable cache from chrome dev tools and try to go to new route the flicker of root route returns. On Firefox browser the problem exists no matter what, on every route change or refresh the momentary flick of root route static markup occurs.

How can I avoid the index.html to be rendered initially on all routes from the service worker without removing the service worker.

In more detail:

With the Service Worker active the following code renders in the body of page source of all routes:

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

IF I remove the Service worker the "/signIn" route renders the following in the body of page source:

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

GiF shows me trying to access "/signIn" Route, and notice the word home (static markup for "/" route) come up for a moment before the actual form for "/signIn" route renders.

解决方案

The issue was that Service Worker(SW) by default in Create React App only caches contents of static folder and the index.html. My pre-rendered .html files from react-snapshot were never cached by the SW. the SW in create react app also is set to serve index.html for all unknown urls, thus it was serving the root path "/" static file index.html. I solved this by overwriting the service-worker.js file by changing the build command in package.json like so:

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

where my sw-precache-config.js looked like the following:

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

这篇关于使用React-Snapshot预渲染静态文件创建React应用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆