Coder Social home page Coder Social logo

gabrielbull / react-router-server Goto Github PK

View Code? Open in Web Editor NEW
435.0 13.0 19.0 117 KB

Server Side Rendering library for React Router v4.

License: MIT License

JavaScript 100.00%
webpack2 react-router code-splitting server-side-rendering ssr react reactjs react-component webpack server

react-router-server's Issues

publicPath is ignored

In my project I have all JavaScript files in a js-Folder so I have publicPath: '/js/' in my webpack config. But when I use react-router-server for code splitting it assumes that all modules are located in the top level.

Support with Rails server

Hey, I like the library a lot, but I have rails as my server bundled by webpack provided by react_on_rails gem, not express. IS there any way you can facilitate that with an example?

React-Universal-Component/React-Async-Component/React-Loadable

Hi @gabrielbull, thank you for creating this library! I am looking to try it in a library which uses the libraries mentioned for 'asynccomponents for code-splitting. I noticed that this library has an export called` as well.

So, I am curious if you think this library would be compatible alongside those libraries if I don't use the <Module /> component or would the <Module /> component need to replace those libraries? And if replace, I'd love to understand the differences between these set of libraries and <Module /> components from you - pros/cons/tradeoffs?

Thank you!

renderToString promise not resolved after upgrading to 1.1.1

Hi,

I upgraded from v0.4.0 to v1.1.1. If I try to render a component without @fetchState decorator, the rendering seems to work fine. However, when I wrap even a simple component in @fetchState decorator, calling the function this.props.done doesn't work.

For example -
This works:

import React from 'react';
class ServerRootContainer extends React.PureComponent {
  render() {
    return <h1>Rendered</h1>
  }
}
export default ServerRootContainer;

But this doesn't:

import React from 'react';
import { fetchState } from 'react-router-server';
@fetchState(
  state => ({}),
  actions => ({ done: actions.done })
)
  class ServerRootContainer extends React.PureComponent {
    componentWillMount() {
      this.props.done({});
    }
    render() {
      return <h1>Rendered</h1>
    }
  }
export default ServerRootContainer;

I see in your example that you're building the server code as well, is this necessary? I can live without the code splitting.

My .babelrc file:

{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": [
   "transform-decorators-legacy",
    "add-module-exports",
    ["transform-runtime", {
      "polyfill": false,
      "regenerator": true
    }]
  ]
}

Redux integration

Hi, could you provide an example of how to use your package alongside Redux?

How to handle multiple nested redux promises ?

Hi,
How to handle multiple nested actions ??
my code is like this.

var _this = this;
    this.props.fetchStateId(this.props.match.params.name,function(err,res){
      _this.props.done();
      if(res && res.data && res.data.states_id){
        _this.props.fetchStateInfo(res.data.states_id,function(err,res){
          _this.props.done();
        });
      }
    })

i tried to call multiple done() but not worked. worked first time only.

Redux support needed

Hi
this is awesome project, but it definitely needs redux support.
Is this on the road-map?

Upgrade to router v4 beta ?

Hi, i'm looking forward to use this library for a big project but i'm waiting for the api to stabilise a little bit. According to this ctrlplusb/react-universally#356 , it seems the react router api should now be stable. Is there any plan to upgrade react-router-server to react-router beta ? Many thanks.

not working with CommonChunksPlugin with async chunk

I'm getting an endless loop when using the async option on CommonChunksPlugin.

This config will create a chunk file for common pieces spread throughout split code. If you use the same common components on multiple split pages, it will place the goods in this chunk file.

It seems that the module loading never completes and it goes into an endless loop with modulesLoading always set to 1. This can be seen by making the following changes to react-router-server-complex-example:

diff --git a/src/components/About.jsx b/src/components/About.jsx
index d7bae53..a1a902b 100644
--- a/src/components/About.jsx
+++ b/src/components/About.jsx
@@ -1,4 +1,7 @@
 import * as React from 'react';
