GithubHelp home page GithubHelp logo

sekoyo / universal-react Goto Github PK

View Code? Open in Web Editor NEW
242.0 11.0 50.0 147 KB

A universal react starter, with routing, meta, title, and data features

JavaScript 100.00%
universal react redux isomorphic javascript server-side-rendering

universal-react's Introduction

Universal React

This boilerplate aims at solving the MVP (Minimal Viable Product) of a universal app while trying to keep the base unopinionated elsewhere and simple to read and extend.

Universal React on NPM Dependency Status

Features

  • Universal routing react-router
  • Redux
  • Hot reloading
  • Title, meta, css, and scripts overridable by each component react-helmet
  • Universal data fetching/rehydration on the client cross-fetch
  • No other templating engines - React from root down
  • 404 and redirect handling
  • Shared app config
  • Webpack and Babel

Since there are so many opinions on how to use css (vanilla, sass, less, react css modules etc) I've left it up to you.

##ย Install & run

npm i && npm start

Go to http://localhost:3000/.

Build

npm run build

This will create a dist/ folder with a app.min.js which will be used on any environment which isn't undefined (i.e. not local).

npm run start-prod

This will build and then run your app with environment set to production, so that app.min.js and config/production.js are used.

Adding routes

Add your routes in Routes.js.

<Route path="users" component={Users} />

Title and Meta

The parent App.js defines the base title and meta in a Helmet component. Any sub-component can override/add properties (even adding scripts and css). See the react-helmet docs for more info.

Config

You can store app settings under app/config/. A file matching process.env.NODE_ENV will be loaded, for example app/config/production.js. If process.env.NODE_ENV is undefined it will fallback to app/config/default.js. You can access the correct config with:

import config from './config';

Data fetching and client hydration

Read the Redux guide if you are new to redux. Write Redux actions and stores as normal, and if the action creator is asynchronous then it should return a Promise (or a Promise.all) in the inner function.

You should write dispatches for actions that must be called for the container to be ready:

static readyOnActions(dispatch, params) {
  return Promise.all([
    dispatch(UserActions.fetchUserIfNeeded(params.id))
  ]);
}

You should also invoke the actions in componentDidMount. This ensures that if the component is reached on the client, then the same actions will be invoked. It's up to the action to figure out if fetches for data need to be made or not:

componentDidMount() {
  User.readyOnActions(this.props.dispatch, this.props.params);
}

universal-react's People

Contributors

davidepalazzo avatar dominictobias avatar keyeh avatar lquixada avatar lunigorn avatar n7best avatar troutzen 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

universal-react's Issues

Had to downgrade to React-Router v3.0.5

I was getting an error "_reactRouter.match is not a function" when attempting to install and start the server. In order to get around this error I had to downgrade React-Router from v4.1.2 to v3.0.5. There were several breaking changes introduced from v3 to v4 and this repo only worked on v3.

SASS implementation example

First, thank you for this boilerplate.

I tried implementing sass in my own but didn't manage to get it working, errors were popping everywhere, could you please provide an example configuration?

Thanks.

Error: Cannot find module './routes'

After install and start, there is error of missing module.

Error: Cannot find module './routes'

To fix this, you need to correct typo on line 6 in app/Router.js './routes.js' => './Routes.js' .

Possible issue with declaring production environments

I've been having a bug with this where the script line in the Root.js file always pulls in the minified version of the file regardless of which build I'm using.

I changed my root code to
<script src={process.env.NODE_ENV != 'production' ? '/app.js' : '/app.min.js'} />

That fixed it but not sure if it's due to an error I've made on my end or it's always receiving 'default' regardless of the build options?

Add to redux docs

Redux docs have an example for server-side rendering, and one for use with react-router, but no example that combines both.

Most starter kits that show up on google are so sophisticated and complicated that they are useless... They are more proof of concept of what can be done.

This universal-react starter-kit was very useful to me to understand how to initialize data both on server and on client. IMO it could be part of redux docs.

What about styles?

How does this boilerplate handle styles in the server and the client?
I see no css, scss, less etc.

HTTP 200 is sent on page not found

When a page is not found the response from the server is an HTTP 200 instead of 404.

Example:
http://localhost:3000/asdf returns 200 status

Removing <Route path="*" component={NoMatch} /> in Routes.js fixes this, but the NoMatch component doesn't render correctly (it should render as a child of Appcomponent)

ES6 in webpack.prod.config

Hello,

I solved it with a babel-register.js at root and modifying changing the "npm run build" script's config to "babel-register.js"

require('babel/register');
module.exports = require('./webpack.production.config.js');
"build": "NODE_ENV=production webpack --config ./babel-register.js --progress --profile --colors"

Built error: "BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders. You need to specify 'babel-loader' instead of 'babel'."

> npm run build

[email protected] build /home/matt/code/universal-react
NODE_ENV=production webpack --config ./webpack.production.config.js --progress

Hash: 8b7ef33165a3b507df89
Version: webpack 2.2.1
Time: 58ms

ERROR in Entry module not found: Error: Can't resolve 'babel' in '/home/matt/code/universal-react'
BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.
                 You need to specify 'babel-loader' instead of 'babel'.

npm ERR! Linux 4.4.0-59-generic
npm ERR! argv "/home/matt/.nvm/versions/node/v4.3.2/bin/node" "/home/matt/.nvm/versions/node/v4.3.2/bin/npm" "run" "build"
npm ERR! node v4.3.2
npm ERR! npm  v2.14.12
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `NODE_ENV=production webpack --config ./webpack.production.config.js --progress`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build script 'NODE_ENV=production webpack --config ./webpack.production.config.js --progress'.
npm ERR! This is most likely a problem with the universal-react package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     NODE_ENV=production webpack --config ./webpack.production.config.js --progress
npm ERR! You can get their info via:
npm ERR!     npm owner ls universal-react
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /home/matt/code/universal-react/npm-debug.log

