Thursday, June 15, 2017

MERN Series Step 7 - Job models and components


Ok, finally got past the stupid webpack issue that was causing a complete gulp fail.  You need to add one more require at the top, and modify the webpack task:
const path = require('path');

gulp.task('webpack', cb => {
webpack({
entry: './app/scripts/webpack.js',
output: {
path: path.resolve(__dirname, '.tmp/scripts/'),
filename: 'bundle.js',
},
}, (err, stats) => {
if (err) {
throw new gutil.PluginError('webpack', err);
}
cb();
});
});

However, there would need to be lots of modifications to my gulpfile.js, so I'm just going to go with the one from the mern framework from techdojo, start up your server using gulp serve and you're off and running with a lovely MERN page

Configure your eslint to work with react:

Something I'm not fond of with this framework at the moment, but this may be in place for server side rendering for search engines or something, but you have to have routes defined on both the server and the client in order to enable both navigation by clicking, or by entering the URL into the browser.  I stumbled on this after creating a new route in /app for my jobs list, but not putting the route in the server, I could get to the page by clicking the link/button, but not entering the URL.

I'm moving on to create back end models in the server code and front end components to display and edit Jobs since what I really want to do with this is learn React and I've not been doing much of that so far, just mucking with Auth0.  I'll finish up the setup for Auth0 once I've got some basic React components and server models set up before doing searching or any more complicated stuff with React.

The yomern yo generator looks like it does a nice job setting up a basic CRUD module both server and app, so  I'll be going with that to create my Jobs module.

C:\Repos\mern [master ≡ +0 ~10 -0 !]> yo yomern
Hello There Fellow MERN User
? What is your module name? Job
? Would you like to generate a new CRUD component ? Yes
Add the front-end routes for the module in app.jsx, add the backend-routes in routeHelper.js, require the backend-route file in the express.js file and require the model in server.js file
? Add a field name to the model Id
? Would you like to add another field name to the model? Yes
? What is your other field name? Description
   create app\components\jobs\CreateJob.jsx
   create app\components\jobs\EditJob.jsx
   create app\components\jobs\ViewJob.jsx
   create app\components\jobs\ViewJobChild.jsx
   create app\components\jobs\ListJobs.jsx
   create app\components\jobs\ListJobsChild.jsx
   create app\components\jobs\Form.jsx
   create app\stores\JobStore.jsx
   create server\models\Job.js
   create server\controllers\jobs.server.controller.js
   create server\routes\job.server.routes.js
C:\Repos\mern [master ≡ +5 ~10 -0 !]>

So, this was very convenient, it generated classes for both the client side app and the server side app, creating basic crud templates, routes, and models with the properties I entered.  I would recommend not calling one of the fields Id, it generates an _id field for you, so I went through and renamed my Id field to Title, I had to touch the jsx files for Create, Form, ListJobsChild, and ViewJobsChild, and server side it was just the Jobs.js in the models.  These are also the files you would have to modify in order to add additional properties.  While the generator does create the server side routes file for you, it does not add it to your routerHelper.js, this should be as easy as copy/paste/rename from one of the sets of routes already in there.  You will also need to set up your routes on the client side in App.jsx, again, copy/paste/rename, really easy.

Saturday, May 20, 2017

MERN Series Step 6 - Auth0 with Tech-Dojo

With the copying of files from the create-react-app auth0 scripts our tech-dojo mern app still runs fine, and the tests all run as well, except for the one that was failing at the start (1) should fail to save an existing user again).  Don't forget to have mongodb running for the unit tests.
Now we'll wire up the auth0 login/signup instead of the login/signup that is in the tech-dojo starter.  Step 1, add the login component from auth0 to app/components/App.jsx by inserting import Login from './auth/Login.js'; to the bottom of the imports section.  Step 2, add a route so we can get to the login component, the routes section should be pretty obvious, it has about 10 lines starting with <Route …>, so I'm adding         <Route path="/login" component={Login} /> to the bottom of that.  Now lets open the site and see what happens.

Hmm, ok, middle of the page is missing content, and the dev tools console says:

