├── .babelrc ├── .gitignore ├── README.md ├── bower.json ├── index.html ├── package.json ├── src ├── components │ ├── App │ │ ├── App.js │ │ └── App.scss │ ├── Hello │ │ ├── Hello.js │ │ └── Hello.scss │ └── variables.scss └── index.js └── tools ├── build.js ├── bundle.js ├── clean.js ├── run.js ├── start.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react", "stage-0"], 3 | "plugins": ["syntax-async-functions"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Include your project-specific ignores in this file 2 | # Read about how to use .gitignore: https://help.github.com/articles/ignoring-files 3 | 4 | build 5 | node_modules 6 | bower_components 7 | npm-debug.log 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Webpack and React 4 | 5 |

6 | 7 | # React.js Webpack Starter 8 | 9 | 10 | > A React.js starter kit featuring [React.js](https://facebook.github.io/react/) ([JSX](https://facebook.github.io/react/docs/jsx-in-depth.html), [ES6](https://github.com/lukehoban/es6features#readme), 11 | [Babeljs](https://babeljs.io/), 12 | [PostCSS](https://github.com/postcss/postcss), 13 | [ReactHotLoader](https://github.com/gaearon/react-hot-loader), and [Webpack](http://webpack.github.io/)) by [Grégory D'Angelo](https://gdangelo.fr) for [EloquentWebApp](http://eloquentwebapp.com). 14 | 15 | > If you're looking to learn React.js in depth see [The Complete ReactJS Developer Course : Build Modern UI](http://eloquentwebapp.teachable.com/) 16 | 17 | This seed repo serves as a React.js starter for anyone looking to get up and running with React.js fast. Using a [Webpack](http://webpack.github.io/) for building our files and assisting with boilerplate. 18 | * Best practices in file and application organization for React.js. 19 | * Ready to go build system using Webpack and Babel for working with JSX and ES6. 20 | * A great React.js seed repo for anyone who wants to start their project. 21 | * Style with PostCSS 22 | * Tweak React components in real time with React Hot Loader 23 | 24 | ### Quick start 25 | > Clone/Download the repo then edit React components inside [`/src/components`](/src/components) 26 | 27 | ```bash 28 | # clone the repo 29 | git clone https://github.com/gdangelo/react-starter.git 30 | 31 | # change directory 32 | cd react-starter 33 | 34 | # install the dependencies with npm and bower 35 | npm install && bower install 36 | 37 | # start the server 38 | npm start 39 | ``` 40 | go to [http://0.0.0.0:3000](http://0.0.0.0:3000) or [http://localhost:3000](http://localhost:3000) in your browser 41 | 42 | # Table of Contents 43 | * [File Structure](#file-structure) 44 | * [Getting Started](#getting-started) 45 | * [Dependencies](#dependencies) 46 | * [Installing](#installing) 47 | * [Running the app](#running-the-app) 48 | * [Support, Questions, or Feedback](#support-questions-or-feedback) 49 | 50 | ## File Structure 51 | We use the component approach in our starter. Each component lives in a single folder with each concern as a file: style and component class. Here's how it looks: 52 | ``` 53 | react-starter/ 54 | ├──build/ * Folder for compiled output 55 | │ 56 | ├──src/ * Source files that will be compiled to javascript 57 | | ├──components/ * React components 58 | │ │ └──variables.scss * Global variables for styles 59 | │ │ 60 | │ └──index.js * Entry file for the application 61 | │ 62 | ├──tools/ * Build automation scripts and utilities 63 | │ ├──build.js * Builds the project from source to output (build) folder 64 | │ ├──bundle.js * Bundles the web resources into package(s) through Webpack 65 | │ ├──clean.js * Cleans up the output (build) folder 66 | │ ├──run.js * Helper function for running build automation tasks 67 | │ ├──start.js * Launches the development web server with hot reload 68 | │ └──webpack.config.js * Configurations for bundles 69 | │ 70 | ├──index.html * The index HTML page that includes the bundle 71 | ├──.babelrc * Babel options file use to specify presets and plugins 72 | ├──package.json * What npm uses to manage it's dependencies 73 | └──bower.json * What bower uses to manage it's dependencies 74 | ``` 75 | 76 | # Getting Started 77 | ## Dependencies 78 | What you need to run this app: 79 | * [Node.js](https://nodejs.org/) v5.0 or newer 80 | * `npm` v3.3 or newer (new to [npm](https://docs.npmjs.com/)?) 81 | 82 | ## Installing 83 | * `clone` the repo 84 | * `npm install` to install all npm dependencies 85 | * `bower install` to install all bower dependencies 86 | 87 | ## Running the app 88 | After you have installed all dependencies you can now run the app. Run `npm start` to start a local server using `webpack-dev-server`. The app will be server at `http://0.0.0.0:3000`. 89 | 90 | ## Other commands 91 | 92 | ### build files 93 | ```bash 94 | npm run build 95 | ``` 96 | 97 | ### clean build folder 98 | ```bash 99 | npm run clean 100 | ``` 101 | 102 | # Support, Questions, or Feedback 103 | > Contact me anytime for anything about this repo or React.js 104 | 105 | * Twitter: [@gdangel0](https://twitter.com/gdangel0) 106 | * Email: gregory@gdangelo.fr 107 | * Codementor: [@gdangelo](https://www.codementor.io/gdangelo) 108 | 109 | ___ 110 | 111 | enjoy — Grégory D'Angelo for **EloquentWebApp** 112 | 113 |

