├── .gitignore ├── .eslintignore ├── .babelrc ├── app ├── component │ ├── bg.png │ ├── logo.png │ ├── Hello.js │ └── Hello.scss ├── index.tpl.html └── index.js ├── .editorconfig ├── server.js ├── package.json ├── webpack.config.prod.js ├── .eslintrc ├── webpack.config.dev.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | **/*.css 3 | **/*.html 4 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /app/component/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenbin92/react-redux-webpack-starter/HEAD/app/component/bg.png -------------------------------------------------------------------------------- /app/component/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenbin92/react-redux-webpack-starter/HEAD/app/component/logo.png -------------------------------------------------------------------------------- /app/index.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import Hello from './component/Hello'; 5 | 6 | ReactDOM.render( 7 | , 8 | document.getElementById('root') 9 | ); 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /app/component/Hello.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import './Hello.scss'; 3 | 4 | import logo from './logo.png'; 5 | 6 | class Hello extends React.Component { 7 | render() { 8 | return ( 9 |
10 |

Hello React

11 | 12 |

Guangzhou, China
chenbin92

13 |
14 | ); 15 | } 16 | } 17 | 18 | export default Hello; 19 | -------------------------------------------------------------------------------- /app/component/Hello.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | position: absolute; 3 | top: 0; 4 | bottom: 0; 5 | left: 0; 6 | right: 0; 7 | background: url(./bg.png) no-repeat 50%/cover; 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | flex-direction: column; 12 | h1 { 13 | color: rgba(41, 58, 64, 0.82); 14 | font-size: 42px; 15 | } 16 | p { 17 | position: fixed; 18 | right: 20px; 19 | bottom: 20px; 20 | color: #fff; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /*eslint no-console: 0*/ 3 | 4 | const webpack = require('webpack'); 5 | const webpackDevServer = require('webpack-dev-server'); 6 | const devConfig = require('./webpack.config.dev.js'); 7 | const prodConfig = require('./webpack.config.prod.js'); 8 | 9 | const isDeveloping = process.env.NODE_ENV === 'development'; 10 | const port = isDeveloping ? 8080 : 9090; 11 | 12 | function baseConfig(config, contentBase) { 13 | return new webpackDevServer(webpack(config), { 14 | historyApiFallback: true, 15 | hot: true, 16 | inline: true, 17 | progress: true, 18 | contentBase: contentBase, 19 | stats: { colors: true } // 用颜色标识 20 | }); 21 | } 22 | 23 | let server; 24 | if(isDeveloping) { 25 | server = baseConfig(devConfig, "/app"); 26 | console.log("development mode..."); 27 | } else { 28 | server = baseConfig(prodConfig, "./build"); 29 | console.log("production mode..."); 30 | } 31 | 32 | server.listen(port, "localhost", function(err) { 33 | if(err) { 34 | console.log(err); 35 | } 36 | console.log('==> 🌎 Listening on ' + process.env.NODE_ENV + ' port ' + port); 37 | }); 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-redux-webpack-starter", 3 | "version": "1.0.0", 4 | "description": "react-redux-webpack-starter", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "export NODE_ENV=development && webpack-dashboard -- node server.js && npm run lint:watch", 9 | "start:prod": "export NODE_ENV=production && npm run build && webpack-dashboard -- node server.js", 10 | "build": "npm run remove:build && NODE_ENV=production && webpack -p --config webpack.config.prod.js --progress --colors", 11 | "clean:build": "npm run remove-build && mkdir build", 12 | "remove:build": "rimraf build", 13 | "lint": "esw webpack.config.* app", 14 | "lint:watch": "npm run lint -- --watch" 15 | }, 16 | "author": "chenbin92 (https://github.com/chenbin92)", 17 | "license": "ISC", 18 | "dependencies": { 19 | "react": "^15.1.0", 20 | "react-dom": "^15.1.0", 21 | "react-redux": "^4.4.5", 22 | "redux": "^3.5.2" 23 | }, 24 | "devDependencies": { 25 | "babel-core": "^6.10.4", 26 | "babel-eslint": "^6.1.0", 27 | "babel-loader": "^6.2.4", 28 | "babel-preset-es2015": "^6.9.0", 29 | "babel-preset-react": "^6.11.0", 30 | "copy-webpack-plugin": "^3.0.1", 31 | "css-loader": "^0.23.1", 32 | "eslint": "^2.9.0", 33 | "eslint-plugin-react": "^5.2.2", 34 | "eslint-watch": "^2.1.13", 35 | "file-loader": "^0.9.0", 36 | "html-webpack-plugin": "^2.22.0", 37 | "image-webpack-loader": "^1.8.0", 38 | "node-sass": "^3.8.0", 39 | "open-browser-webpack-plugin": "0.0.2", 40 | "sass-loader": "^4.0.0", 41 | "style-loader": "^0.13.1", 42 | "url-loader": "^0.5.7", 43 | "webpack": "^1.13.1", 44 | "webpack-dashboard": "^0.1.6", 45 | "webpack-dev-server": "^1.14.1" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const OpenBrowserPlugin = require('open-browser-webpack-plugin'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | 6 | const config = { 7 | devtool: 'cheap-source-map', 8 | entry: [ 9 | 'webpack-dev-server/client?http://localhost:9090', 10 | path.resolve(__dirname, 'app/index.js') 11 | ], 12 | output: { 13 | path: path.resolve(__dirname, 'build'), 14 | filename: '[chunkhash:8].bundle.js', 15 | publicPath: '/' 16 | }, 17 | resolve: { 18 | extensions: ['', '.js', '.jsx'] 19 | }, 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.js|jsx$/, 24 | exclude: /(node_modules|bower_components)/, 25 | loaders: ['babel'] 26 | }, 27 | { 28 | test: /(\.css|\.scss)$/, 29 | loaders: ["style", "css", "sass"] 30 | }, 31 | { 32 | test: /\.(jpe?g|png|gif|svg)$/i, 33 | loaders: [ 34 | 'url?limit=10000&name=[hash:8].[name].[ext]', 35 | 'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}' 36 | ] 37 | } 38 | ] 39 | }, 40 | plugins: [ 41 | new webpack.DefinePlugin({ 42 | 'process.env.NODE_ENV': JSON.stringify('production'), 43 | __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false')) 44 | }), 45 | new webpack.optimize.DedupePlugin(), 46 | new webpack.optimize.UglifyJsPlugin({ 47 | compress: { 48 | warnings: false 49 | } 50 | }), 51 | new HtmlWebpackPlugin({ 52 | template: 'app/index.tpl.html', 53 | filename: 'index.html', 54 | inject: true 55 | }), 56 | new OpenBrowserPlugin({ url: 'http://localhost:9090/' }) 57 | ] 58 | }; 59 | 60 | module.exports = config; 61 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parserOptions": { 3 | "ecmaVersion": 6, 4 | "sourceType": "module", 5 | "ecmaFeatures": { 6 | "jsx": true 7 | } 8 | }, 9 | "env": { 10 | "browser": true, 11 | "node": true, 12 | "es6": true, 13 | "mocha": true 14 | }, 15 | "plugins": [ 16 | "react" 17 | ], 18 | parser: 'babel-eslint', 19 | extends: [ 20 | "eslint:recommended" 21 | ], 22 | "rules": { 23 | "quotes": 0, 24 | "no-console": 1, 25 | "no-debugger": 1, 26 | "no-var": 1, 27 | "import/named": 0, 28 | "semi": [1, "always"], 29 | "no-trailing-spaces": 0, 30 | "eol-last": 0, 31 | "no-underscore-dangle": 0, 32 | "no-alert": 0, 33 | "no-lone-blocks": 0, 34 | "jsx-quotes": 1, 35 | "react/display-name": [ 1, {"ignoreTranspilerName": false }], 36 | "react/forbid-prop-types": [1, {"forbid": ["any"]}], 37 | "react/jsx-boolean-value": 0, 38 | "react/jsx-closing-bracket-location": 0, 39 | "react/jsx-curly-spacing": 1, 40 | "react/jsx-indent-props": 0, 41 | "react/jsx-key": 1, 42 | "react/jsx-max-props-per-line": 0, 43 | "react/jsx-no-bind": 0, 44 | "react/jsx-no-duplicate-props": 1, 45 | "react/jsx-no-literals": 0, 46 | "react/jsx-no-undef": 1, 47 | "react/jsx-pascal-case": 1, 48 | "react/jsx-sort-prop-types": 0, 49 | "react/jsx-sort-props": 0, 50 | "react/jsx-uses-react": 1, 51 | "react/jsx-uses-vars": 1, 52 | "react/no-danger": 1, 53 | "react/no-did-mount-set-state": 1, 54 | "react/no-did-update-set-state": 1, 55 | "react/no-direct-mutation-state": 1, 56 | "react/no-multi-comp": 1, 57 | "react/no-set-state": 0, 58 | "react/no-unknown-property": 1, 59 | "react/prefer-es6-class": 1, 60 | "react/prop-types": 1, 61 | "react/react-in-jsx-scope": 1, 62 | "react/require-extension": 1, 63 | "react/self-closing-comp": 1, 64 | "react/sort-comp": 1, 65 | "react/wrap-multilines": 1 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const path = require('path'); 3 | const OpenBrowserPlugin = require('open-browser-webpack-plugin'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | const DashboardPlugin = require('webpack-dashboard/plugin'); 6 | 7 | const config = { 8 | devtool: "source-map", // or "inline-source-map" 9 | entry: [ 10 | 'webpack/hot/dev-server', 11 | 'webpack-dev-server/client?http://localhost:8080', 12 | path.resolve(__dirname, 'app/index.js') // 定义入口文件 13 | ], 14 | output: { // 定义出口目录 15 | path: path.resolve(__dirname, 'build'), 16 | filename: 'bundle.js', 17 | publicPath: 'http://localhost:8080/' // html引用路径 18 | }, 19 | resolve: { // resolve 指定可以被 import 的文件后缀 20 | extensions: ['', '.js', '.jsx'] 21 | }, 22 | module: { 23 | loaders: [ 24 | { 25 | test: /\.js|jsx$/, // 检测哪些文件需要此loader,是一个正则表达式,用正则来匹配文件路径,这段意思是匹配 js 或者 jsx 26 | exclude: /(node_modules|bower_components)/, 27 | loaders: ['babel'] // 加载模块 "babel" 是 "babel-loader" 的缩写 28 | }, 29 | { 30 | test: /(\.css|\.scss)$/, 31 | loaders: ["style", "css?sourceMap", "sass?sourceMap"] 32 | }, 33 | { 34 | test: /\.(jpe?g|png|gif|svg)$/i, 35 | loaders: [ 36 | 'url?limit=10000&name=img/[hash:8].[name].[ext]', 37 | 'image-webpack?{progressive:true, optimizationLevel: 7, interlaced: false, pngquant:{quality: "65-90", speed: 4}}' 38 | ] 39 | } 40 | ] 41 | }, 42 | plugins: [ 43 | new HtmlWebpackPlugin({ 44 | template: 'app/index.tpl.html', 45 | inject: 'body', 46 | filename: 'index.html' 47 | }), 48 | new webpack.DefinePlugin({ 49 | 'process.env.NODE_ENV': JSON.stringify('development'), 50 | __DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false')) 51 | }), 52 | new webpack.HotModuleReplacementPlugin(), 53 | new webpack.NoErrorsPlugin(), 54 | new OpenBrowserPlugin({ url: 'http://localhost:8080/' }), 55 | new DashboardPlugin() 56 | ] 57 | }; 58 | 59 | module.exports = config; 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React-babel-webpack-es6 Starter Project 2 | 3 | A boilerplate using React, webpack and hot module reloading, and ES6 + JSX via Babel.You could use it as a base to build your own web app. 4 | 5 | ## Features 6 | 7 | The provided boilerplate enables client-side ES6 via the following technologies: 8 | 9 | - [webpack](http://webpack.github.io/) and [webpack-dev-server](https://webpack.github.io/docs/webpack-dev-server.html) as a client-side module builder and module loader. 10 | - [npm](https://www.npmjs.com/) as a package manager and task runner 11 | - [Babel](http://babeljs.io/) 6 as a transpiler from ES6 to ES5. 12 | - [React](https://facebook.github.io/react/) and [JSX](https://facebook.github.io/jsx/) as a virtual Dom JavaScript library for rendering user interfaces (views). 13 | - [ESLint](http://eslint.org/) as a reporter for syntax and style issues. [eslint-plugin-react](https://github.com/yannickcr/eslint-plugin-react) for additional React specific linting rules. 14 | - [Sass](http://sass-lang.com/) as a compiler of CSS styles with variables, mixins, and more. 15 | - Inline base64 URLs for images and fonts if their size is less than specified limit of [file-loader](https://github.com/webpack/file-loader) 16 | - Image compression processing of [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader) 17 | - Watch `index.html` for changes of [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) 18 | 19 | ## Getting Started 20 | 21 | ### Installation 22 | 23 | you should clone the repo and install the dependencies. 24 | 25 | ``` 26 | $ git clone https://github.com/chenbin92/react-redux-webpack-starter.git app-name 27 | $ cd app-name 28 | $ npm install //or cnpm install 29 | ``` 30 | 31 | ## Development 32 | In the development mode. launch the boilerplate app: 33 | 34 | ``` 35 | // run the dev server http://localhost:8080 36 | 37 | $ npm start 38 | ``` 39 | 40 | you should see a new browser tap opening and a title of "Hello React” in [http://localhost:8080/](http://localhost:8080/), page hot reloads automatically when there are changes 41 | 42 | ![Webpack-dashboard](http://i2.buimg.com/4851/c971b58acc349be2.png) 43 | ![homepage](https://cloud.githubusercontent.com/assets/3995814/16775798/ef9cf446-4894-11e6-9510-af171fec3107.png) 44 | 45 | When you run npm start: 46 | 47 | - The sass-loader compiles Sass into CSS 48 | - Webpack bundles the compiled CSS、JS into `bundle.js` 49 | 50 | ## Production 51 | 52 | In the production mode, you can: 53 | 54 | ``` 55 | // run the prod server http://localhost:9090 56 | 57 | $ npm run start: prod 58 | ``` 59 | 60 | ``` 61 | // build the static files. 62 | 63 | $ npm run build 64 | ``` 65 | 66 | ```npm run build```. This will prepare and build the project for production use. It does the following: 67 | 68 | - Minifies all JS and CSS 69 | - Inline base64 URLs for images and fonts if their size is less than specified limit 70 | - Sets NODE_ENV to production so that React is built in production mode 71 | - Places the resulting built project files into `/build` directory 72 | 73 | ## All configuration tasks 74 | 75 | - `npm start`: start the development model of server 76 | - `npm run start:prod`: start the production model of server 77 | - `npm run build`: compile code in production mode 78 | - `npm run lint`: lint with ESlint and Airbnb's style sheet. 79 | - `npm run lint:watch`: eslint watching 80 | - `npm run remove:build`: remove the dist directory 81 | - `npm run clean:build `: clean the dist directory 82 | 83 | ## TODO 84 | 85 | - [ ] add test 86 | 87 | ## Others 88 | 89 | * [more information](https://github.com/chenbin92/react-redux-webpack-starter/issues/1) 90 | --------------------------------------------------------------------------------