app\components\App.jsx:33 Uncaught ReferenceError: Login is not defined
    at new exports.default (app\components\App.jsx:33)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:148)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (ReactPerf.js:66)
    at Object.mountComponent (ReactReconciler.js:37)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:225)
    at ReactCompositeComponentWrapper.wrapper [as mountComponent] (ReactPerf.js:66)
    at Object.mountComponent (ReactReconciler.js:37)
    at mountComponentIntoNode (ReactMount.js:266)
    at ReactReconcileTransaction.perform (Transaction.js:136)
    at batchedMountComponentIntoNode (ReactMount.js:282)

Ok, so looking closer at /app/components/auth/login.js I see:
import {login} from '../auth';
So it looks like I moved the auth.js file one folder to high, so move it from the apps folder to the components folder.

After the move, now I get this in the console:
C:/Repos/mern/app/components/auth.js: Unexpected token (67:10) while parsing file: C:\Repos\mern\app\components\auth.js
  65 | export function connectProfile(WrappedComponent) {
  66 |   return class ProfileContainer extends Component {
> 67 |     state = {
     |           ^
  68 |       profile: null
  69 |     };
  70 |

Ok, no idea here what's going on.  Taking a step back and going to make sure the create-react-app with auth0 customizations that I started from is working, and it appears that it's not, so I'm going to get that working first and hopefully that will either solve my issues or point me in the right direction.  Looking at the generic create-react-app w/o the auth0 additions and that works fine, so I have likely missed something I need to do to enable auth0 to work.

Running the base auth0 app and I'm getting this:
warning.js:36 Warning: Failed prop type: The prop `history` is marked as required in `Router`, but its value is `undefined`. in Router (at App.js:12) in App (at index.js:7)
After hunting through the results in google, looks like react-router has changed significantly since the auth0 scripts were created, they should probably have that pinned to ^3.0.5 until they update the routes to be 4.x compliant.  To get it running I had to update packages.json to use
    "react-router": "^3.0.5"
And remove the entry for react-router-dom (it's only for 4.x version of react-router).  Once that change was made make sure your server isn’t running, do npm i and restart your server and it should work.  One other thing to note, when you're putting your client key and domain in, make sure you remove the curly braces, that's not evident until you look at the errors in the console.

So, now with my base auth0 react-app running fixing the tech-dojo version should be easy. Still getting this error:
C:/Repos/mern/app/components/auth.js: Unexpected token (67:10) while parsing file: C:\Repos\mern\app\components\auth.js
  65 | export function connectProfile(WrappedComponent) {
  66 |   return class ProfileContainer extends Component {
> 67 |     state = {
     |           ^
  68 |       profile: null
  69 |     };
  70 |

Update dependencies in package.json, several missing or out of date:
  "dependencies": {
    "async": "^1.5.0",
    "auth0-lock": "^10.14.0",
    "babel": "^6.0.0",
    "babel-core": "^6.2.1",
    "babel-loader": "^6.1.0",
    "babel-preset-es2015": "^6.1.2",
    "babel-preset-react": "^6.1.2",
    "babelify": "^7.2.0",
    "body-parser": "^1.12.4",
    "connect-mongo": "^1.0.2",
    "cookie-parser": "^1.4.0",
    "cors": "^2.6.0",
    "dotenv": "^4.0.0",
    "ejs": "^2.3.1",
    "events": "^1.1.1",
    "express": "^4.15.2",
    "express-jwt": "^5.3.0",
    "express-session": "^1.15.2",
    "glob": "^6.0.1",
    "guid": "0.0.12",
    "gulp-uglify": "^1.5.3",
    "history": "1.17.x",
    "jquery": "^2.1.4",
    "jwt-decode": "^2.2.0",
    "lodash": "^3.10.1",
    "mongoose": "4.0.3",
    "node-jsx": "^0.13.3",
    "nodemailer": "^1.10.0",
    "object.assign": "4.0.3",
    "passport": "^0.3.2",
    "passport-auth0": "^0.6.0",
    "passport-local": "^1.0.0",
    "react": "^15.5.4",
    "react-bootstrap": "^0.28.1",
    "react-dom": "^15.5.4",
    "react-router": "^3.0.5",
    "react-router-bootstrap": "^0.20.1",
    "react-slick": "^0.9.3",
    "react-tools": "^0.13.3",
    "reactcss": "^0.4.2",
    "reactify": "^1.1.1",
    "source-map": "^0.5.2",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0"
  },
 and run npm I to install them

And we still get this:
C:/Repos/mern/app/components/auth.js: Unexpected token (67:10) while parsing file: C:\Repos\mern\app\components\auth.js
  65 | export function connectProfile(WrappedComponent) {
  66 |   return class ProfileContainer extends Component {
> 67 |     state = {
     |           ^
  68 |       profile: null
  69 |     };
  70 |

So, integrating the auth0 scaffolding from create-react-app may not be the way to go, not sure but there may be something in there dependent on what react-scripts does.  I'm going to look at pulling in the code from the 01-login example from auth0 that doesn't use create-react-app.

Insert these transforms after the babelify tranform:
    .transform("brfs")
    .transform("ejsify")
    .transform("reactify")

You'll need to add brfs and ejsify to your package.json also
Npm I --save-dev brfs
Npm I --save-dev ejsify

Now I'm getting:
[08:03:41] WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.output.path: The provided value ".tmp/scripts/" is not an absolute path!
    at webpack (C:\Repos\ItSideJobs\web\node_modules\webpack\lib\webpack.js:19:9)
    at Gulp.gulp.task.cb (C:\Repos\ItSideJobs\web\gulpfile.js:36:3)
    at module.exports (C:\Repos\ItSideJobs\web\node_modules\orchestrator\lib\runTask.js:34:7)
    at Gulp.Orchestrator._runTask (C:\Repos\ItSideJobs\web\node_modules\orchestrator\index.js:273:3)
    at Gulp.Orchestrator._runStep (C:\Repos\ItSideJobs\web\node_modules\orchestrator\index.js:214:10)
    at Gulp.Orchestrator.start (C:\Repos\ItSideJobs\web\node_modules\orchestrator\index.js:134:8)
    at C:\Users\David\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:129:20
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)
    at Module.runMain (module.js:606:11)

Saturday, April 22, 2017

"React components, do you need class to do them properly?" -or- "local state, It's a trap!"


So, I'm looking at https://facebook.github.io/react/docs/state-and-lifecycle.html and how React has leveraged the class construct and hierarchy in encapsulating the clock class in the example. I'm wondering, is the class construct necessary, and I'm very much hoping it is not. I'm going to try to re-create the example without using the class and extends and sticking with functional javascript. We already know you can use stateless functional components, but can we use local state in a functional component.

It would seem not entirely, you need a stateful component somewhere in your application. It looks like the right place for this is as close to the root of the application as you can get it, if you want to move toward having a single state atom (which looks extremely beneficial). So how can we re-write the react clock example using a stateless functional component.

<div id="container"> 
<!-- This element's contents will be replaced with your component. --> 
</div> 

function Clock(props) { 
    return <div><h1>Hello, world! </h1> <h2>It is {props.date.toLocaleTimeString()}. </h2></div> 
} 

var App = React.createClass({ 
    getInitialState: function() { 
        return { date: new Date() }; 
    }, 
    render: function() { 
        return <Clock date={this.state.date} />; 
    }, 
    componentDidMount: function() { 
        this.timerID = setInterval(() => this.setState({date: new Date()}),1000); 
    } 
}); 

 
ReactDOM.render( <App /> , 
    document.getElementById('container') 
); 


So, this gets the application state all in one place, in the App class, which we can persist or restore atomically, enabling time travel debugging and keeping us from getting in an inconsistent state. This doesn't necessarily mean you want all state in one place, just that relevant to App.

https://facebook.github.io/react/docs/state-and-lifecycle.html
https://www.safaribooksonline.com/blog/2015/10/29/react-local-component-state/
https://hackernoon.com/react-stateless-functional-components-nine-wins-you-might-have-overlooked-997b0d933dbc

https://github.com/reactjs/redux/issues/1385

MERN Series Step 5 - Auth0 React Client Template


Reviewing the link from last time, https://auth0.com/docs/quickstart/spa/react, let's see what the create-react-app scripts get us.

This also led me to the link for the facebook create-react-app scripts: https://github.com/facebookincubator/create-react-app, I'll review and compare that as well in this article.

It looks like the create-react-app script is focused on the client side portion of the app, which makes sense, and the folder structure is somewhat different than that provided by tech-dojo's start repo (https://github.com/tech-dojo/mern, so they're all in one place).

For review, here's the structure tech-dojo gave us:

| .gitignore 
| CONTRIBUTING.md 
| favicon.ico 
| gulpfile.js 
| LICENSE 
| package.json 
| README.md 
| yarn.lock 
+---app 
| | .DS_Store 
| | index.ejs 
| | main.jsx 
| | style.css 
| | 
| +---components 
| | | App.jsx 
| | | 
| | +---articles 
| | | CreateArticle.jsx 
| | | EditArticle.jsx 
| | | Form.jsx 
| | | ListArticles.jsx 
| | | ListArticlesChild.jsx 
| | | ViewArticle.jsx 
| | | ViewArticleChild.jsx 
| | | 
| | +---core 
| | | Footer.jsx 
| | | Header.jsx 
| | | Home.jsx 
| | | Template.jsx 
| | | 
| | \---users 
| | EditUserProfile.jsx 
| | EditUserProfileChild.jsx 
| | Signin.jsx 
| | SigninChild.jsx 
| | SignOut.jsx 
| | Signup.jsx 
| | SignupChild.jsx 
| | 
| +---images 
| | | … 
| | | 
| | \---fav 
| | … 
| | 
| +---services 
| | Authentication.js 
| | 
| \---stores 
| ArticleStore.jsx 
| RestAPI_Helper.js 
| UserStore.jsx 
+---server 
| | express.js 
| | passport.js 
| | seeds.js 
| | server.js 
| | 
| +---config 
| | | config.js 
| | | 
| | \---env 
| | all.js 
| | development.js 
| | local.example.js 
| | production.js 
| | test.js 
| | 
| +---controllers 
| | | .DS_Store 
| | | articles.server.controller.js 
| | | errors.server.controller.js 
| | | users.server.controller.js 
| | | 
| | \---users 
| | users.authentication.server.controller.js 
| | users.authorization.server.controller.js 
| | users.password.server.controller.js 
| | users.profile.server.controller.js 
| | 
| +---models 
| | .DS_Store 
| | Article.js 
| | User.js 
| | 
| +---routes 
| | .DS_Store 
| | article.server.routes.js 
| | routeHelper.js 
| | users.server.routes.js 
| | 
| \---strategies 
| facebook.js 
| github.js 
| google.js 
| linkedin.js 
| local.js 
| twitter.js 
\---tests 
| article.server.model.test.js 
| article.server.routes.test.js 
| user.server.model.test.js 
\---componentTest 
article.test.jsx 
articleStore.test.jsx 
user.test.jsx 
userStore.test.jsx 

This does contain some potentially extraneous items that someone not initially learning React may not need (i.e. articles, users), and yes, I know lots of "may" in there. I am learning React, so I can't tell you that yet.

Facebook's vanilla create-react-app script gives you this structure:

| .gitignore
| package.json
| README.md
|
+---public
| favicon.ico
| index.html
|
\---src
App.css
App.js
App.test.js
index.css
index.js
logo.svg

They have a great section on why to use this for creating your app, and how to customize it in the future if you need to: https://github.com/facebookincubator/create-react-app#why-use-this. This structure seems a bit more simplistic than I'd like, having everything in the src folder, but may be good for getting something up and going quickly.

Installing the auth extensions to the facebook app using create-react-app my-app1 --scripts-version auth0-react-scripts gives the same basic structure, but at least has a components folder under src, and the addition of auth0 stuff.

| .env.example 
| .gitignore 
| package.json 
| README.md 
+---public 
| favicon.ico 
| index.html 
\---src 
| auth.js 
| index.css 
| index.js 
| logo.svg 
\---components 
App.js 
App.test.js 
EditProfile.css 
EditProfile.js 
Home.css 
Home.js 
Login.css 
Login.js 
Site.css 
Site.js 

So, I'll be sticking with my initial layout, and just copy the auth0 stuff from the components folder generated by the auth0 extensions to create-react-app into an auth folder under my components folder, so it will end up looking like this:

| +---components 
| | | App.jsx 
| | | 
| | +---articles 
| | | CreateArticle.jsx 
| | | EditArticle.jsx 
| | | Form.jsx 
| | | ListArticles.jsx 
| | | ListArticlesChild.jsx 
| | | ViewArticle.jsx 
| | | ViewArticleChild.jsx 
| | | 
| | +---core 
| | | Footer.jsx 
| | | Header.jsx 
| | | Home.jsx 
| | | Template.jsx 
| | | 
| | +---users 
| | | EditUserProfile.jsx 
| | | EditUserProfileChild.jsx 
| | | Signin.jsx 
| | | SigninChild.jsx 
| | | SignOut.jsx 
| | | Signup.jsx 
| | | SignupChild.jsx 
| | \---auth 
| | EditProfile.css 
| | EditProfile.js 
| | Login.css 
| | Login.js 

There's also an auth.js in the src folder one layer up from components that I'm copying over also. So that's going to be my basic layout with auth0, next article I'll cover anything needed to integrate and get everything running with the MERN starter project from tech-dojo.

x
x

Sunday, April 16, 2017

Learn to code deal

https://academy.sciencealert.com/sales/pwyw-learn-to-code-2017-google-go?utm_source=sciencealert.com&utm_medium=referral&utm_campaign=pwyw-learn-to-code-2017-google-go_020217&utm_term=scsf-211745

Learn to code package.  I haven't tried anything from these people, I'm going to try this one though, has a lot of languages I want to learn more about.

Friday, April 14, 2017

MERN Series Step 4 - Authentication with Auth0

https://auth0.com/docs/overview
They have a great intro video, watch it.

Our starter project already came with passport, so we'll just need to add passport-auth0 and express-session:
Yarn add passport-auth0 express-session auth0-lock


Looking at the architecture options, SPA+API looks like a natural fit to pursue: https://auth0.com/docs/architecture-scenarios/application/spa-api

You can also use the spa quickstart https://auth0.com/docs/quickstart/spa/react, that looks like it has some scripting that would be useful, I'll review that and compare in the next article.

You may also want to review JWTs as auth0 uses them, and they are beyond the scope of what I'm writing about in this series, I may get into some more detail later, but my focus with this series is not on JWTs.

First step, create a new account with the website name, then select Single Page App for the application type:

This will then present you with a sample project you can download (that will have your keys in it).  I've downloaded mine, it looks like the two files you'll need are in src/utils, with the rest of the code showing how to integrate into your app.  The .env file in the root contains your auth0 clientid and domain.  The code in src/views/Main/routes.js has examples of how to protect routes using react-router.  You can run the project itself using npm start, it just serves up a page with a login control that opens the auth0 login widget. 


Run it and try to log in and it will fail with CORS error.  Take a look at the logs for your auth0 Client (the application)


This means that we'll need to add http://localhost:3000 in order to have our sample auth0 app to connect.  Click on Clients, then on your app (mine is still "Default App") then settings, scroll down to "Allowed Origins (CORS)" and add http://localhost:3000, while you're there add http://localhost:3000/login to the "Allowed Callback URLs" area, as the sample app uses that for where auth0 sends data back to it.  Once you've done that you'll be able to login using one of the providers you've enabled (I enabled google and linked-in since this is a job board), and you should see a lovely landing page with welcoming you by name (nice!), with a logout button.

We'll take this sample app and incorporate it into our main application.  I'll be using a login widget instead of the full page layout of the auth0 sample, but beyond that we'll leave it the same.  We'll also use auth0 for authorization once we get to where we have multiple roles for our app.  Now, since we've logged into our app, you'll be able to see yourself as a user and view details.  Check it out under users:

Sunday, April 9, 2017

MERN Series Step 3 - Which client app

After looking at the two clients, one from generator-webapp and the other from tech-dojo's starter repo, I'm going to go with the app from tech-dojo, as it's structure is laid out for react components and services, vs generator-webapp is pretty generic and I'd have to do all the react setup myself.
Generator-webapp gives you an app folder with fonts, images, scripts and styles, which is fine for your generic client side app.  It also gives you a decent gulpfile to start with, and a tests folder using mocha and chai.
Tech-dojo's MERN starter gives you an app folder with components (with some examples coded, articles, core, and users), images, services, and stores, a gulpfile that I'm not familiar with yet, tests using mocha/chai/sinon with tests set up to run against the components, and you also get test coverage reporting.  On top of that you get the server folder set up to use express, mongoose, passport, and some seed data for the example components.
 
So, basically if you're reading these all in one go, skip everything I did in step one :) I'll be updating the article to reflect this new information and moving on to setting up login next using auth0, because security is hard and I don't have time to stay on top of it, and it’s their job to do so.  
Which brings me to a general point, if something is not part of your core business, don’t write it if you don't have to!  I'm not going to re-write paypal functionality if I want to take payments, nor am I going to write an email service.  Bring in something open source, or buy it if you need to, but only write it if you have to. 

Saturday, April 8, 2017

MERN Series Step 2 - MongoDB and yomern

MongoDB installation guide is located here: https://docs.mongodb.com/v3.0/installation/. I am a big fan of chocolatey, so I'll be using chocolatey command line to install it: choco install -y mongodb.

Some handy mongodb commands:
https://docs.mongodb.com/v3.0/tutorial/install-mongodb-on-windows/#run-mongodb

I'm using tech-dojo's MERN framework, read the docs on tech-dojo's page as there is more to it than just the generator, they have a starter in github:
git clone https://github.com/tech-dojo/mern

The starter app uses mocha/chai/sinon stack for testing, which I prefer over Jasmine/Karma. Once installed, verify the app is working by running gulp serve
Run the unit tests using gulp test. I had one user test fail, but everything else passed.

Choosing a generator/starter project is mainly governed by what you want to use in the project. There are several options out there for MERN type stacks, I chose tech-dojo's because it uses the testing stack I'm interested in, as well as using express and mongodb. Some other options that looked promising:
  • mern-cli from http://mern.io for scaffolding and code generation 
  • Accelerate looks like it might be interesting , but appears to be more than just a generator, I may look at it in detail later. 
  • You could probably also get away with using parts of angular-fullstack generator, but that seems like wasting its potential. If you're going with MEAN stack it's definitely the way to go. 
  • Fountain-webapp also look like it could be good, it's using Karma for testing 
  • Last one I'll list, react-fullstack look very popular, but hasn't been updated in a year. 
This process leaves you with both client and server side set up, so I'll need to look at what's in this client vs what I set up using yo webapp in the previous article. I know I don't like currently having both the client and server in the same git repo, and the tests for both client and server are in the tests folder instead of separated. This makes it more difficult to rev them independently. I'll likely at least be splitting the repo into two and split the tests.

I also noticed a number of deprecated packages during the npm install, I will investigate updating all of these after I get the base scaffolding done.

It looks like the yomern yeoman generator is for creating components of functionality, which seems like it would be quite useful to eliminate boilerplate

Tuesday, March 7, 2017

MERN Series Step 1 - Scaffolding and setup

Note: due to decisions made in step 3 of the series, you can skip all steps in here.  Webapp generator is a good generator for a base SPA, but tech-dojo's MERN starter gives you more to begin with.

I'm going to write a series on creating a MERN stack application (MongoDB, Express, React, Node) from scratch to deployment and maintenance.  Why am I going with React instead of Angular?  Well, I've learned some ng1.x with node.js backend, and I like it, and in the process I learned a lot about Javascript.  I tend to agree with most of what Crockford says, and I place great value on the opinions and findings of Eric Elliot, thus my leaning to learn React and not ng > 1.  

The application is going to be a job site type of application.  Yes, I know there are 100's of them out there, but this will hit most what of any application is going to use: Payment, Subscription, Authentication and Authorization, search, DB back end.  I may change out MongoDB for Couchbase, or Amazon DymanoDB, I haven't decided yet.  I'm going to use Amazon Elastic Beanstalk, possibly with Docker containers depending on how complex the back end gets, but I tend to think that won't be necessary at the start.  For front end hosting using S3 as a static website should do fine to start with.

Step 1: Scaffolding with Yeoman
One of the problems I've often seen is where to start with a new application.  Yeoman helps with that by creating a basic project structure for you.  I'm going to start with the webapp generator and add the React recipie, maybe React Router as well, all will be documented.

Starting with yo webapp: (https://github.com/yeoman/generator-webapp#readme) you will be prompted for a couple of items. I included Sass, and Modernizr, and selected TDD for style of DSL.  I am actually going to be using Less, not Sass, but I've cheated and looked ahead, and the Less recipe we'll be following later instructs you to select Sass, but not Bootstrap.  Bootstrap is added later when following the Less recipe.  After your selections it will create your basic file structure, shown below, including starting points for bower.json, package.json, and gulpfile.js, and it will run npm install and bower install for you

     _-----_     ╭──────────────────────────╮
    |       |    │  'Allo 'allo! Out of the │
    |--(o)--|    │    box I include HTML5   │
   `---------´   │ Boilerplate, jQuery, and │
    ( _´U`_ )    │ a gulpfile to build your │
    /___A___\   /│           app.           │
     |  ~  |     ╰──────────────────────────╯
   __'.___.'__
 ´   `  |° ´ Y `

? What more would you like?

 (*) Sass
>( ) Bootstrap
 (*) Modernizr
? What more would you like? (Press <space> to select)Sass, Bootstrap, Modernizr
? Would you like to include jQuery? (Y/n) n
? Choose your style of DSL TDD
   create bower.json
   create package.json
   create gulpfile.js
   create .babelrc
   create .gitignore
   create .gitattributes
   create .bowerrc
   create .editorconfig
   create app\favicon.ico
   create app\apple-touch-icon.png
   create app\robots.txt
   create app\styles\main.scss
   create app\scripts\main.js
   create app\index.html
   create test\spec\test.js
   create test\index.html

I'm all done. Running npm install & bower install for you to install the required dependencies. If this fails, try running the command yourself.


you will end up with a file structure like this:
you will have a reasonable .gitignore, but no git repo set up, so that should be your first step after running the generator
git init
git add *
git commit -m 'initial commit'

It would probably be wise to also add a remote at this point and push code to it, and create a develop branch.  That has our initial scaffold set up, next step is to follow the steps for the recipes we're adding to it.  The webapp page I put the link for above has a recipes link, go to that and we'll start with Less.  Follow the steps on the recipe page to get less working, they're pretty straight forward.  I am adding bootstrap in, and going with the option to add it fully as I don't know what I'm going to be using yet, so we can optimize it later if we need to.

Next up, the React recipe.  This straightforward, no choices to make.  I like to use gulp-inject for getting my app's js files into html pages, so having jsx files in the scripts folder may be an issue, we'll visit that later and see.

Then we're adding React Router for url routing, again, follow the instructions, no choices to be made here.  I did hit a minor hiccup with the recipe instructions.  React is installed as a bower component from the React recipe, but react-router is installed via npm and didn't like that react wasn't there:
npm WARN react-router@3.0.2 requires a peer of react@^0.14.0 || ^15.0.0 but none was installed.  The warning was quashed if you do npm i react --save-dev before installing react-router, not sure if this will cause any issues later.

Finally, we add AWS S3 Deployment recipe.  You'll need an AWS account for this, or deploy using your favorite hosting provider.  I've been working with AWS for a while and find the capability to script out what I want my environments to look like immensely helpful.  I will also follow the advise to utilize asset revisioning, and help to keep my AWS costs lower, so follow that recipe from the AWS S3 Deployment recipe.  FYI, if you haven't served up static site from S3 before, make sure you name the bucket the same as your root website (i.e. for http://somejobsite.com, name your S3 bucket somejobsite.com).  If this is your first time using AWS, you may also need to set up your default credentials so you can publish successfully, see here.  Now you can verify all this with gulp deploy, maybe.  Due to the way the released version of gulp dependencies work, you will get inconsistent results due to race conditions.  I'd recommend using run-sequence plugin, which will take some modifications to your gulpfile and installing another module:
npm i run-sequence --save-dev
Add run-sequence to the declarations in your gulpfile.js:
const runSequence = require('run-sequence');
And last, modify your default task like so:
gulp.task('default', (done=> {
  runSequence('clean''build', () => {
    done();
  });
});

Finally, so we have a good spot to restore to if needed, commit your changes to git
git add *
git commit -m 'scaffolding complete'
git push