Giter Site home page Giter Site logo

nfl / react-wildcat Goto Github PK

View Code? Open in Web Editor NEW
436.0 35.0 38.0 4.05 MB

An opinionated React environment.

Home Page: https://medium.com/nfl-engineers/nfl-react-84e9cd11d384

License: MIT License

Makefile 1.22% JavaScript 95.28% Shell 3.08% Dockerfile 0.42%

react-wildcat's Introduction

DEPRECATED - React Wildcat - This react framework is no longer supported

Join the chat at https://gitter.im/nfl/react-wildcat

npm package build status codecov.io dependency status

A new, opinionated React environment from the National Football League. Read more on Wildcat.

Todo

Add more documentation. So much to document...

Features

  • dev tooling
    • Bundle-free development environment
    • Short and sweet time-to-dev (see Getting Started below)
    • Babel for on-the-fly component transpilation
    • react-transform-hmr for hot component reloading
    • Karma + Mocha + Chai + Sinon for unit tests
    • Istanbul for code coverage
    • Protractor + Mocha + Chai for e2e integration tests
    • eslint for static code analysis
  • client
    • React 0.14 + React Router 1.0 on the cilent and server
    • Route-based lazy component loading with React Router + Webpack
    • Radium for inline styling
    • Helmet for managing your document head
    • React Metrics for tracking analytics
    • Store-agnostic Prefetching for client data hydration
  • server
    • Loads client dependencies from a centralized location (no more per-project bundles)
    • Koa + (optional) HTTP2 for fast file serving
    • TLS-only via secure HTTP
    • Optimized production workflow

Server Requirements

  • Node 6.x (install via (n): n 6.x)
  • npm v3.x (npm install -g npm)

Client Requirements

  • IE10+

Development environment

Getting started: docker development

Clone this repository.

Create the file /etc/resolver/dev with the following contents (requires root permission):

nameserver 127.0.0.1
port 53535

Run:

  • cd example
  • docker-compose up
  • Open https://www.example.dev:3000

This will run the example wildcat project, with automatic file syncing in src/ and api/. The example/ folder is a great starting point to create your own project.

Getting started: local development

Clone this repository, then:

  • make install
  • cd example
  • npm run dev
  • Add the following to /etc/hosts:
127.0.0.1 www.example.dev
127.0.0.1 static.example.dev

Note: You'll very likely need to increase the file watch limit. Follow these steps to do so.

Accepting the development SSL certificate:

While it is possible to run the environment with an untrusted SSL certificate, for best results you should have OS X trust the self-signed certificate. Here's how:

Production environment

Wildcat is designed to run on two servers:

  • A Node server which accepts HTTP requests and renders static markup
  • (optional) A static file server that serves static assets (JavaScript files, CSS, images, etc)

This setup provides several benefits, including:

  • A single point of origin for serving all web projects.
  • A single point of origin for static file assets.
  • Ownership of static asset file caching.
  • Delta static asset cache purging.
  • The ability to update static files without a server reboot.
  • An (optional) use of HTTP2, including push support for static assets.

An example production setup with docker can be found in example/docker-compose.prod.yml. To run, use the command docker-compose -f docker-compose.prod.yml up.

Each server should have the required tools installed (see above). Each server is designed to run in its own environment. Below is an implementation reference to set up and run the web prototype:

Node server

Your app server environment must contain the following files and directories:

package.json
wildcat.config.js
cd path/to/project
npm install --production
env PORT=80 STATIC_URL=https://static.example.com npm run prod

Static assets

Note: The provided static file server is an optional dependency. The app server is agnostic about what solution is provided to serve static assets. It only expects the correct files to live in the domain specified via your STATIC_URL environment variable.

Your static server environment must contain the following files and directories:

bin
bundles
favicon.ico
public

Follow step one below to implement your own custom server, or skip to step 2 to use the bundled static asset server.

1. Custom static server

You will need to precompile the static assets:

cd path/to/project
npm install --production
env STATIC_URL=https://static.example.com npm run preprod-static

2. Setting up the static file server

cd path/to/project
npm install --production
env STATIC_URL=https://static.example.com npm run prod-static

Environment variables

LOGGING_HOST The graylog host to use to send server logs too.

Contributing to this project

Please take a moment to review the guidelines for contributing.

License

MIT

react-wildcat's People

Contributors

akalachik avatar alanmulhall avatar badrey avatar carakuei avatar dhoward avatar doctyper avatar gitter-badger avatar jamsea avatar ldeavila avatar lgcambra avatar miblanchard avatar npmcdn-to-unpkg-bot avatar pertrai1 avatar potench avatar ss81 avatar staxmanade avatar taak77 avatar tmbtech 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

