我正在构建一个同构 React 应用程序,它在服务器上使用express.js。客户端应用程序向其他快速处理程序发出大量 AJAX 请求,这当前需要它们向自身发出多个 HTTP 请求。
作为一种优化,我想拦截我知道服务器处理的请求并直接调用它们(从而避免离开应用程序边界的成本)。我已经访问了应用程序路由器来了解它处理哪些路由,但是我正在努力寻找启动新请求的最佳方法。所以我的问题是:
如何快速处理来自程序源而不是网络的 HTTP 请求?
我有一个同构的React应用程序,它可以在浏览器和服务器上运行.我通过两个不同的入口点和不同的配置运行两个单独的Webpack构建,为两者构建相同的代码.
问题是,在服务器上的节点中运行时,浏览器窗口中存在的外部文件(在此实例中为Google Maps)显然不存在.除入口点文件外,代码完全相同.
index.html的:
// index.html
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXX"></script>
Run Code Online (Sandbox Code Playgroud)
简化配置:
// Server Webpack config
{
entry: 'server.js',
target: 'node',
externals: {
google: google
}
}
// Client Webpack config
{
entry: 'client.js',
target: 'browser',
externals: {
google: google
}
}
Run Code Online (Sandbox Code Playgroud)
组件:
// The view which builds and runs fine in
// the client but doesn't run on the server.
var React = require('react'),
css = require('./style.css'),
google = require('google'); // Nope, not on the server obviously!
var Component = React.createClass({ …Run Code Online (Sandbox Code Playgroud) 因此,我一直在摆弄:最近使用了一些同构的React + Flux,并且发现一些概念实在令人困惑。我一直在研究有关如何构造同构应用程序的最佳实践,并正在寻求建议。
假设您正在创建一个由相同的REST API支持的Web应用程序和一个移动应用程序。您是否将REST API与网络应用程序捆绑在一起?我见过有人提倡捆绑和为REST API建立单独的代码库。
任何建议或建议的阅读表示赞赏!
目标:我正在尝试在nodejs和webpack中设置一个项目,以便 require函数可以以root身份使用项目目录,因此我可以在两个环境中使用相对于项目根的绝对路径(同构使用即React服务器+客户端呈现).
情况:在webpack中你可以设置config.resolve.root使其工作,但在nodejs中,最好不要覆盖/修改global.require.
提议1:我可以创建一个新的全局功能
global.p_require
Run Code Online (Sandbox Code Playgroud)
所以它在节点中工作; 但是,我无法找到一种方法让webpack将"p_require"解析为__webpack_require__而不更改webpack源代码.
提案2:我可以创建一个新的全局变量
global.ROOT_DIR = process.cwd()
Run Code Online (Sandbox Code Playgroud)
所以它在节点中工作
require(ROOT_DIR + <relative path to root>);
Run Code Online (Sandbox Code Playgroud)
但是,webpack会认为这是动态需求.有没有办法让webpack解析ROOT_DIR?我已经尝试过Define Plugin,但似乎在webpack解析require之后加载.
题
任何人都有解决方案或面临同样的问题?
我正在尝试使用Webpack设置一个同构服务器端呈现React应用程序,但是当我尝试使用renderToString将我的React代码转换为字符串时出现此错误:
Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components).
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Run Code Online (Sandbox Code Playgroud)
当我用renderToString函数注释掉这行时,我停止得到这个错误(当然,应用程序仍然不起作用 - 我只是不再收到错误消息).
我已经尝试传递renderToString <RootApp />而React.createElement(RoutingContext不是制作工厂,但这些都没有奏效.使用React.createElement导致相同的错误,并使用<RootApp />扔了一个unexpected token < error.
关于可能发生的事情的想法?
我的应用看起来像:
app.js
"use strict"
require("babel-register");
const Express = require('express');
const BodyParser = require('body-parser'); …Run Code Online (Sandbox Code Playgroud) 我正在研究在 React 应用程序中使用代码分割。
我似乎找不到一种方法来为服务器端渲染引入代码分割(和导入),从而干净地传递到客户端。
仅供参考:我知道有一种方法可以使用 React Router 来做到这一点,但我认为这是一个更普遍的问题,并不是每个人都想使用它。另外,我觉得代码分割不一定与路由同义。
下面是一个非常基本的类示例,它将加载和呈现分割代码包的内容SplitComponent。
如果服务器端渲染的路由包含此组件,则将确保在调用之前componentWillMount同步加载代码。它检查它是否是服务器端,因此它不会执行此客户端操作。requirerender
然后对于客户端,componentDidMount将异步SplitComponent加载System.import.
这样做的结果是服务器端呈现正确的页面并且客户端将显示它,但随后将立即componentDidMount导致客户端加载SplitComponent,在此期间它将不显示任何内容(但短暂地取决于加载时间)。最后,SplitComponent将加载并渲染。但当它被移除然后再次添加时,可能会出现闪烁。这削弱了在服务器上进行渲染的优势。
有更好的方法来处理这个问题吗?
import React from 'react';
const canUseDOM = !!(
(typeof window !== 'undefined' &&
window.document && window.document.createElement)
);
class Lazy extends React.Component {
constructor() {
super();
this.state = {
module: null
};
}
componentWillMount() {
if (!canUseDOM) {
const m = require('./SplitComponent');
this.setState({
module: m.default
});
}
}
componentDidMount() { …Run Code Online (Sandbox Code Playgroud) 我使用SSR收到以下错误
Warning: Expected server HTML to contain a matching <div> in <div>.
检查组件装载时的浏览器宽度,然后设置组件的状态以呈现其移动版本时,问题出现在客户端上.
但是服务器默认了容器的桌面版本,因为它不知道浏览器宽度.
我该如何处理这种情况?我可以以某种方式检测服务器上的浏览器宽度并在发送到客户端之前呈现移动容器吗?
编辑:现在我决定在组件安装时渲染容器.这样,服务器端和客户端都不会在最初时阻止此错误.
我仍然愿意接受更好的解决方案
我的无服务器 Web 应用程序托管在 AWS Amplify 上。如果我尝试刷新页面,我会收到拒绝访问错误 XML。当我查看控制台时,它没有显示任何输出。该代码在 上运行良好localhost,但会导致 403 错误。
我发现了一个非常相似的问题,只是我没有使用 CloudFront。
我怎样才能找到这个问题的潜在原因?
我解决了这个问题,并在答案部分发布了答案。但是,我现在有了这个问题的第 2 部分。
如何让客户端可以像这样直接调用我的 URL:
https://URL.com/listing/LISTING_ID
现在,如果我尝试在传递LISTING_ID页面错误时直接调用它。这与 Isomorphic ReactJs 有什么关系吗?
我曾尝试使用 Digital Ocean 而不是 AWS 作为我的网络托管服务。发生同样的错误。
amazon-web-services node.js isomorphic-javascript server-side-rendering aws-amplify
我正在尝试从isomorphic-git获取类似于git diffGitHub 操作的输出。
我在这里查看了isomorphic-git 中实现的map函数,但我在使用它时遇到了问题。git.walk
我可以使用以下代码成功地遍历树:
async function main() {
const ref = 'HEAD'
const trees = [git.TREE({ref}), git.WORKDIR()]
const walk = await git.walk({
fs,
dir: '.github',
trees,
map: (filepath, [workdir, tree]) => [filepath, !!workdir, !!tree]
})
console.log(walk)
}
main()
Run Code Online (Sandbox Code Playgroud)
如何改进map这里的功能并使用jsdiffHEAD将当前工作树和stdout之间的文件更改输出?
我正在尝试制作一个 SSR 反应应用程序,但无法将道具从 express 传递到组件。我在做什么错误?
服务器.js
import AppPage2 from './src/project02/LandingPage';
......
......
server.get('/project2',async (req,res)=>{
const context = {data:'test'}
const sheet = new ServerStyleSheet();
const content = ReactDOMServer.renderToString(sheet.collectStyles(
<StaticRouter location={req.url} context={context}>
<AppPage2 state={{"foo":"baar"}}/>
</StaticRouter>)
);
const styles = sheet.getStyleTags();
let html = appShell( 'Project 2', content,' project2.bundle.js',styles)
res.status(200).send(html);
res.end()
})
Run Code Online (Sandbox Code Playgroud)
AppPage2(./src/project02/LandingPage)
import React from 'react';
import {Wrapper,Title} from './styleComponent/testStylePage'
.......
.......
class AppPage extends React.Component {
componentDidMount() {
console.log("{{API}}",this,this.props, this.props.staticContext)
}
render(){
return(
<Wrapper>
<Title>This is project 01 </Title>
</Wrapper>
) …Run Code Online (Sandbox Code Playgroud) javascript reactjs react-router isomorphic-javascript server-side-rendering
reactjs ×7
javascript ×4
node.js ×4
webpack ×3
aws-amplify ×1
express ×1
flux ×1
fluxible ×1
git ×1
react-router ×1
reactjs-flux ×1