我根据https://prerender.io/documentation使用create-react-app完成了nginx的大部分必要设置,但我确实有几个问题
但是让我解释一下我的项目设置。
我的文件夹结构
公共
/index.html
SRC /
组件
集装箱
index.js(容器应用)
src / index.js 看起来像
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {ConnectedRouter} from 'react-router-redux';
import './index.css';
import './main.css';
import App from './containers/app';
import store, { history } from './store';
const target = document.querySelector('#root');
ReactDOM.render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
target
);
在我的nginx中,我已将根指定为/path/to/project/public/index.html
的index.html
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root">
My custom text
</div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
方法#1 - Nginx工作正常并在此页面上显示html。 默认情况下,捆绑包不存在。显然,当我们启动纱线开始或npm开始时,webpack处理这个部分。如何将此bundle.js添加到index.html,以便prerender.io服务可以找到它并返回生成的反应页面的html?或者我甚至需要这样做?
方法#2 - 我在端口上启动项目说3001(纱线启动)然后在我的预渲染服务器开启的情况下,我运行了http://localhost:3000/http://localhost:3001
其中http://localhost:3000 = Prerender.io服务器 http://localhost:3001是项目运行的地方。
现在,
它不会从项目根目录http://localhost:3001提供我的静态资产,而是来自http://localhost:3000
其次,在这种情况下,我不觉得有必要手动设置nginx。我需要的只是prerender服务器,我的项目已经通过yarn start
运行。
我觉得第2点适用于本地测试。第1点将适用于预渲染的实际部署。
方法#3 - create-react-app本身具有预渲染的反应快照,但在我的设置中也会出现错误
index.js文件
import React from 'react';
// import ReactDOM from 'react-dom';
import { render } from 'react-snapshot';
import {Provider} from 'react-redux';
import {ConnectedRouter} from 'react-router-redux';
import './index.css';
import './main.css';
import App from './containers/app';
import store, { history } from './store';
const target = document.querySelector('#root');
render(
<Provider store={store}>
<ConnectedRouter history={history}>
<App />
</ConnectedRouter>
</Provider>,
target
);
运行时会出现错误Syntax error: Unexpected token, expected , (15:14)
对于方法#1和#2,思维是否正确?最简单的方法#3有什么问题?
更新 - nginx.conf文件
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 8000;
server_name localhost;
root /Users/vedant/Projects/myProject/build;
index index.html;
location / {
try_files $uri @prerender;
}
location @prerender {
proxy_set_header X-Prerender-Token eNlgaUedb3xptcXiFlex;
set $prerender 0;
if ($http_user_agent ~* "baiduspider|twitterbot|facebookexternalhit|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($uri ~* "\.(js|css|xml|less|png|jpg|jpeg|gif|pdf|doc|txt|ico|rss|zip|mp3|rar|exe|wmv|doc|avi|ppt|mpg|mpeg|tif|wav|mov|psd|ai|xls|mp4|m4a|swf|dat|dmg|iso|flv|m4v|torrent|ttf|woff|svg|eot)") {
set $prerender 0;
}
#resolve using Google's DNS server to force DNS resolution and prevent caching of IPs
resolver 8.8.8.8;
if ($prerender = 1) {
#setting prerender as a variable forces DNS resolution since nginx caches IPs and doesnt play well with load balancing
set $prerender "service.prerender.io";
rewrite .* /$scheme://$host$request_uri? break;
proxy_pass http://$prerender;
}
if ($prerender = 0) {
rewrite .* /index.html break;
}
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
include servers/*;
}
更新2 -
我尝试访问http://localhost:8000/localhost:3001其中 http://localhost:8000是我的nginx服务器。
但它只给我页眉和页脚。尝试添加<script> window.prerenderReady = false; </script>
。但它部分呈现。
答案 0 :(得分:0)
方法#2对于在本地测试事物是正确的。由于您直接在浏览器中访问Prerender服务器,因此预计会查看http://localhost:3000请求的静态资产。一旦你正确设置了nginx配置,你就会通过nginx提供预渲染的页面,这些问题就会消失。
方法#1应该在生产中工作,因为bundle文件将包含在index.html中,但是在本地你需要让你的nginx只对你的localhost webpack服务器执行proxy_pass。这样你就可以从npm start获得注入的包。