114 | 115 |

116 | 117 | React.js Course 118 | 119 |

120 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-starter", 3 | "description": "A React Starter Kit to use as a starting point for working on simple ReactJS app", 4 | "main": "index.js", 5 | "authors": [ 6 | "Grégory D'Angelo" 7 | ], 8 | "license": "ISC", 9 | "keywords": [ 10 | "ReactJS" 11 | ], 12 | "homepage": "https://github.com/gdangelo/react-starter", 13 | "moduleType": [], 14 | "private": true, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ], 22 | "dependencies": { 23 | "bootstrap": "~3.3.6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | React Starter 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-starter", 3 | "version": "1.0.0", 4 | "description": "A React Starter Kit to use as a starting point for working on simple ReactJS app", 5 | "main": "index.js", 6 | "scripts": { 7 | "clean": "babel-node tools/run clean", 8 | "bundle": "babel-node tools/run bundle", 9 | "build": "babel-node tools/run build", 10 | "start": "babel-node tools/run start" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/gdangelo/react-starter.git" 15 | }, 16 | "keywords": [ 17 | "ReactJS, Webpack, Babel, Sass" 18 | ], 19 | "author": "Grégory D'Angelo", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/gdangelo/react-starter/issues" 23 | }, 24 | "homepage": "https://github.com/gdangelo/react-starter#readme", 25 | "devDependencies": { 26 | "babel-loader": "^6.2.0", 27 | "babel-plugin-react-transform": "^1.1.1", 28 | "babel-preset-react": "^6.3.13", 29 | "del": "^2.2.0", 30 | "react-hot-loader": "^1.3.0", 31 | "react-transform-catch-errors": "^1.0.0", 32 | "react-transform-hmr": "^1.0.1", 33 | "redbox-react": "^1.2.0", 34 | "webpack": "^1.12.9", 35 | "webpack-dev-server": "^1.14.0", 36 | "postcss-loader": "~0.8.0", 37 | "postcss": "~5.0.12", 38 | "precss": "~1.3.0", 39 | "css-loader": "~0.23.0", 40 | "autoprefixer": "~6.1.2", 41 | "style-loader": "~0.13.0", 42 | "file-loader": "~0.8.5", 43 | "url-loader": "~0.5.7", 44 | "babel-preset-es2015": "~6.3.13", 45 | "babel-plugin-syntax-async-functions": "~6.3.13", 46 | "babel-preset-stage-0": "~6.3.13" 47 | }, 48 | "dependencies": { 49 | "react": "^0.14.3", 50 | "react-dom": "^0.14.3", 51 | "normalize.css": "~3.0.3", 52 | "babel-core": "~6.3.21" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/components/App/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Hello from '../Hello/Hello'; 3 | import s from './App.scss'; 4 | 5 | class App extends Component { 6 | 7 | render() { 8 | return ; 9 | } 10 | 11 | } 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /src/components/App/App.scss: -------------------------------------------------------------------------------- 1 | @import '../../../node_modules/normalize.css/normalize.css'; 2 | @import '../variables.scss'; 3 | 4 | /* 5 | * Base styles 6 | * ========================================================================== */ 7 | 8 | html { 9 | color: #222; 10 | font-weight: 100; 11 | font-size: 1em; /* ~16px; */ 12 | font-family: $font-family-base; 13 | line-height: 1.375; /* ~22px */ 14 | } 15 | 16 | .container { 17 | margin: 0 auto; 18 | padding: 0 0 40px; 19 | max-width: $max-content-width; 20 | } 21 | -------------------------------------------------------------------------------- /src/components/Hello/Hello.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import s from './Hello.scss'; 3 | 4 | class Hello extends Component { 5 | 6 | render() { 7 | return

Hello, {this.props.name}!

; 8 | } 9 | 10 | } 11 | 12 | export default Hello; 13 | -------------------------------------------------------------------------------- /src/components/Hello/Hello.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Hello styles 3 | * ========================================================================== */ 4 | -------------------------------------------------------------------------------- /src/components/variables.scss: -------------------------------------------------------------------------------- 1 | /* 2 | * Colors 3 | * ========================================================================== */ 4 | 5 | $white-base: hsl(255, 255, 255); 6 | 7 | /* 8 | * Typography 9 | * ========================================================================== */ 10 | 11 | $font-family-base: 'Segoe UI', 'HelveticaNeue-Light', sans-serif; 12 | 13 | /* 14 | * Layout 15 | * ========================================================================== */ 16 | 17 | $max-content-width: 1000px; 18 | 19 | /* 20 | * Media queries breakpoints 21 | * ========================================================================== */ 22 | 23 | $screen-xs-min: 480px; /* Extra small screen / phone */ 24 | $screen-sm-min: 768px; /* Small screen / tablet */ 25 | $screen-md-min: 992px; /* Medium screen / desktop */ 26 | $screen-lg-min: 1200px; /* Large screen / wide desktop */ 27 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import App from './components/App/App'; 4 | 5 | var element = React.createElement(App, {}); 6 | render(element, document.querySelector('.container')); 7 | -------------------------------------------------------------------------------- /tools/build.js: -------------------------------------------------------------------------------- 1 | import run from './run'; 2 | import clean from './clean'; 3 | import bundle from './bundle'; 4 | 5 | async function build() { 6 | await run(clean); 7 | await run(bundle); 8 | }; 9 | 10 | export default build; 11 | -------------------------------------------------------------------------------- /tools/bundle.js: -------------------------------------------------------------------------------- 1 | import webpack from 'webpack'; 2 | import webpackConfig from './webpack.config'; 3 | 4 | /** 5 | * Bundles JavaScript. 6 | */ 7 | function bundle() { 8 | return new Promise((resolve, reject) => { 9 | let compiler = webpack(webpackConfig); 10 | compiler.run((err, stats) => { 11 | if (err){ 12 | reject(err); 13 | } 14 | console.log(stats.toString(webpackConfig.stats)); 15 | resolve(); 16 | }); 17 | }); 18 | }; 19 | 20 | export default bundle; 21 | -------------------------------------------------------------------------------- /tools/clean.js: -------------------------------------------------------------------------------- 1 | import del from 'del'; 2 | import fs from 'fs'; 3 | 4 | /** 5 | * Cleans up the output (build) directory. 6 | */ 7 | async function clean() { 8 | await del(['build/*'], { dot: true }); 9 | }; 10 | 11 | export default clean; 12 | -------------------------------------------------------------------------------- /tools/run.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Script inspired from https://github.com/kriasoft/react-starter-kit/blob/master/tools/run.js. 3 | */ 4 | 5 | function format(time) { 6 | return time.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1'); 7 | } 8 | 9 | async function run(fn, options) { 10 | const start = new Date(); 11 | console.log(`[${format(start)}] Starting '${fn.name}'...`); 12 | 13 | await fn(options); 14 | 15 | const end = new Date(); 16 | const time = end.getTime() - start.getTime(); 17 | console.log(`[${format(end)}] Finished '${fn.name}' after ${time} ms`); 18 | } 19 | 20 | if (process.mainModule.children.length === 0 && process.argv.length > 2){ 21 | delete require.cache[__filename]; 22 | const module = process.argv[2]; 23 | run(require('./' + module + '.js').default).catch(err => console.error(err.stack)); 24 | } 25 | 26 | export default run; 27 | -------------------------------------------------------------------------------- /tools/start.js: -------------------------------------------------------------------------------- 1 | import webpack from 'webpack'; 2 | import WebpackDevServer from 'webpack-dev-server'; 3 | import webpackConfig from './webpack.config'; 4 | 5 | /** 6 | * Launches Webpack dev server. 7 | */ 8 | async function server() { 9 | await new Promise((resolve, reject) => { 10 | new WebpackDevServer(webpack(webpackConfig), { 11 | publicPath: webpackConfig.output.publicPath, 12 | hot: true 13 | }).listen(3000, 'localhost', (err, result) => { 14 | if (err){ 15 | console.log(err); 16 | reject(err); 17 | } 18 | console.log("Listening at localhost:3000"); 19 | resolve(); 20 | }); 21 | }); 22 | }; 23 | 24 | export default server; 25 | -------------------------------------------------------------------------------- /tools/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var webpack = require("webpack"); 3 | var autoprefixer = require('autoprefixer'); 4 | var precss = require('precss'); 5 | 6 | module.exports = { 7 | entry: [ 8 | 'webpack-dev-server/client?http://localhost:3000', // WebpackDevServer host and port 9 | 'webpack/hot/only-dev-server', // "only" prevents reload on syntax errors 10 | './src/index' // Your appʼs entry point 11 | ], 12 | output: { 13 | path: path.resolve(__dirname, '../build'), 14 | filename: 'bundle.js', 15 | publicPath: '/build/' 16 | }, 17 | plugins: [ 18 | new webpack.HotModuleReplacementPlugin() 19 | ], 20 | resolve: { 21 | extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.json'], 22 | }, 23 | module: { 24 | loaders: [ 25 | { 26 | test: /\.jsx?$/, 27 | exclude: /(node_modules|bower_components)/, 28 | loaders: ['react-hot', 'babel'] 29 | }, { 30 | test: /\.scss$/, 31 | loaders: ['style-loader', 'css-loader', 'postcss-loader'] 32 | }, { 33 | test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/, 34 | loader: 'url-loader?limit=10000', 35 | } 36 | ] 37 | }, 38 | postcss: function () { 39 | return [autoprefixer, precss]; 40 | }, 41 | stats: { 42 | colors: true 43 | } 44 | }; 45 | --------------------------------------------------------------------------------