react-wildcat's Issues

Running e2e tests should stop a server in dev mode and start a server in prod mode

Currently, running wildcat-protractor-runner will check if there's a server running on a specified port before starting one. However, if a server is already running in dev mode the e2e tests will run against the dev server instead of a prod one.

This can lead to subtle false positives and negatives, and is the main issue blocking #142 from working 100% correctly. Instead, we should kill the process listening to the specified port in wildcat.config.js (default is 3000) and start a new one.

Umbrella Docker Tasklist

Create a Wildcat Docker image that includes the following:

Outstanding

  • Required global dependencies
    • Node 4.x
    • npm 3.x
    • jspm 0.16.x
  • Required local dependencies
    • node_modules
    • jspm_packages
  • Sync file system changes between host and container with volumes
  • Create docker-compose file with every environment variable that can be configured in Wildcat

Wishlist

  • Host / maintain a development TLD (e.g. .dev, .localhost) within a Docker container
  • Script and/or instructions on how deploy to AWS/Azure/Digital Ocean via Docker

Parameterized routes hang on first try?

Hey,

Something interesting I've been seeing while playing with a couple routes that have parameters.

On initial server-start and first request appeared to just hang. Sometimes I would have to refresh the browser 2-3 times before I would see the route start working.

One thing I noticed was that in the following commit these hangs turned from hangs into errors at the console. (So before-hand the hangs must have just been swallowed errors) - but now I'm not exactly sure why I'm getting the error on the first or second/third request - but after the server has "warmed up" everything seems to run fine again.

Error printed to the console:

