Giter Site home page Giter Site logo

redfin / react-server Goto Github PK

View Code? Open in Web Editor NEW
3.9K 62.0 184.0 4.69 MB

:rocket: Blazing fast page load and seamless navigation.

Home Page: https://react-server.io/

License: Apache License 2.0

JavaScript 71.96% CSS 2.11% Shell 1.23% Dockerfile 0.92% SCSS 2.73% Sass 0.08% Less 20.97%
react-server react server universal isomorphic ssr

react-server's Introduction

React Server is now defunct

Consider Next.js instead.

React Server

Build Status NPM version NPM downloads per month Chat on Slack NPM license Powered by Redfin

React framework with server render for blazing fast page load and seamless transitions between pages in the browser.


Just getting started with react-server?

The easiest way to get started is with our yeoman generator:

# install yeoman
npm install -g yo

# install the react-server generator
npm install -g generator-react-server

# make a new react-server project in the CURRENT directory
yo react-server

# run the new app
npm run start
# go to http://localhost:3000

That hooks you up with react-server-cli, which will take care of the server part and get you up and running right away.

Why react-server?

One of the great things about React is its support for server-side rendering, which can make sites show up faster for users and play better with search engine bots.

However, when you actually try to use React for server-side rendering, you quickly run into a bunch of practical problems, such as:

  • How should I load data on the server for my components?
  • How do I ensure that the client and the server load the same data and generate the same HTML markup?
  • How do I write code that can be both generated server-side and be part of a single-page application (SPA)?
  • How should I optimize the delivery of my JavaScript and CSS?
  • How do I find out about and follow performance best practices?
  • How do I ensure that my site is streamed to the browser as quickly as humanly possible?
  • How can I make my app resilient when my backend has high latency spikes?

react-server is a framework designed to make universal (née isomorphic) React easier to write, providing standard answers for these questions and more. When you write your app for react-server, you concentrate on your React components, and react-server takes care of everything else that's needed to run and deploy real React server-rendered apps. Under the hood, react-server is doing a bunch of clever optimizations, many borrowed from the ideas behind Facebook's Big Pipe, to make sure that your site shows up as quickly as humanly possible for your users.

Once you're hungry for more, dig into the React Server documentation and the react-server code.


Migrating from react-server 0.8.1 to 1.0.0

This release is a major, potentially breaking, change which upgrades react-server's dependencies from webpack 1.x to webpack 4.x, and babel 6.x to babel 7.x.

If using default react-server configuration, you should be able to update to 1.0.0 without issue. However, if you have extended the default react-server webpack config using the webpackConfig option, you may need to update your webpack configuration options to match Webpack 4.x Documentation.

Note: If you are having trouble loading css bundles in mode = production, try switching from import to require() syntax. webpack-contrib/mini-css-extract-plugin#27

Want to help?

Great! There's a lot to do! See the contributing guide to get started.

Where's all the code?!

This is a Lerna respository with multiple npm packages! Check out the packages/ directory 👀.

react-server's People

Contributors

aickin avatar alexhanson avatar careylin avatar davidalber avatar davidgolden avatar decoy31 avatar dfabulich avatar doug-wade avatar drewpc avatar egid avatar emecell avatar feychou avatar gigabo avatar greenkeeperio-bot avatar helenaut avatar hzhu avatar jbenesch avatar karlhorky avatar krisxw avatar mlolson avatar ptomasroos avatar redfin-sasha-aickin avatar roblg avatar rodrijuarez avatar sresant avatar stevevitali avatar toddsullivan avatar tonyhyk avatar vinsewah avatar withinboredom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-server's Issues

Question: should I merge my examples in?

I have some example code that I'd love to donate to the project to help folks learn react-server, but I'm not sure if it's something that y'all want and/or where it would go.