Immutable

Hi thanks for your example.
But I have a little problem.
Inside my reducers I wont to use immutableJS.

const { Map } from 'immutable';
const initialState = Map({});

export const someReducer = ( store = initialState, action ) => {
// store is not immutable object and don't have any methods from immutableJS :(
}

Unable to add styles

module: {
    loaders: [
      {
        test: /\.js?/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'app'),
      },
      {
        test: /\.scss$/,
        loader: 'style-loader!css-loader!sass-loader',
        include: path.join(__dirname, 'app')
      }
    ]
  }
SyntaxError: /Users/evan/code/universal-react/app/style.scss: Unexpected token, expected ; (1:5)
> 1 | body {
    |      ^
  2 |   text-align: center;
  3 | }

This project is apparently unable to allow for the addition of CSS modules via webpack

Getting Code Splitting to work

Possible just a feature request if you have time (I'll put a pull request if I work it out) but this one has me a bit stuck and I'm still a bit of newbie with React. I'm trying to get code splitting to work on routes but can't find documentation that works with and the webpack 3.4.1 instructions don't work for me either.

My current guess is that node can't work with the newer import() operator. If I switch it out to require() I can get the server to start up. If I then switch it over to import() it will generate the files so I know webpack is at least working with it but then Node will error out.

Any ideas?

Error

webpack: Compiled successfully.
TypeError: Cannot read property 'initialValue' of undefined
at domOnlyProps (/home/megha/public_html/universal-react/app/containers/header.js:8:22)
at Header.render (/home/megha/public_html/universal-react/app/containers/header.js:38:741)
at /home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:796:21
at measureLifeCyclePerf (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:75:12)
at null.ReactCompositeComponent._renderValidatedComponentWithoutOwnerOrContext (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:795:25)
at null.ReactCompositeComponent._renderValidatedComponent (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:822:32)
at null.ReactCompositeComponent.performInitialMount (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:362:30)
at null.ReactCompositeComponent.mountComponent (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:258:21)
at Object.ReactReconciler.mountComponent (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactReconciler.js:46:35)
at null.ReactCompositeComponent.performInitialMount (/home/megha/public_html/universal-react/node_modules/react-dom/lib/ReactCompositeComponent.js:371:34)
screenshot from 2017-04-13 14-41-41

Adding universal CSS import support

Hey! First of all, I must say I'm really impressed with all the work you've done on this project and the simplicity it has with such non-trivial task of setting up universal react stack!

Motivation

These are the points I want to achieve:

  • Each component imports its styles from separate CSS/Sass file,
  • During development, normal css-loader is used, with HMR support.
  • On production extract-text-plugin is used to generate separate stylesheet so there is no flash of unstyled server-rendered content.

Problem

Actually, I got stuck right at the first point above. What I did is I changed following code in webpack.config.js:

module: {
    loaders: [
      {
        test: /\.js?$/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'app'),
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
            options: {
              sourceMap: true,
            },
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },

and added simple import in app/components/UserCard.js:

import React from 'react';
import PropTypes from 'prop-types';
import './UserCard.css'; // Simple CSS import

const UserCard = ({ user }) => (
/* ... */

and after running npm start babel blew up:

/Users/krzksz/Sites/universal-react/node_modules/babel-core/lib/transformation/file/index.js:590
      throw err;
      ^

SyntaxError: /Users/krzksz/Sites/universal-react/app/components/UserCard.css: Unexpected token, expected ; (1:3)
> 1 | ul {
    |    ^
  2 |   background: yellow;
  3 | }
  4 |
    at Parser.pp$5.raise (/Users/krzksz/Sites/universal-react/node_modules/babylon/lib/index.js:4454:13)

Funny thing is that if I add this import after the server has started, webpack is parsing it correctly, even HMR works. Unfortunately, it is not the case on production build.

Cause

As far as I understand babel is trying to follow my import for CSS file but it obviously can't understand it, which is due to this require:
https://github.com/DominicTobias/universal-react/blob/7a25583f54ca1093bde8a2947f1511be7fe9b477/server.js#L48
In order for it to work, webpack would probably be needed to also make a separate server bundle.

Solution

I'm not really sure here so maybe you can give some insight. If I understand correctly then we would have to introduce separate webpack builds for server and client code, which would introduce some complexity and I'm not really sure I'm up for the challenge ๐Ÿค”

Hot reload not working (windows 8.1)

Can't speak for everyone, but I had to modify a couple of things to get hot reload to work on windows.

First, remove localhost binding in server.js (reference).

server.listen(port, (err) => {
    if (err) {
        console.error(err);
    }
    console.info('==> ๐ŸŒŽ Listening on port %s. Open up http://localhost:%s/ in your browser.', port, port);
});

Also, add base public path in webpack.config (reference).

output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
    publicPath: '/'
},

Pass cookies to server side fetch.

Hey!

Trying your React starter project and I like it! :)

I have a question though.

The first thing I do when I start the app is to check whether the user is logged in ( Stormpaths access_token in cookie by calling /me), any ideas on how to use it on the server-side rendering?

For now I get unauthorised all the time, probably because the accept-token isn't used when the server calls /me.

app/index.js: Unexpected token (2:7)

Hello, when i run "npm start" i got an error:

SyntaxError: /Volumes/Mac Data/Users/Elias/noteshare/app/index.js: Unexpected token (2:7)
  1 | import 'isomorphic-fetch';
> 2 | export serverMiddleware from './Router';
    |        ^

Here my log:
npm-debug copy.txt

Any ideas?

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.