[0] TypeError: Invalid attempt to destructure non-iterable instance
[0]     at eval (https://localhost:4000/jspm_packages/npm/[email protected]/helpers/sliced-to-array.js:39:13)
[0]     at ensureResult (https://localhost:4000/public/routes/ViewGame/routes.js:25:21)
[0]     at normalizedImportsError (https://localhost:4000/jspm_packages/npm/[email protected]/dist/index.js:68:16)
[0]     at process._tickCallback (node.js:368:9)

Example of how I'm setting up a route...

In a folder example/src/routes/ViewGame I have the following

routes.js

import ensure from "react-wildcat-ensure";

// React router route
export const path = "/view-game/:gameId";

// Lazy loaded components
export function getComponent(location, cb) {
    ensure(["./ViewGame.js"], module, function ensureResult(err, [module]) {
        return cb(err, module);
    });
}

ViewGame.js

import React from "react";
import Helmet from "react-helmet";
import 'isomorphic-fetch';

export default class ViewGame extends React.Component {
    render() {
        return <div>Hello</div>;
    }
}

I've extended example/src/ApplicationRoutes.js with the following

import React from "react";
import {IndexRoute, Redirect, Route} from "react-router";

import Application from "./components/Application/Application.js";

import * as indexExampleRoutes from "./routes/IndexExample/routes.js";
+import * as viewGameRoutes from "./routes/ViewGame/routes.js";
-import * as errorExampleRoutes from "./routes/ErrorExample/routes.js";
-import * as flexboxExampleRoutes from "./routes/FlexboxExample/routes.js";
-import * as helmetExampleRoutes from "./routes/HelmetExample/routes.js";
-import * as prefetchExampleRoutes from "./routes/PrefetchExample/routes.js";

var Routes = (
    <Route path="/" component={Application}>
        <IndexRoute {...indexExampleRoutes} />

+        <Route {...viewGameRoutes} />
-        <Route {...errorExampleRoutes} />
-        <Route {...flexboxExampleRoutes} />
-        <Route {...helmetExampleRoutes} />
-        <Route {...prefetchExampleRoutes} />
-
-       <Redirect from="/redirect" to="/flexbox-example" />
    </Route>
);

export default Routes;

Have you seen this before? Could I be implementing parameterized routes wrong? Any thoughts?

Exceptions on startup not reported

I noticed that if an exception were raised within server.js, the error is not logged to the console or easily visible and it appears to just hang the process on startup.

I noticed that the caller to .start() here does not use a .catch(...) from the returned promise, however the function doesn't always return a promise so I'm not sure what the intent is there (with the clustering etc..).

Thoughts?

Use Flow

Look into using Flow for static type checking. Possible blockers:

  • Does it support experimental Babel features?
  • Does it support rest/spread?

Prefetch test suite fails to run.

env BABEL_ENV=test jest --env=node jest test/node.test.js --config .jestrc.node.json
 FAIL  test/node.test.js
  ● Test suite failed to run

    Cannot find module '../lib/index.js' from 'prefetchSpec.js'

I think it's supposed to be ../src/index.js

Test runners should take an --only flag

react-wildcat-test-runners should take an optional --only flag. This flag would accept a comma-separated list of files which would limit code coverage to those specific files.

This would be useful for code quality tools such as Phabricator, allowing differentials to report coverage scoped only to changed files.

Received message: `Error: Could not locate the bindings file. Tried:`

Ran make install. The command terminated with the following.

$installDirectory/react-wildcat/packages/react-wildcat/node_modules/memwatch-next/node_modules/bindings/bindings.js:96
  throw err

Error: Could not locate the bindings file. Tried:
 → $installDirectory/react-wildcat/packages/react-wildcat/node_modules/memwatch-next/build/memwatch.node
 → $installDirectory/react-wildcat/packages/react-wildcat/node_modules/memwatch-next/build/Debug/memwatch.node
 → $installDirectory/react-wildcat/packages/react-wildcat/node_modules/memwatch-next/build/Release/memwatch.node
 → (several more, similar)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Object.Module._extensions.(anonymous function) [as .js] ($installDirectory/react-wildcat/node_modules/istanbul/lib/hook.js:109:37)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
(and so on)

Realize that this is a gyp issue, but seemed like it would be better to document than to just ignore.

Resolution:

  • npm install -g npm-gyp
  • cd packages/react-wildcat/
  • npm install --python=python2.7
  • cd ../..
  • make install

New Setup Fails

Hey @doctyper,

I'm trying to do a deploy to Heroku and ran into some trouble - when I went back to my current solution (removed the node_modules folder and tried to re-setup by running make install I get the following. The same reproduces if I freshly clone react-wildcat and try to run make install.

~/code/temp/react-wildcat> make install
./shell/clean.sh
./shell/clean-example.sh
npm install --silent
make: *** [bootstrap] Error 1

if I npm install (without the --silent) flag I get:

npm ERR! Darwin 15.3.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v4.2.4
npm ERR! npm  v2.14.12
npm ERR! code ETARGET

npm ERR! notarget No compatible version found: react-wildcat-prefetch@'>=1.1.0 <2.0.0'
npm ERR! notarget Valid install targets:
npm ERR! notarget ["1.0.0-beta5","1.0.0-beta4","1.0.0-beta7","1.0.0-beta6","1.0.0-beta1","1.0.0-beta3","1.0.0-beta2","1.0.0-rc4","1.0.0-rc3","1.0.0-rc2","1.0.0-rc1","1.0.0-beta9","1.0.0-beta10","1.0.0-rc8","1.0.0-beta8","1.0.0-rc7","1.0.0","1.0.0-rc6","1.0.1","1.0.0-rc5"]
npm ERR! notarget
npm ERR! notarget This is most likely not a problem with npm itself.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget
npm ERR! notarget It was specified as a dependency of 'wildcat'
npm ERR! notarget

How to tack on some extra server-only routes?

Hey, been playing with the project for a bit and so far it's mostly going great...

I've mostly rewritten a little toy project's server/client page rendering using react-wildcat. However the app's data is currently being pulled in via an AJAX call to the production endpoint.

I'd like to take a couple express JSON API routes that I have and would like to now bring them into the react-wildcat dev project.

I see that both client and server are configured load "main.js". How would you suggest I go about tacking on some API express routes?

Thinking I'll need to break server/client root json - but not how that should interact with wildcat as well as how do I get access to express in the server to add custom api routes etc...

Thoughts?

This (which starts the server) doesn't expose the result of the .start(). (But also haven't yet found where this package gets initialized from...
https://github.com/nfl/react-wildcat/blob/master/packages/react-wildcat/main.js#L12

Ya'll rock!

Just wanted to say ya'll rock and I found out it shows up on your Slack :)

Thanks for putting this together!

Cheers!

Documentation Umbrella Task

This was started in PR #140. I think it makes sense to split this up so we don't feel overwhelmed.

A good first step is to get a README.md file in each of wildcat's smaller packages. We've already finished a few of them:

  • react-wildcat-ensure
  • react-wildcat-handoff
  • react-wildcat-hot-reloader
  • react-wildcat-prefetch
  • react-wildcat-test-runners

https://github.com/nfl/react-wildcat/tree/master/packages/react-wildcat-prefetch is a great example of what we need for each of these projects. Just a markdown file explaining what the project is and an example of how to use it.

PR #140 introduces gitbook support which makes for some nicely formatted docs.

/error-example page fails with an error

After following instructions from https://github.com/nfl/react-wildcat#getting-started-local-development /error-example page fails with an error in logs"

ErrorExample.js:10 Uncaught TypeError: this.props is not a function
at ErrorExample.render (ErrorExample.js:10)
at ErrorExample.render (createPrototypeProxy.js:44)
at finishClassComponent (index.js:210)
at updateClassComponent (index.js:210)
at beginWork (index.js:210)
at performUnitOfWork (index.js:210)
at workLoop (index.js:210)
at HTMLUnknownElement.callCallback (index.js:210)
at Object.invokeGuardedCallbackDev (index.js:210)
at invokeGuardedCallback (index.js:210)
render @ ErrorExample.js:10
_handleRouteStateChange @ createPrototypeProxy.js:44
finishClassComponent @ index.js:210
updateClassComponent @ index.js:210
beginWork @ index.js:210
performUnitOfWork @ index.js:210
workLoop @ index.js:210
callCallback @ index.js:210
invokeGuardedCallbackDev @ index.js:210
invokeGuardedCallback @ index.js:210
replayUnitOfWork @ index.js:210
renderRoot @ index.js:210
performWorkOnRoot @ index.js:210
performWork @ index.js:210
performSyncWork @ index.js:210
requestWork @ index.js:210
scheduleWork$1 @ index.js:210
enqueueSetState @ index.js:210
Component.setState @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
done @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ routes.js:6
Promise.then (async)
getComponent @ routes.js:6
getComponentsForRoute @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
mapAsync @ index.js:210
getComponents @ index.js:210
finishEnterHooks @ index.js:210
runTransitionHooks @ index.js:210
runEnterHooks @ index.js:210
(anonymous) @ index.js:210
runTransitionHooks @ index.js:210
runChangeHooks @ index.js:210
finishMatch @ index.js:210
(anonymous) @ index.js:210
next @ index.js:210
loopAsync @ index.js:210
matchRoutes @ index.js:210
match @ index.js:210
historyListener @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
updateLocation @ index.js:210
(anonymous) @ index.js:210
(anonymous) @ index.js:210
next @ index.js:210
loopAsync @ index.js:210
confirmTransitionTo @ index.js:210
transitionTo @ index.js:210
push @ index.js:210
push @ index.js:210
push @ index.js:210
handleClick @ index.js:210
callCallback @ index.js:210
invokeGuardedCallbackDev @ index.js:210
invokeGuardedCallback @ index.js:210
invokeGuardedCallbackAndCatchFirstError @ index.js:210
executeDispatch @ index.js:210
executeDispatchesInOrder @ index.js:210
executeDispatchesAndRelease @ index.js:210
executeDispatchesAndReleaseTopLevel @ index.js:210
forEachAccumulated @ index.js:210
runEventsInBatch @ index.js:210
runExtractedEventsInBatch @ index.js:210
handleTopLevel @ index.js:210
batchedUpdates$1 @ index.js:210
batchedUpdates @ index.js:210
dispatchEvent @ index.js:210
interactiveUpdates$1 @ index.js:210
interactiveUpdates @ index.js:210
dispatchInteractiveEvent @ index.js:210
index.js:210 The above error occurred in the component:
in ErrorExample (created by RouterContext)
in main (created by Application)
in div (created by Application)
in div (created by Application)
in Application (created by MetricsContainer)
in MetricsContainer (created by ApplicationContext)
in div (created by StyleRoot)
in StyleRoot (created by ApplicationContext)
in ApplicationContext (created by RouterContext)
in RouterContext (created by Router)
in Router
in Unknown
in AppContainer

Error on getOverride for jspm:npm

I am getting the following error when using make install after cloning your repo:

     warn Error on getOverride for jspm:npm
       Error: Command failed: /bin/sh -c git fetch --all && git reset --hard origin/master
       error: cannot open .git/FETCH_HEAD: Permission denied


         at ChildProcess.exithandler (child_process.js:213:12)
         at emitTwo (events.js:87:13)
         at ChildProcess.emit (events.js:172:7)
         at maybeClose (internal/child_process.js:829:16)
         at Socket.<anonymous> (internal/child_process.js:319:11)
         at emitOne (events.js:77:13)
         at Socket.emit (events.js:169:7)
         at Pipe._onclose (net.js:486:12)

If I do a sudo make install the make file completes it's installation; however the app itself won't run unless I sudo and then I get permission errors on the actual app.

I've used git fetch to create the FETCH_HEAD as I first thought that may be the issue, and made sure I am the proper owner of the file.

Would love to try out your environment but need some help please!

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.