├── src ├── components │ ├── .gitkeep │ └── app.js ├── styles │ └── app.scss └── index.js ├── Procfile ├── public └── index.html ├── app.js ├── index.html ├── .babelrc ├── README.md ├── server.js ├── webpack.config.js ├── webpack.prod.config.js ├── .gitignore └── package.json /src/components/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm start 2 | -------------------------------------------------------------------------------- /src/styles/app.scss: -------------------------------------------------------------------------------- 1 | h1 { 2 | color: blue; 3 | } 4 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const Server = require('./server.js') 2 | const port = (process.env.PORT || 8080) 3 | const app = Server.app() 4 | 5 | app.listen(port) 6 | console.log(`Listening at http://localhost:${port}`) 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/app.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default class App extends React.Component { 4 | render () { 5 | return ( 6 |
7 |

Change me

8 |
9 | ) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "latest", { 5 | "es2015": { 6 | "modules": false 7 | } 8 | } 9 | ], 10 | "react" 11 | ], 12 | "plugins": [ 13 | "react-hot-loader/babel" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Deployable React + Webpack 2 starter kit 2 | 3 | - React 15 4 | - Webpack 2 5 | - React-hot-loader 3 6 | - SASS 7 | 8 | Running on development mode: 9 | ``` 10 | npm run dev 11 | ``` 12 | 13 | Running on production mode: 14 | ``` 15 | npm run build 16 | npm start 17 | ``` 18 | 19 | Before you deploy, make sure you generated your bundle through `npm run build`. 20 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const express = require('express') 3 | 4 | module.exports = { 5 | app: function () { 6 | const app = express() 7 | const indexPath = path.join(__dirname, 'index.html') 8 | const publicPath = express.static(path.join(__dirname, 'public')) 9 | 10 | app.use('/public', publicPath) 11 | app.get('/', function (_, res) { res.sendFile(indexPath) }) 12 | 13 | return app 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import App from './components/app' 4 | import './styles/app.scss' 5 | import { AppContainer } from 'react-hot-loader' 6 | 7 | const render = Component => { 8 | ReactDOM.render( 9 | 10 | 11 | , 12 | document.getElementById('main') 13 | ) 14 | } 15 | 16 | render(App) 17 | if (module.hot) { 18 | module.hot.accept('./components/app', () => { render(App) }) 19 | } 20 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | devtool: 'source-map', 6 | entry: [ 7 | 'babel-polyfill', 8 | 'react-hot-loader/patch', 9 | './src/index' 10 | ], 11 | 12 | output: { 13 | path: path.join(__dirname, 'public'), 14 | filename: 'bundle.js', 15 | publicPath: '/public/' 16 | }, 17 | 18 | plugins: [ 19 | new webpack.HotModuleReplacementPlugin(), 20 | new webpack.NoEmitOnErrorsPlugin() 21 | ], 22 | 23 | module: { 24 | rules: [ 25 | { test: /\.js?$/, 26 | loader: 'babel-loader', 27 | include: path.join(__dirname, 'src') 28 | }, 29 | { test: /\.scss?$/, 30 | loader: 'style-loader!css-loader!sass-loader', 31 | include: path.join(__dirname, 'src', 'styles') }, 32 | { test: /\.png$/, 33 | loader: 'file-loader' }, 34 | { test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, 35 | loader: 'file-loader'} 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const webpack = require('webpack') 3 | 4 | module.exports = { 5 | devtool: 'source-map', 6 | 7 | entry: [ 8 | './src/index' 9 | ], 10 | 11 | output: { 12 | path: path.join(__dirname, 'public'), 13 | filename: 'bundle.js', 14 | publicPath: '/public/' 15 | }, 16 | 17 | plugins: [ 18 | new webpack.optimize.UglifyJsPlugin({ 19 | minimize: true, 20 | compress: { 21 | warnings: false 22 | } 23 | }), 24 | new webpack.DefinePlugin({ 25 | 'process.env': { 26 | 'NODE_ENV': JSON.stringify('production') 27 | } 28 | }) 29 | ], 30 | 31 | module: { 32 | rules: [ 33 | { test: /\.js?$/, 34 | loader: 'babel-loader', 35 | include: path.join(__dirname, 'src') }, 36 | { test: /\.scss?$/, 37 | loader: 'style-loader!css-loader!sass-loader', 38 | include: path.join(__dirname, 'src', 'styles') }, 39 | { test: /\.png$/, 40 | loader: 'file-loader' }, 41 | { test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, 42 | loader: 'file-loader'} 43 | ] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io 2 | 3 | ### OSX ### 4 | .DS_Store 5 | .AppleDouble 6 | .LSOverride 7 | 8 | # Icon must end with two \r 9 | Icon 10 | 11 | # Thumbnails 12 | ._* 13 | 14 | # Files that might appear in the root of a volume 15 | .DocumentRevisions-V100 16 | .fseventsd 17 | .Spotlight-V100 18 | .TemporaryItems 19 | .Trashes 20 | .VolumeIcon.icns 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | ### Node ### 30 | # Logs 31 | logs 32 | *.log 33 | 34 | # Runtime data 35 | pids 36 | *.pid 37 | *.seed 38 | 39 | # Directory for instrumented libs generated by jscoverage/JSCover 40 | lib-cov 41 | 42 | # Coverage directory used by tools like istanbul 43 | coverage 44 | 45 | # node-waf configuration 46 | .lock-wscript 47 | 48 | # Compiled binary addons (http://nodejs.org/api/addons.html) 49 | build/Release 50 | 51 | # Dependency directory 52 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 53 | node_modules 54 | 55 | ### Vim ### 56 | [._]*.s[a-w][a-z] 57 | [._]s[a-w][a-z] 58 | *.un~ 59 | Session.vim 60 | .netrwhist 61 | *~ 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-heroku-boilerplate", 3 | "version": "1.0.0", 4 | "description": "Simplest Heroku starter kit for React apps.", 5 | "main": "./src/entry.js", 6 | "homepage": "https://github.com/wallacyyy/webpack-heroku", 7 | "author": "Leonardo Couto", 8 | "license": "MIT", 9 | "scripts": { 10 | "build": "cross-env NODE_ENV=production webpack --config ./webpack.prod.config.js --progress --colors", 11 | "start": "node app.js", 12 | "dev": "webpack-dev-server --hot --history-api-fallback --open" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/wallacyyy/webpack-heroku.git" 17 | }, 18 | "keywords": [ 19 | "react", 20 | "express", 21 | "webpack", 22 | "es2015", 23 | "javascript" 24 | ], 25 | "dependencies": { 26 | "express": "^4.15.2", 27 | "react": "^15.5.4", 28 | "react-dom": "^15.5.4" 29 | }, 30 | "devDependencies": { 31 | "babel-core": "^6.24.1", 32 | "babel-loader": "^6.4.1", 33 | "babel-polyfill": "^6.23.0", 34 | "babel-preset-latest": "^6.22.0", 35 | "babel-preset-react": "^6.24.1", 36 | "cross-env": "^3.1.3", 37 | "css-loader": "^0.28.0", 38 | "file-loader": "^0.11.1", 39 | "node-sass": "^4.5.2", 40 | "react-hot-loader": "^3.0.0-beta.6", 41 | "sass-loader": "^3.2.0", 42 | "style-loader": "^0.16.1", 43 | "url-loader": "^0.5.8", 44 | "webpack": "^2.2.1", 45 | "webpack-dev-server": "^2.4.2" 46 | } 47 | } 48 | --------------------------------------------------------------------------------