├── .gitignore ├── README.md ├── app ├── client │ ├── app.js │ ├── components │ │ └── app.jsx │ └── stylesheets │ │ └── main.scss ├── server │ ├── index.js │ └── routes │ │ └── index.js └── static │ ├── css │ └── main.css │ ├── index.html │ └── js │ └── bundle.js ├── gulpfile.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-boilerplate 2 | 3 | Simple React.js app boilerplate, using the following: 4 | 5 | * React (0.14) 6 | * Express (4.x) 7 | * Browserify (12.x) + Babelify, Reactify, Minifyify (when `$NODE_ENV` equals `production`) and Watchify 8 | * Gulp 9 | * `gulp-live-server` (which includes LiveReload for client-side js/css) 10 | * SASS 11 | 12 | ### Gulp tasks 13 | 14 | ##### `$ gulp js` 15 | 16 | Generate `app/static/js/bundle.js` from `app/client/app.js` using Browserify. 17 | 18 | ##### `$ gulp css` 19 | 20 | Generate `app/static/css/main.css` from `app/client/stylesheets/main.scss` using SASS. 21 | 22 | ##### `$ gulp serve` 23 | 24 | Runs `js` and `css` tasks and subsequently starts the Express app (`app/server/index.js`) and installs watchers for frontend and backend file changes. 25 | 26 | ### Directory structure 27 | 28 | ``` 29 | . 30 | ├── README.md 31 | ├── gulpfile.js 32 | ├── package.json 33 | └── app 34 |    ├── client 35 |    │   ├── app.js // React entry point 36 |    │   ├── components // React components 37 |    │   │   └── app.jsx 38 |    │   └── stylesheets // SASS stylesheets 39 |    │   └── main.scss 40 |    ├── server 41 |    │   ├── index.js // Express entry point 42 |    │   └── routes 43 |    │   └── index.js 44 |    └── static 45 |    ├── index.html 46 |    ├── css 47 |    │   └── main.css // Generated by SASS 48 |    └── js 49 |    └── bundle.js // Generated by Browserify 50 | ``` 51 | -------------------------------------------------------------------------------- /app/client/app.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | var App = require('./components/app.jsx'); 4 | 5 | ReactDOM.render(, document.getElementById('app')); 6 | -------------------------------------------------------------------------------- /app/client/components/app.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | module.exports = React.createClass({ 4 | displayName : 'App', 5 | render() { 6 | return

Hello World

; 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /app/client/stylesheets/main.scss: -------------------------------------------------------------------------------- 1 | // Main SASS stylesheet 2 | -------------------------------------------------------------------------------- /app/server/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var server = app.listen(3013); 4 | 5 | // Middleware. 6 | app.use(require('morgan')('combined')); 7 | app.use(require('compression')()); 8 | app.use(express.static('./app/static')); 9 | 10 | // Routes. 11 | app.use(require('./routes')(app)); 12 | -------------------------------------------------------------------------------- /app/server/routes/index.js: -------------------------------------------------------------------------------- 1 | var Router = require('express').Router; 2 | 3 | module.exports = function(app) { 4 | var router = Router(); 5 | // ... 6 | return router; 7 | }; 8 | -------------------------------------------------------------------------------- /app/static/css/main.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertklep/react-boilerplate/95e20e14568d99ccc9ab0d742dc4e6b6a7fd4132/app/static/css/main.css -------------------------------------------------------------------------------- /app/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | react-boilerplate 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/static/js/bundle.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robertklep/react-boilerplate/95e20e14568d99ccc9ab0d742dc4e6b6a7fd4132/app/static/js/bundle.js -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var gls = require('gulp-live-server'); 3 | var sass = require('gulp-sass'); 4 | var source = require('vinyl-source-stream'); 5 | var browserify = require('browserify'); 6 | var minifyify = require('minifyify'); 7 | var babelify = require('babelify'); 8 | var IS_PRODUCTION = process.env.NODE_ENV === 'production'; 9 | 10 | var paths = { 11 | main_css : [ 'app/client/stylesheets/main.scss' ], 12 | css : [ 'app/client/stylesheets/**/*.scss' ], 13 | main_js : [ 'app/client/app.js' ], 14 | js : [ 'app/client/**/*.js*' ], 15 | }; 16 | 17 | gulp.task('css', function() { 18 | return gulp .src(paths.main_css) 19 | .pipe( 20 | sass({ 21 | outputStyle: IS_PRODUCTION ? 'compressed' : 'nested' 22 | }).on('error', sass.logError) 23 | ) 24 | .pipe(gulp.dest('app/static/css/')); 25 | }); 26 | 27 | gulp.task('js', function() { 28 | var bundler = browserify(paths.main_js) 29 | .transform('babelify', { 30 | presets : [ 'es2015', 'react' ] 31 | }); 32 | 33 | if (IS_PRODUCTION) { 34 | bundler = bundler.plugin('minifyify', { 35 | map : false, 36 | compress : { 37 | drop_debugger : true, 38 | drop_console : true 39 | } 40 | }) 41 | } 42 | 43 | bundler.bundle().on('error', function(err) { 44 | console.error('[browserify error]', err.message); 45 | }).pipe(source('bundle.js')) 46 | .pipe(gulp.dest('app/static/js')); 47 | }); 48 | 49 | gulp.task('serve', [ 'css', 'js' ], function () { 50 | // Generic watch tasks for SASS and Browserify 51 | gulp.watch(paths.css, [ 'css' ]); 52 | gulp.watch(paths.js, [ 'js' ]); 53 | 54 | // Start the app server. 55 | var server = gls('app/server/index.js', { stdio : 'inherit' }); 56 | server.start(); 57 | 58 | // Reload server when backend files change. 59 | gulp.watch([ 'app/server/**/*.js' ], function() { 60 | server.start.bind(server)(); 61 | }); 62 | 63 | // Notify server when frontend files change. 64 | gulp.watch([ 'app/static/**/*.{css,js,html}' ], function(file) { 65 | server.notify(file); 66 | }); 67 | }); 68 | 69 | gulp.task('default', [ 'css', 'js' ]); 70 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-boilerplate", 3 | "version": "1.0.0", 4 | "description": "React.js boilerplate (+ Stylus + Browserify + Watchify + LiveReload)", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "Robert Klep ", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "babel-preset-es2015": "^6.1.18", 13 | "babel-preset-react": "^6.1.18", 14 | "babelify": "^7.2.0", 15 | "browserify": "^12.0.1", 16 | "gulp": "^3.9.0", 17 | "gulp-live-server": "0.0.29", 18 | "gulp-sass": "^2.1.0", 19 | "minifyify": "^7.1.0", 20 | "vinyl-source-stream": "^1.1.0", 21 | "watchify": "^3.6.0" 22 | }, 23 | "dependencies": { 24 | "compression": "^1.6.0", 25 | "express": "^4.13.3", 26 | "morgan": "^1.6.1", 27 | "react": "^0.14.2", 28 | "react-dom": "^0.14.2" 29 | } 30 | } 31 | --------------------------------------------------------------------------------