@gigabo: in this comment, you said that "[t]hose are definitely better showcase examples than what I'm imagining here. I think they make sense to maintain as separate packages". I wasn't sure if that means you want me to keep them as separate packages in a separate repo, or that you mean they'd be welcome as sub-packages of the react-server monorepo. (I'm fine either way.)

So I'm looking for thoughts on if these would be a good addition to the monorepo, and if so, where they should go in the folder structure. Thanks!

vulnerability in react-server-test-pages

I doubt it'll ever affect anyone, but its an example and nsp is a good practice.

dougwade packages/react-server-test-pages ‹master*› » npm install
(node:75611) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.

> [email protected] prepublish /Users/doug.wade/code/react-server/packages/react-server-test-pages
> gulp build

[23:36:13] Requiring external module babel-register
(node:75612) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version.
[23:36:13] Using gulpfile ~/code/react-server/packages/react-server-test-pages/gulpfile.babel.js
[23:36:14] Starting 'eslint'...
[23:36:14] Starting 'nsp'...
[23:36:16] 'nsp' errored after 1.43 s
[23:36:16] Error in plugin 'gulp-nsp'
Message:
    (+) 1 vulnerabilities found
┌───────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│               │ Insecure Defaults Allow MITM Over TLS                                                                                                                   │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Name          │ engine.io-client                                                                                                                                        │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Installed     │ 1.6.9                                                                                                                                                   │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Vulnerable    │ <= 99.999.99999 || <= 1.6.8                                                                                                                             │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Patched       │ None                                                                                                                                                    │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Path          │ [email protected] > [email protected] > [email protected] > [email protected] > [email protected] > [email protected]  │
├───────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ More Info     │ https://nodesecurity.io/advisories/99                                                                                                                   │
└───────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

[23:36:16] Finished 'eslint' after 2.33 s

npm WARN [email protected] No repository field.
npm ERR! Darwin 15.4.0
npm ERR! argv "/usr/local/bin/iojs" "/usr/local/bin/npm" "install"
npm ERR! node v6.0.0
npm ERR! npm  v3.8.6
npm ERR! code ELIFECYCLE
npm ERR! [email protected] prepublish: `gulp build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] prepublish script 'gulp build'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the react-server-test-pages package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     gulp build
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs react-server-test-pages
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls react-server-test-pages
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/doug.wade/code/react-server/packages/react-server-test-pages/npm-debug.log

Automated tests against `react-server-test-pages` server

The react-server-test-pages server is great for testing by hand. It's easy to build simple test pages to play with and to iterate quickly. It would be great to take some of the test cases we exercise by hand during development there and automate them for regression tests.

Would selenium work for this? What's an easy way to set this up?

non-absolute URLs in stylesheets cause client-side stylesheet resolution machinery to replace stylesheets

I noticed this while working on #115

It seems like if the server returns a relative URL for a stylesheet, the client-side code in ClientCssHelper sees an absolute URL in the document, and when it compares that to the relative URL returned by getHeadStylesheets client-side, it thinks they're different and replaces them.

I didn't have time to investigate deeply, but I think this is what's happening. (I don't think it's something that #115 introduced)

Question: How do run react-server in production (without react-server-cli)?

Firstly, this looks and works amazingly!

Secondly, I've just played around with code from the yeoman generator for a while now and loveit but I've checked the docs an couldn't find any quides for running react-server in production, I assume running react-server-cli in production mode is not the right way(please correct me if I'm wrong). Am I supposed use react-server as a standalone middleware in express? Please point me in the right directions! Thanks!

Request: Startup log prints current NODE_ENV

When starting the server (particularly for the first time) We're not really explicit as to what NODE_ENV was found. We mention in the docs that it defaults to staging but we don't actually log out something along the lines of NODE_ENV defaulting to 'staging'

Just a little friendlier than 2016-04-19T22:00:45.054Z - warning: [react-server-cli.src.index] -- NODE_ENV is not set to "production".

Clarify documentation

Based on the gitter chatter this morning, it sounds like we need to make some docs updates to clarify that the “most common” use case is to run a separate back-end server, and that its a “bring your own flux” stack

Transient zombie failure on Travis

Builds fail periodically with An error occurred running zombie tests TypeError: connect ECONNREFUSED 127.0.0.1:8770 on travis. The build works if you kick it off again, but its not a very good experience for contributors.

see also
#156
#151
#164

DISCUSSION: react-server-build-tools and react-server-bundleNameUtil

We had an interesting situation at Redfin where we accidentally introduced a build-time dependency on React via our build-time dependency on react-server. This is solvable by using relative file imports, but its an easy bug to commit -- at build time you require('react-server/core/util/bundleNameUtil'), and at runtime you require('react-server').bundleNameUtil. I'm not sure how or if we want to fix this, but one way might be to add two new packages: react-server-bundleNameUtil (which contains bundleNameUtil) and react-server-build-tools (which contains react-server-bundleNameUtil and the babel options, and more generally any of the tools that are required at build-time). You could then take a devDep on react-server-build-tools and a dependency on react-server, and have them both work as anticipated (and, if we did need a build-time dependency of React, we could bundle a copy of React and not rely on a peerDep).

triton-root elements should not add extra dom nesting/nodes

Currently react server adds extra dom nodes for each root element that it creates. This makes full page or "app like" layouts quite tricky, especially since they don't have unique classes on them. Preferably we would not add an extra node if its not needed.

If this proves impossible, a fallback would be to allow developers to add unique classes to the root elements so that they can be styled.

Example below:

<body class='route-'>
   <div id='content' data-triton-content>
      <div data-triton-root-id="0" data-triton-timing-offset="25">
         <div class="Header" data-reactid=".wcmxgbtvk0" data-react-checksum="2028020681">...</div>
      </div>
   </div>
</body>

react-server-cli does not work with npm 2.x

As reported in #2 at comment #2 (comment)

To repro:

  1. Use npm 2.x (I used 2.14.20)
  2. git clone https://github.com/doug-wade/example-reactserver.git
  3. cd example-reactserver/
  4. npm install
  5. ./node_modules/react-server-cli/bin/react-server-cli

Gives this result:

2016-02-24T15:40:09.989Z - warning: [react-server-cli/index.js] PRODUCTION WARNING: the following current settings are discouraged in production environments. (If you are developing, carry on!):
2016-02-24T15:40:09.991Z - warning: [react-server-cli/index.js] -- Hot reload is enabled. Pass --hot=false, pass --production, or set NODE_ENV=production to turn off.
2016-02-24T15:40:09.991Z - warning: [react-server-cli/index.js] -- Minification is disabled. Pass --minify, pass --production, or set NODE_ENV=production to turn on.
2016-02-24T15:40:09.991Z - warning: [react-server-cli/index.js] -- NODE_ENV is not set to "production".
2016-02-24T15:40:13.584Z - notice: [react-server-cli/startServer.js] Starting servers...
2016-02-24T15:40:13.584Z - info: [react-server-cli/startServer.js] Starting hot reload JavaScript server...
2016-02-24T15:40:13.628Z - info: [react-server-cli/startServer.js] Starting HTML server...
2016-02-24T15:40:14.047Z - info: [react-server-cli/startServer.js] Started HTML server on port 3000
2016-02-24T15:40:14.174Z - info: [react-server-cli/startServer.js] Started hot reload JavaScript server on port 3001
2016-02-24T15:40:14.174Z - notice: [react-server-cli/startServer.js] Ready for requests on port 3000.
Hash: 22a0d3906fbc6214957a
Version: webpack 1.12.14
Time: 488ms
               Asset     Size  Chunks       Chunk Names
HelloWorld.bundle.js  22.3 kB       0       HelloWorld
chunk    {0} HelloWorld.bundle.js (HelloWorld) 64 bytes [rendered]
    [0] multi HelloWorld 64 bytes {0} [built] [4 errors]

ERROR in multi HelloWorld
Module not found: Error: Cannot resolve module 'webpack-dev-server/client' in /Users/sashaaickin/code/example-reactserver
 @ multi HelloWorld

ERROR in multi HelloWorld
Module not found: Error: Cannot resolve module 'webpack/hot/only-dev-server' in /Users/sashaaickin/code/example-reactserver
 @ multi HelloWorld

ERROR in multi HelloWorld
Module not found: Error: Cannot resolve module 'react-hot' in /Users/sashaaickin/code/example-reactserver
 @ multi HelloWorld

ERROR in multi HelloWorld
Module not found: Error: Cannot resolve module 'react-hot' in /Users/sashaaickin/code/example-reactserver
 @ multi HelloWorld
2016-02-24T15:40:14.974Z - debug: [react-server.core.renderMiddleware] Incoming request for /sockjs/info
2016-02-24T15:40:14.974Z - ok: [react-server.core.renderMiddleware] requestLocalStorageNamespaces val=6
2016-02-24T15:40:14.976Z - debug: [react-server.core.context.Navigator] Navigating to /sockjs/info?cb=7hgeqnbisy

Do something about config.js

This config.js is cool. It allows sites to specify config that's available both server side and in the browser.

But we also have a config file for the server itself, which doesn't make sense to transfer to the browser.

Two config files seems weird. Do we need both? Can we merge them cleanly somehow?

More discussion here.

Preload JS and CSS assets also

#74 introduced data preload to improve client transition performance between pages on the same route, but fetching static assets will still drag down client transition performance across routes.

@aickin proposed a solution that supports not only prefetch of webpack asset bundles, but also any independently included assets required by a page.

This would significantly improve first-time client transition performance across routes.

test failures are hard to understand

In our test output, it looks like we have failures, but none are reported

dougwade packages/react-server ‹rename-data-triton-root-id*› » gulp test
[19:39:19] Warning: gulp version mismatch:
[19:39:19] Global gulp is 3.9.0
[19:39:19] Local gulp is 3.8.10
[19:39:20] Using gulpfile ~/code/react-server/packages/react-server/gulpfile.js
[19:39:20] Starting 'compileServer'...
[19:39:20] Starting 'compileClient'...
[19:39:21] Finished 'compileClient' after 741 ms
[19:39:21] Finished 'compileServer' after 752 ms
[19:39:21] Starting 'test'...
...........................................................(node) OutgoingMessage.flush is deprecated. Use flushHeaders instead.
...2016-02-26T03:39:25.496Z - error: [react-server.core.renderMiddleware] Error in renderPage chain message=Timed out rendering., timeWaited=196, elements=[P]
......................................................[object Object]
..2016-02-26T03:39:42.519Z - error: [react-server.core.context.Navigator] Error while handling route message=died, stack=Error: died
    at InternalServerErrorException.handleRoute (/Users/doug.wade/code/react-server/packages/react-server/target/server/__tests__/integration/internalServerError/pages/InternalServerErrorException.js:26:10)
    at /Users/doug.wade/code/react-server/packages/react-server/target/server/util/PageUtil.js:358:25
    at /Users/doug.wade/code/react-server/packages/react-server/target/server/util/PageUtil.js:350:15
    at /Users/doug.wade/code/react-server/packages/react-server/node_modules/continuation-local-storage/context.js:74:17
    at _fulfilled (/Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:834:54)
    at self.promiseDispatch.done (/Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:863:30)
    at Promise.promise.promiseDispatch (/Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:796:13)
    at /Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:857:14
    at runSingle (/Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:137:13)
    at flush (/Users/doug.wade/code/react-server/packages/react-server/node_modules/q/q.js:125:13)
    at /Users/doug.wade/code/react-server/packages/react-server/node_modules/async-listener/glue.js:188:31
    at nextTickCallbackWith0Args (node.js:415:9)
    at process._tickCallback (node.js:344:13)
[object Object]
.2016-02-26T03:39:42.524Z - error: [react-server.core.context.Navigator] Error while handling route rejected
[object Object]
..........................................................

177 specs, 0 failures
Finished in 0 seconds
[19:39:59] Finished 'test' after 39 s

Replace __reactServerTimingStart with browser's navigation start event

React-server writes out a script tag as early as possible in the head to log t0 on the client side. Now that navigation timing API is available in all the browsers we care about, we get to eliminate this script tag and call into the browser's (presumably more accurate) t0 via window.performance.timing.navigationStart

Question: how do you feel about Selenium for integration tests?

So, I have a question for you all: how would you feel about porting the current integration test codebase from Zombie to Selenium?

I ask because I have a few features I'm itching to add, but I find myself a bit worried about how faithfully Zombie will test various scenarios. This is especially true with feature ideas like using the fetch API for data or implementing http/2, when different browsers end up taking completely different code paths because of polyfills and differing capabilities. I've been nervous enough about the testing matrix that I feel like it's worth stopping and shoring up the integration suite before proceeding. The only way I can think of doing so that makes sense to me is through Selenium and (probably) SauceLabs.

(It's worth noting that I wrote the first version of the integration suite, and I specifically opted for Zombie and against Selenium because I'd had bad experiences with maintaining Selenium tests and test machines in the past. I also was putting more weight on simplicity and reproducibility of tests back then and less on cross-browser quirks.)

Selenium pros:

  • Runs on real browsers: As we get into more optimizations and features, it's more and more likely that we hit browser inconsistencies. For example, if we move ReactServerAgent over to the Fetch API, it'd be nice to have integration tests that run both in browsers that natively support Fetch and ones that use the polyfill.
  • Takes videos and screenshots by default: Every test that runs on sauce labs takes a video of the browser as it goes through the test. This can make it much, much easier to understand what failed in a test.
  • Our tests seem convertible: I've looked through our current integration test codebase, and it seems like all or almost all of the current tests would be able to be converted to Selenium.
  • Setting up Travis seems relatively easy: Setting up with Selenium/Sauce/Sauce Connect is pretty easily supported on Travis.

Selenium cons:

  • A lot slower: Each command to the browser is run independently, over the Internet, as opposed to in-process JavaScript with Zombie. It's fairly easy to parallelize different testing different browsers in Travis, but parallelizing individual tests is harder.
  • More confusing to run tests locally: Zombie just requires npm install && gulp test locally, whereas Selenium would require either a webdriver/selenium server local installation, or that the dev have Sauce Lab credentials and set up Sauce Connect.
  • More moving parts makes tests less reliable: I have a general worry that the more complexity you put into your test setup, the more likely it will fail intermittently, and intermittent failures are the death of a test codebase.

Better API for declaring the fold: <TheFold />

Instead of saying "the fold for this page is after the first N elements" (which could change based on middlewares? maybe?), it'd be nice if you could just declare it inline with everything else in JSX. Eg:

getElements() {
    var prefetchConfig = {prefetchUrls:this._getPrefetchURLS()};

    return [
        RootElements.createRootElementWhenResolved(this._emailVerificationBannerStore, <EmailVerificationBanner />),
        RootElements.createRootElementWhenResolved(this._searchAndMerchStore, <SearchAndMerch />),
        <TheFold />
        RootElements.createRootElementWhenResolved(this._listingFeeStore, <MarketingSections />),
        RootElements.createRootElementWhenResolved(this._generalInquiryStore, <GeneralInquiryForm />),
        RootElements.createRootElementWhenResolved(this._eigencitiesStore, <EigencitiesSection />),
        <Prefetch {...prefetchConfig}/>,
    ];
}

(Obviously it doesn't need to really be React or JSX. It could just be require("react-server/TheFold") or something.)

DISCUSSION: Feature ideas for `react-server` & `react-server-cli`

(Dunno if this is the right place to put this; please advise if it's not.)

I was thinking about how I could best contribute to making react-server a public success, and I wanted to open a little bit of a discussion about what features might be added to (or subtracted from!) react-server-cli and react-server. I brainstormed for a little while on my own, and the list is pretty scattered and wildly biased towards my own priorities. It's really only meant to be a starting point, and to prevent me from coding on something for a week or two that has no chance whatsoever of being merged because it's not in line with y'all's vision. Caveat: I'm not even sure that these are good ideas if there were infinite time to implement, and they betray my two main priorities: making dev rampup as quick & painless as possible, and having react-server(-cli) be a good example of web performance best practices.

Without any further ado, here's my list, with guesses at T-shirt size:

  • Replace superagent with fetch (L/XL): seems like fetch is rapidly becoming the standard, with pretty good polyfills for both client and node. Swapping out superagent for fetch would reduce the amount of documentation required for data loading: rather than sending in a loader argument to the page API and then explaining superagent, we'd just say "use fetch like you already do".
  • Port to webpack 2 with tree shaking (M/L): This could in theory reduce the size of the initial bundle. Webpack 2 is not out of beta, yet, though, so it's somewhat moot until then.
  • Add support for HTTP/2 with server push (XL/XXL): I think one of the most powerful things about react-server is that the server-side knows, in a structured way, about all of the associated resources for a page (JS, CSS, JSON XHR) and could push them pro-actively. Not only would this theoretically be faster than the current code, it would also obviate the need for the TritonAgent cache, which would simplify the logic a lot in the HTTP/2 case.
  • Commons chunk (S): Tweak the webpack build in react-server-cli to pull out a common chunk of JavaScript, which would include the core of react-server. This would allow that chunk to be cached and shared in between pages. (Edited: Forgot I already did this, and it was merged in e30947a. Too much context switching!)
  • Long-term caching of static assets (M/L): Implement the webpack config best practices for setting a far future expiration on static assets.
  • Allow RootElements to each have their own CSS (XL) - This one is more of a research project in all honesty. It's based on this article by Jake Archibald about CSS link tags in the body, and how they can reduce the amount of time your page spends waiting for CSS before rendering. It's hard for me to see how this would be done with the current API of react-server and webpack, but I haven't spent a ton of time thinking about it.
  • Port the react-server tests to use react-server-cli (M) - A bunch of tests for react-server fire up an actual express server, parse and massage the routes file, and run webpack before running a simulated browser against the resulting site. It would be nice if instead they used react-server-cli to do that, both because we could delete a lot of code, and because it would help serve as a test for react-server-cli.
  • Allow react-server to be launched with a single Page file instead of a routes file (M) - One of the really interesting ideas at React Conf was a command line that could take in just a component file and would set everything up for you for rapid prototyping. I would love to be able to just point react-server-cli at a page file and have it set up a simple "/" route for that page. I could also potentially imagine pointing it at a directory and having every file named XXXPage.js being mapped to /xxx.
  • Allow routes to map to a component instead of a page (M/L) - This is another feature for folks who just want to get a rapid prototype up and running. If you don't care about page title or stylesheets or extra JS, it's a bit of a burden to create a Page class in addition to your component.
  • Add support for best quality compression (S) - I've got a fun side project called shrink-ray that is adding zopfli and brotli support to express compression. I don't think this is a particularly good thing to spend time on right now, fwiw.
  • Add support for streaming rendering (M/L) - I also had to put this in, as I wrote react-dom-stream; probably also not a particularly good use of time right now until rds is a bit more stable.
  • Simplify the use of routr (S) - Routr could be a little more user friendly if it had some smart defaults. For instance, it'd be nice if it didn't require you to always specify the HTTP method of every route, but rather just assumed GET.
  • Explore using react-router for routing instead of routr (XL) - I'm super uncertain about this one, but I do think that react-router has become the standard for routing in the React world, and there are a lot more folks familiar with it than with routr. I'm afraid that react-router makes some fundamental assumptions that go against the streaming nature of react-server, but that may have changed, and I may be wrong.
  • Add more documentation and example projects about how to do data loading (M) - I may be wrong, but I think there isn't much info on how to use TritonAgent.
  • Expose a programmatic API to react-server-cli (S) - Basically just make startServer callable.

OK, that's what I've got for now. As I said, all totally up for discussion and not all great ideas. Please feel to add, subtract, disagree, etc. I'm especially interested in which ideas are total non-starters, and which you'd gladly accept as contributions if they were done well. Thanks!

reuseDom Client Transition error

I ran into an issue today with reuseDom, when the destination page has fewer root elements than the source page.

Let's say Page A has 3 root elements, Page B has 1 root element.
When transitioning from from page A to page B via a Client Transition with reuseDom, the 1st root element will get correctly replaced by Page B, but the 2nd and 3rd root elements will remain unchanged (minus CSS) from Page A.

reuseDom needs to wipe out extra root elements when transitioning to a page with fewer Root Elements.

Unfortunately I don't have a good, non-sensitive test case for this.

Travis CI build is broken

Failing on lerna bootstrap. Not sure why, exactly. Works locally. Worked pre-lerna publish of v0.0.6.

Only thing I can think of is the cross-dependency version didn't get updated during publish.

Filed a ticket on lerna about the unexpected publish behavior.

Meanwhile, maybe we should just update the cross-dependency version manually?

Should "clean" before publishing

To make sure that we're not publishing old crufty files, we should add a "clean" step that we run before building to publish.

Support `FormData` objects in `ReactServerAgent.send(...)`

We currently don't support sending FormData with .send(...) on RSA requests, even though superagent does. We should support it, at least when making calls from the client-side. (It's possible that it would be reasonable to make calls from server-side too, but we'd have to figure out how to serialize the data, and how to do equality checking against the data cache on the frontend.)

Add a "writing a page" doc

We have "writing middleware" and "page API", but no overview of writing a page.

Worth highlighting:

  • Methods have sane defaults
  • Data requests should be kicked off in handleRoute
  • Importance of getAboveTheFoldCount
  • ???

Proposal: how to enable long-term caching of assets.

I'd like to write down a proposal I'm thinking of to implement far future caching in react-server-cli to get feedback before diving in. I have some worries about it, and I'd rather have some discussion before jumping in.

For background, read this excellent article on how to implement long-term caching in webpack; basically my proposal is just to implement everything in that article when in production mode (or when long-term caching's turned on by a flag).

Mostly this is fairly straightforward, but there is one wrinkle that I want to run by all of you. It's the case where you compile the client code ahead of time and upload the assets to a CDN or static server. Then you launch react-server-cli with jsUrl: http://mycdn.com/my/precompiled/assets/, and r-s-c launches just the HTML server, pointing all JS and CSS URLs at something like http://mycdn.com/my/precompiled/assets/main.js.

The problem in this case is that the HTML server needs to know about the output of the client webpack build in order to get the hashed names of both the entrypoint script files and the chunks that are loaded later. I can see two ways to do this:

  1. Decoupled: Don't change the current compile codepath. When firing up a server with jsUrl set, run the compile codepath again just to get the file hashes (and throw away the actual assets).
  2. Manifest File: When compiling the client code, output a manifest.json in the root directory that has all of the file hashes present. When firing up a server with jsUrl set, do NOT compile the client. Instead pull down the manifest file via HTTP(S) and use that to determine the file names.

I'm leaning towards a manifest file. If for whatever reason the client compilation was performed on a different version of the app codebase than what the server is attempting to run, we could detect that case using the manifest file and warn or refuse to start up at all. I'm sure that client/server version mismatches would create wildly hard to find bugs.

I also have some worries about the manifest file, particularly that requiring there to be a network path from the HTML server to the static file server might trip some folks up. Thoughts?

We need a logo

Can't be taken seriously without a cute picture to represent the project, right?

Simpler API for client transitions

We've got to make this easier. I want to be able to initiate a client transition with a single import.

Something as simple as:

const {navigateTo} = require("react-server");

navigateTo(path, {options});

Currently looks like:

const {
    ClientRequest
    History,
    getCurrentRequestContext,
} = require("react-server");

getCurrentRequestContext().navigate(
    new ClientRequest(this.props.path),
    History.events.PUSHSTATE
);

Implement getCanonicalUrl

From #166, we plan to implement the following page api method

getCanonicalUrl(next: Function), optional: String | Promise(String)

  • NOT YET IMPLEMENTED
  • A string (or promise thereof) that is the canonical URL for this webpage
  • Default: no canonical URL header added.

`gulp test` output is noisy

There are at least three sources of noise in gulp test output:

  • Excess gulp-chug prefixes
  • Node's (node) OutgoingMessage.flush is deprecated. Use flushHeaders instead warning.
  • Error in renderPage chain message=Timed out rendering.
    • This is just a logger.error() message. We should capture and suppress.

Improve displayElement to log the time it takes for the element to be displayed

Currently displayElement.fromStart timings are based on data-react-server-timing-offset set on the server side. In practice, the numbers we see are wildly different from the time at which content shows up on the page.

According to @gigabo , the "hack" was only necessary to log above the fold display times. We propose to kill displayElement times for individual elements above the fold, and log a more "accurate" time for displayAboveTheFold and elements after that.

Proposal: Package reshuffle for user friendliness

Right now react-server isn't easy to get started with.

It's missing big pieces that are provided by react-server-cli.

Proposal:

  • Move react-server to react-server-core.
  • Pull the bulk of react-server-cli into react-server
    • react-server exports startServer.js (as .start() or .run())
    • react-server-cli just becomes CLI for calling require('react-server').start().

RootContainers count twice for getAboveTheFoldCount

We have a page that has an entire RootContainer that's above the fold, but we don't account for it in our getAboveTheFoldCount implementation. While debugging why our waterfall is looking weird (caused by this wrong count number), we noticed that the fix would be to a) take into account the RootContainer in our getAboveTheFoldCount implementation, but also b) increment our count by 2 for each entirely-above-the-fold RootContainer. The latter is extremely confusing and easy to miss - can we either omit RootContainers from being part of the above-the-fold-count (they are elements, but they're container elements that can only contain RootElements, which already count for above-the-fold so it seems duplicative), or at least fixing this double-counting thing?

Expected error or warning when attempting route with null or invalid `page`

Ran into this one pretty quick, I had a typo in the page attribute in my routes file and the log didn't give any warning that the router was unable to find a valid page class at that filesystem location.

Log output:
2016-04-19T22:05:36.031Z - debug: [react-server.core.context.Navigator] Navigating to /home

Route:

routes: {
    Test: {
        path: ["/home"],
        page: "./pages/Hone"
    },
}

Note: it should be "Home" not home, as the page class is at ./pages/Home.js

I expected some sort of warning here in the log, particularly when not running in prod mode.

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.