+import hello from './Common';
+
+hello()

 const Component = (props) => (
   <div>
diff --git a/src/components/Common.js b/src/components/Common.js
new file mode 100644
index 0000000..f08ec80
--- /dev/null
+++ b/src/components/Common.js
@@ -0,0 +1,4 @@
+
+export default () => {
+  console.log('hello world!')
+}
diff --git a/src/components/Home.jsx b/src/components/Home.jsx
index 0ad06d4..a3fe950 100644
--- a/src/components/Home.jsx
+++ b/src/components/Home.jsx
@@ -1,6 +1,9 @@
 import React, { Component, PropTypes } from 'react';
 import { fetchState } from 'react-router-server';
 import '../styles/home.css';
+import hello from './Common';
+
+hello()

 @fetchState(
   state => ({
diff --git a/src/components/Images.jsx b/src/components/Images.jsx
index a97e338..9ca0563 100644
--- a/src/components/Images.jsx
+++ b/src/components/Images.jsx
@@ -1,4 +1,7 @@
 import * as React from 'react';
+import hello from './Common';
+
+hello()

 const Images = (props) => (
   <div>
diff --git a/webpack.config.js b/webpack.config.js
index d367e06..a9bef18 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,6 +2,7 @@ import path from 'path';
 import StatsPlugin from 'stats-webpack-plugin';
 import fs from 'fs';
 import ExtractTextPlugin from 'extract-text-webpack-plugin';
+import webpack from 'webpack'

 const nodeModules = {};
 fs.readdirSync(path.join(__dirname, 'node_modules'))
@@ -47,6 +48,10 @@ const config = server => ({
   },

   plugins: [
+    new webpack.optimize.CommonsChunkPlugin({
+      async: 'common',
+      minChunks: 2
+    }),
     new StatsPlugin('stats.json', {
       chunkModules: true,
       exclude: [/node_modules/]

Visiting any page that references the common chunk will spin indefinitely.

Preact support needed

Hi
this is awesome project and targeted at high performance apps it would be great if it would support preact.
Is this on the road-map?

Warning: setState called on an unmounted component

Hi there !

First of all, thanks for your work !

I got an issue with it though and I was wondering how you would like to solve it.

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the _class component.

The faulty setState is in fact caused by:
https://github.com/gabrielbull/react-router-server/blob/master/src/fetchState.js#L60

I guess we should follow what's in here: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html

What do you think ?

endless loop using `babel-preset-env` with node >= 4

It looks like the transpile is slightly different when the preset-env picks up that the node environment supports arrow functions. The regular expressions aren't matching properly and things go haywire.

The imports before --

// unminified
function () {
  return __webpack_require__.e/* import() */(6).then(__webpack_require__.bind(null, 73));
}

// minified
function (){return l.e(6).then(l.bind(null,73))}

And after --

// unminified
() => __webpack_require__.e/* import() */(6).then(__webpack_require__.bind(null, 73))

// minified
()=>t.e(6).then(t.bind(null,73))

In the unminified case, the first loadFunc still matches but the second does not - meaning we'll keep trying to re-render indefinitely (endless loop). In the minified case, neither matches so there's no endless loop but modules comes back as empty.

Unless I'm missing something here, I think the regular expression could be greatly simplified by just matching the number inside a parenthetical before .then... i.e., /\(([0-9]*)\).then/

Then again, there's not a lot of tests describing what the expected values are going for this loadFunc.... in my limited testing, I wasn't able to get the block commented as system import or system import minimized to hit, despite the un-transpiled code looking something like....

<Switch>
{asyncRoute('/', () => System.import('./home'))}
</Switch>

callstack exceeded results in server crash

This might be the result of doing stupid things and using react-router in unexpected ways, but I found a mysterious crash that wound up being max callstack exceeded. You can see this if you take the react-router-server-complex-example project and make the following changes:

  • Remove the <Switch /> element from ./components/App.jsx
  • Change NoMatch to use async loading like the other routes.

If you visit one route, it works fine... but visit another and hit refresh you'll get a server crash.

On my machine, Windows10 there is no actual error returned from the process.... but you can inspect %ERRORLEVEL% to see what the exit code is... here is the output from the shell,

D:\Code\react-router-server-complex-example>node_modules\.bin\babel-node.cmd --plugins system-import-transformer -- src/server.js
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead.
Example site listening on 3000!

^--- server crashes :(

D:\Code\react-router-server-complex-example>echo %ERRORLEVEL%
-1073741571

-1073741571 is a stack overflow exception.

I put a debugger on it in my own project where I found this initially, and I found that context.callback kept getting called, and went into another renderPass which ended up calling context.callback again.

I noticed the then callback in load was never fired, so add never gets called and the exists check never passes and the modules array kept getting the same module added over & over again.

unhandled promise rejection... can't be caught

I encountered this serendipitously while using react-helmet with a <FormattedMessage/> from react-intl.... react-helmet doesn't like this at all, and will throw back an error if it doesn't get a simple string.

Anyway, using react-router-server there is an unhandled promise rejection logged to the console. I attempted to add a catch block to the renderToString call, but this has no effect.

It appears there needs to be a try{}catch{} wrapping renderToString here -- https://github.com/gabrielbull/react-router-server/blob/master/src/renderer/renderPass.js#L36-L40 -- and if an error occurs, call into context.reject with the error.

This might also crop up with things like invariant errors or who knows what else. When it happens, the browser is left hanging with a pending request.

renderToStaticMarkup

Hello,

Great project! Thanks!

How can we render output with React.renderToStaticMarkup ?

Simplify fetchState

I'm using react-router-server with redux and that's working like a charm. Thank you very much for this package.

But I always need to write this on my containers:

fetchState(null, actions => actions)(
  connect(mapStateToProps, mapDispatchToProps)(Container)
)

Since I'm rehydrating state through redux, if I got it right, the only thing I need is the done action so I can pass it to my redux actions and fetch data on server properly.

For that case, I was wondering if could be there something like withDone decorator, which just passes the done action to props:

import { withDone } from 'react-router-server'
...
withDone(connect(mapStateToProps, mapDispatchToProps)(Container))

should `this.idx` be `this.index` ?

I'm working on a higher order component that wraps fetchState. You can see it here:

https://github.com/tswaters/react-todo/blob/e0e539ae21528dfac07d1fdf24458012f0861a83/src/common/initial-data.jsx

The idea here is to load localization values a component needs in addition to any promises that need to be resolved prior to rendering.... I noticed a problem with this approach - I would sometimes get ready set to true without firing done, and no locale key found would show up.

(Initially, I tried to fix this by adding some kind of uniqueness to the component, so instead of a generic ready I actually used the name of the component as the key for done and for checking. This seemed to work initially, but has a flaw if multiples of the same component are in use - only the first is rendered.... (see this revision))

Anyway, inspecting the props of the component at the time of componentWillMount I found that I was getting the wrong data context the done was fired with. I tested this by including the name of the component with the ready boolean - and in some cases, the name as completely different than what should have been loading. This results in the component thinking it's already loaded and not going further.

I had a line to test this inside the componentWillMount

if (this.props.isDone && name !== this.props.name) {
  console.log('wtf?!')
}

So, I went to randomly digging around the react-router-server code and I came across this line:

reactRouterServerFetchStateParentIndex: this.idx

Here's the thing, this.idx is undefined always here. There is a this.index property. I tried toggling it to test it out and... everything works properly.

Is this a typo?

fetchState not working if component uses contextTypes

I tried using react-router-server in a project that uses react-intl. In some components I need to use the intl context that is provided by react-intl but if I declare contextTypes for that component fetchState doesn't work.

I added console.log statements to the callback of my data fetch method and the callback of renderToString and it seems like the component just ignores that it should fetch data and renders immediately.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.