使用 React-Snapshot 预渲染静态文件创建 React 应用程序
Create React app with React-Snapshot Pre-Rendering static files
我正在使用带有 react-snapshot 的 create react app 来为我的路线预呈现静态标记。即 "/", "/signIn", "/signUp"
分别生成 index.html, signIn.html, signUp.html
。
我面临的问题是,无论我去哪条路线,最初都会为根路线 "/"
提供从反应快照生成的静态 index.html
,然后提供正确的静态路线文件,然后提供 main.js
包(参见 gif)。如果我只是从捆绑的 main.js
单独提供我的应用程序,那会很好。但是因为我想使用静态预生成的 html 文件,我如何禁止服务工作者在我已经有静态 html 文件的某些路由上服务 index.html。
更新: 如果我从 create react 应用程序中删除 service worker,应用程序会为该路径加载静态文件。但是,我想为 PWA 特性保留 service worker 的功能。
更新 2: 在 chrome browser
上,根路由静态标记的快速闪烁对于每个路由只发生一次。在第一次闪烁之后,chrome 浏览器缓存似乎修复了它,此外,如果我从 chrome 开发工具禁用缓存并尝试转到新路由,根路由 returns 的闪烁。
在 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>
如果我删除 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>
GiF 显示我试图访问 "/signIn"
路由,并注意 home
一词("/"
路由的静态标记)在"/signIn"
路由渲染的实际形式。
如果您有从 react-snapshot 生成的所有标记的列表,您可以为它们手动设置重写规则,然后为其余部分添加回退规则。
例如
"rewrites": [
{
"source": "/signup",
"destination": "/signup.html"
},
{
"source": "/orders",
"destination": "/orders.html"
},
{
"source": "**",
"destination": "/index.html"
}
]
问题是 Service Worker(SW)
在 Create React App
中默认只缓存 static folder
和 index.html
的内容。 SW
从未缓存我来自 react-snapshot 的预渲染 .html
文件。 create react app
中的 SW
也设置为为所有未知 url 服务 index.html
,因此它服务于根路径 "/"
静态文件 index.html.
我解决了这个问题通过更改 package.json
中的构建命令来覆盖 service-worker.js
文件,如下所示:
"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'
}
我正在使用带有 react-snapshot 的 create react app 来为我的路线预呈现静态标记。即 "/", "/signIn", "/signUp"
分别生成 index.html, signIn.html, signUp.html
。
我面临的问题是,无论我去哪条路线,最初都会为根路线 "/"
提供从反应快照生成的静态 index.html
,然后提供正确的静态路线文件,然后提供 main.js
包(参见 gif)。如果我只是从捆绑的 main.js
单独提供我的应用程序,那会很好。但是因为我想使用静态预生成的 html 文件,我如何禁止服务工作者在我已经有静态 html 文件的某些路由上服务 index.html。
更新: 如果我从 create react 应用程序中删除 service worker,应用程序会为该路径加载静态文件。但是,我想为 PWA 特性保留 service worker 的功能。
更新 2: 在 chrome browser
上,根路由静态标记的快速闪烁对于每个路由只发生一次。在第一次闪烁之后,chrome 浏览器缓存似乎修复了它,此外,如果我从 chrome 开发工具禁用缓存并尝试转到新路由,根路由 returns 的闪烁。
在 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>
如果我删除 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>
GiF 显示我试图访问 "/signIn"
路由,并注意 home
一词("/"
路由的静态标记)在"/signIn"
路由渲染的实际形式。
如果您有从 react-snapshot 生成的所有标记的列表,您可以为它们手动设置重写规则,然后为其余部分添加回退规则。
例如
"rewrites": [
{
"source": "/signup",
"destination": "/signup.html"
},
{
"source": "/orders",
"destination": "/orders.html"
},
{
"source": "**",
"destination": "/index.html"
}
]
问题是 Service Worker(SW)
在 Create React App
中默认只缓存 static folder
和 index.html
的内容。 SW
从未缓存我来自 react-snapshot 的预渲染 .html
文件。 create react app
中的 SW
也设置为为所有未知 url 服务 index.html
,因此它服务于根路径 "/"
静态文件 index.html.
我解决了这个问题通过更改 package.json
中的构建命令来覆盖 service-worker.js
文件,如下所示:
"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'
}