├── src ├── assets │ └── README.md ├── redux │ ├── reducers.js │ └── configureStore.js ├── containers │ ├── index.js │ └── App │ │ ├── index.css │ │ └── index.jsx ├── components │ ├── index.js │ └── MyComponent │ │ ├── index.css │ │ └── index.jsx ├── routes │ └── index.js ├── index.js └── index.html ├── conf ├── webpack.test.config.js ├── webpack.dll.config.js ├── server.dev.js ├── webpack.prod.config.js ├── webpack.dev.config.js └── base.js ├── .eslintignore ├── static └── u.js ├── CHANGELOG.md ├── test ├── setup.js └── counter.spec.js ├── .babelrc ├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .eslintrc ├── LICENSE ├── README.md └── package.json /src/assets/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/redux/reducers.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /conf/webpack.test.config.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/redux/configureStore.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /src/containers/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export App from './App/index.jsx'; 4 | -------------------------------------------------------------------------------- /static/u.js: -------------------------------------------------------------------------------- 1 | 2 | //installer.failurerequests 3 | //test 4 | 5 | window.a = "我是不需要编译的全局资源"; 6 | -------------------------------------------------------------------------------- /src/components/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export MyComponent from './MyComponent/index.jsx'; 4 | -------------------------------------------------------------------------------- /src/containers/App/index.css: -------------------------------------------------------------------------------- 1 | p{ 2 | font-size: 40px; 3 | text-align: center; 4 | color: red; 5 | } 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 2016-12-13 4 | 5 | - 新增static目录 6 | - 新增conf目录,将webpack配置文件都统一在conf目录 7 | - 更新package.json 8 | -------------------------------------------------------------------------------- /src/components/MyComponent/index.css: -------------------------------------------------------------------------------- 1 | .demo { 2 | font-size: 50px; 3 | color: blue; 4 | text-align: center; 5 | font-weight: bold; 6 | } 7 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | import { jsdom } from 'jsdom' 2 | 3 | global.document = jsdom('') 4 | global.window = document.defaultView 5 | global.navigator = global.window.navigator 6 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"], 3 | "plugins": ["transform-runtime", "transform-decorators-legacy"], 4 | "env": { 5 | "production": { 6 | "presets": ["react-optimize"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/routes/index.js: -------------------------------------------------------------------------------- 1 | import { Router, Route, browserHistory } from 'react-router'; 2 | import { App } from '../containers'; 3 | import React from 'react'; 4 | 5 | export default ( 6 | 7 | 8 | 9 | ) 10 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import routes from './routes' 4 | 5 | const root = document.getElementById('app'); 6 | 7 | if ( __DEV__ ){ 8 | console.log("现在是开发环境") 9 | } 10 | 11 | if (__PROD__) { 12 | console.log("现在是生产环境") 13 | } 14 | 15 | render(routes, root) 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Do you want to request a feature or report a bug? 2 | 你希望向我报告BUG还是提交一个内容需求? 3 | 4 | What is the current behavior? 5 | 目前的问题表现是什么样的? 6 | 7 | If the current behavior is a bug, please provide the steps to reproduce . 8 | 如果这是个确认的问题,请描述一下具体的文章位置或是复现的步骤。 9 | 10 | What is the expected behavior? 11 | 你预期的效果是什么样的呢? 12 | -------------------------------------------------------------------------------- /test/counter.spec.js: -------------------------------------------------------------------------------- 1 | var assert = require("assert"); 2 | describe('Array', function(){ 3 | describe('#indexOf()', function(){ 4 | it('测试用例1', function(){ 5 | assert.equal(-1, [1,2,3].indexOf(5)); 6 | assert.equal(-1, [1,2,3].indexOf(0)); 7 | }) 8 | }); 9 | 10 | describe('#indexOf()', function(){ 11 | it('测试用例2', function(){ 12 | assert.equal(-1, [1,2,3].indexOf(2)); 13 | }) 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /src/components/MyComponent/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | import './index.css'; 4 | 5 | class MyComponent extends Component { 6 | render() { 7 | return ( 8 |

9 | 10 | 更多干货请前往:http://guoyongfeng.github.io/idoc/ 11 | 12 |

13 | ); 14 | } 15 | } 16 | 17 | export default MyComponent; 18 | -------------------------------------------------------------------------------- /src/containers/App/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { MyComponent } from '../../components'; 3 | 4 | import './index.css'; 5 | 6 | class App extends Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render() { 12 | return ( 13 |
14 | 15 |

16 | 欢迎在github上一起维护这个脚手架项目
17 | https://github.com/GuoYongfeng 18 |

19 |
20 | ); 21 | } 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Before submitting a pull request, please make sure the following is done... 2 | 在你准备向我提交一个pr的时候,请确认以下事项是否完成: 3 | 4 | 1.Fork the repo and create your branch from master. 5 | 2.If you've added code that should be tested, add tests! 6 | 3.If you've changed APIs, update the documentation. 7 | 4.Ensure the test suite passes (npm test). 8 | 5.Make sure your code lints (npm run lint) - we've done our best to make sure these rules match our internal linting guidelines. 9 | 7.If you haven't already, complete the CLA. 10 | -------------------------------------------------------------------------------- /conf/webpack.dll.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | var publicPath = path.resolve(__dirname, '../public/'); 4 | var deps = require('../package.json').dependencies; 5 | 6 | module.exports = { 7 | entry: { 8 | 'react': Object.keys(deps) 9 | }, 10 | output: { 11 | path: publicPath, 12 | filename: '[name].dll.js', 13 | library: '[name]_library', 14 | }, 15 | plugins: [ 16 | new webpack.DllPlugin({ 17 | path: path.resolve(__dirname, '../public/[name]-manifest.json'), 18 | name: '[name]_library', 19 | }), 20 | ], 21 | debug: true 22 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # build resource 3 | build 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # node-waf configuration 25 | .lock-wscript 26 | 27 | # Compiled binary addons (http://nodejs.org/api/addons.html) 28 | build/Release 29 | 30 | # Dependency directory 31 | node_modules 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | public 39 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | boilerplate 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | 'env': { 4 | 'es6': true, 5 | 'node': true, 6 | }, 7 | "strict": [2, "global"], 8 | 'parserOptions': { 9 | 'ecmaVersion': 6, 10 | 'sourceType': 'module', 11 | }, 12 | "globals": { 13 | "$": true, 14 | "window": true, 15 | 'document': true, 16 | "__dirname": true, 17 | }, 18 | "rules": { 19 | 'no-new-func': 1, 20 | 'func-names': 0, 21 | 'no-new': 0, 22 | 'no-param-reassign': [2, { "props": false }], 23 | 'yoda': [1, "never", {"exceptRange": true,"onlyEquality": true}], 24 | "no-useless-concat": 0, 25 | "no-implicit-coercion": [2, { 26 | "boolean": true, 27 | "number": true, 28 | "string": true, 29 | "allow": [/* "!!", "~", "*", "+" */], 30 | }], 31 | "semi": [2, "never"] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /conf/server.dev.js: -------------------------------------------------------------------------------- 1 | var express = require('express'), 2 | webpack = require('webpack'), 3 | // favicon = require('express-favicon'), 4 | config = require('./webpack.dev.config'), 5 | app = express(); 6 | 7 | var compiler = webpack(config); 8 | 9 | // for highly stable resources 10 | app.use('/static', express.static(config.commonPath.staticDir)); 11 | 12 | // app.use(favicon(path.join(__dirname, '../favicon.ico'))); 13 | 14 | // handle fallback for HTML5 history API 15 | app.use(require('connect-history-api-fallback')()); 16 | 17 | // serve webpack bundle output 18 | app.use(require('webpack-dev-middleware')(compiler, { 19 | noInfo: true, 20 | publicPath: config.output.publicPath 21 | })); 22 | 23 | // enable hot-reload and state-preserving 24 | // compilation error display 25 | app.use(require('webpack-hot-middleware')(compiler)); 26 | 27 | app.listen(9000, '127.0.0.1', function(err) { 28 | err && console.log(err); 29 | }); 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 GuoYongfeng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /conf/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var config = require('./base'); 3 | var CopyWebpackPlugin = require('copy-webpack-plugin'); 4 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | 6 | /** 7 | * ouput config 8 | * @type {String} 9 | */ 10 | config.output.filename = '[name].[chunkhash:6].js'; 11 | config.output.chunkFilename = '[id].[chunkhash:6].js'; 12 | 13 | /** 14 | * devtool config 15 | * @type {String} 16 | */ 17 | config.devtool = "cheap-source-map"; 18 | 19 | /** 20 | * loaders config 21 | * @type {RegExp} 22 | */ 23 | config.module.loaders.push({ 24 | test: /\.css$/, 25 | loader: ExtractTextPlugin.extract('style', 'css') 26 | }, { 27 | test: /\.less$/, 28 | loader: ExtractTextPlugin.extract('style', 'css!less') 29 | }); 30 | 31 | /** 32 | * plugins config 33 | * @type {[type]} 34 | */ 35 | config.plugins.push( 36 | // stataic目录下静态资源的复制 37 | new CopyWebpackPlugin([ { 38 | context: config.commonPath.rootPath, 39 | from: 'static/*', 40 | ignore: ['*.md'] 41 | } 42 | ]), 43 | new webpack.optimize.DedupePlugin(), 44 | new webpack.optimize.UglifyJsPlugin({ 45 | compress: { 46 | warnings: false 47 | } 48 | }), 49 | new webpack.optimize.OccurenceOrderPlugin(), 50 | // 公共代码分离打包 51 | new webpack.optimize.CommonsChunkPlugin({ 52 | names: ['vendor', 'mainifest'] 53 | }), 54 | // 若要按需加载 CSS 则请注释掉该行 55 | new ExtractTextPlugin('[name].[contenthash:6].css', { 56 | allChunks : true 57 | }) 58 | ); 59 | 60 | module.exports = config; 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于React + Webpack + Babel的项目脚手架 2 | 3 | > 这个脚手架工程模板用于快速启动基于 React + Webpack 为技术栈的前端项目 4 | 5 | ## Features 功能特性 6 | 7 | - 可以解析 JSX 语法 8 | - 可以解析 ES6 语法新特性 9 | - 支持 LESS 预处理器 10 | - 支持 SASS 预处理器 11 | - 编译完成自动打开浏览器 12 | - 区分开发环境和生产环境 13 | - 实现组件级热更新 14 | - 实现代码的热替换,浏览器实时刷新查看效果 15 | - 分离业务功能代码和公共依赖代码 16 | - 单独分离 CSS 样式文件 17 | - 支持编译 HTML 模板 18 | - 支持文件 MD5 戳,解决文件缓存问题 19 | - 支持图片、图标字体等资源的编译 20 | - 支持浏览器源码调试 21 | - 可以进行代码规则校验 22 | - 支持 mocha 测试用例运行 23 | - 支持一行命令产出待部署资源 24 | 25 | ## 1. start 26 | 27 | ``` 28 | $ git clone https://github.com/GuoYongfeng/webpack-dev-boilerplate 29 | $ cd webpack-dev-boilerplate 30 | $ npm install 31 | ``` 32 | ## 2. dev 33 | ### 2.1 开发调试 34 | ``` 35 | //首先运行dll预打包 36 | $ npm run start:pre 37 | //打包完成,启动项目 38 | $ npm start 39 | ``` 40 | 41 | 查看效果` http://127.0.0.1:9090` 42 | 43 | ### 2.2 代码检查 44 | ``` 45 | $ npm run lint 46 | ``` 47 | 48 | ### 2.3 测试用例 49 | ``` 50 | $ npm run test:watch 51 | ``` 52 | 53 | ### 2.4 产出资源 54 | ``` 55 | $ npm run build 56 | ``` 57 | 58 | ## 3. 技术栈 59 | 60 | - [x] [Webpack](https://webpack.github.io) 61 | - [x] [React](https://facebook.github.io/react/) 62 | - [x] [ES6](http://es6.ruanyifeng.com/) 63 | - [x] [Redux](https://github.com/rackt/redux) 64 | - [x] [React-router](https://github.com/rackt/react-router-redux) 65 | - [x] [react-router-redux](https://github.com/reactjs/react-router-redux) 66 | - [x] [Babel](https://babeljs.io/) 67 | - [ ] [Autoprefixer](https://github.com/postcss/autoprefixer) 68 | - [ ] [PostCSS](https://github.com/postcss/postcss) 69 | - [x] [CSS modules](https://github.com/outpunk/postcss-modules) 70 | - [x] [Less](https://github.com/less/less.js) 71 | - [x] [Sass](https://github.com/sass/node-sass) 72 | - [x] [Eslint](https://github.com/eslint/eslint) 73 | -------------------------------------------------------------------------------- /conf/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require("path"); 4 | var webpack = require('webpack'); 5 | var config = require('./base'); 6 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 7 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 8 | var BrowserSyncPlugin = require('browser-sync-webpack-plugin'); 9 | 10 | var rootPath = config.commonPath.rootPath; // 项目根目录 11 | var srcPath = config.commonPath.srcPath; // 开发源码目录 12 | var publicPath = config.commonPath.public; 13 | 14 | /** 15 | * output config 16 | * @type {String} 17 | */ 18 | config.output.filename = '[name].js'; 19 | config.output.chunkFilename = '[id].js'; 20 | config.output.publicPath = '/'; 21 | 22 | /** 23 | * devtool config 24 | * @type {[type]} 25 | */ 26 | config.devtool = 'cheap-eval-source-map'; 27 | 28 | /** 29 | * entry config 30 | * @type {Array} 31 | */ 32 | config.entry.app = [ 33 | 'eventsource-polyfill', 34 | 'webpack-hot-middleware/client?reload=true', 35 | 'webpack/hot/only-dev-server', 36 | path.join(srcPath, "index.js") 37 | ]; 38 | 39 | /** 40 | * webpack-dev-server config 41 | * @type {Object} 42 | */ 43 | config.devServer = { 44 | historyApiFallback: true, 45 | hot: true, 46 | inline: true, 47 | contentBase: publicPath, 48 | port: 8080, 49 | stats: { colors: true } 50 | } 51 | 52 | /** 53 | * loader config 54 | * @type {RegExp} 55 | */ 56 | config.module.loaders.push({ 57 | test: /\.css$/, 58 | loader: 'style!css' 59 | }, { 60 | test: /\.less$/, 61 | loader: 'style!css!less' 62 | }); 63 | 64 | config.plugins.push( 65 | new webpack.DllReferencePlugin({ 66 | context: __dirname, 67 | manifest: require(path.resolve(publicPath,'react-manifest.json')), 68 | name:'react_library' 69 | }), 70 | new webpack.optimize.OccurenceOrderPlugin(), 71 | new webpack.HotModuleReplacementPlugin(), 72 | new webpack.NoErrorsPlugin(), 73 | new ExtractTextPlugin('[name].css'), 74 | new BrowserSyncPlugin({ 75 | host: '127.0.0.1', 76 | port: 9090, 77 | proxy: 'http://127.0.0.1:9000/', 78 | logConnections: false, 79 | notify: false 80 | }, { 81 | reload: false 82 | }) 83 | ); 84 | 85 | module.exports = config; 86 | -------------------------------------------------------------------------------- /conf/base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var webpack = require('webpack'); 5 | var HtmlWebpackPlugin = require("html-webpack-plugin"); 6 | 7 | var rootPath = path.resolve(__dirname, '..'); // 项目根目录 8 | var srcPath = path.join(rootPath, 'src'); // 开发源码目录 9 | var env = process.env.NODE_ENV.trim(); // 当前环境 10 | 11 | var commonPath = { 12 | rootPath: rootPath, 13 | srcPath: srcPath, 14 | public: path.join(rootPath, 'public'), // build 后输出目录 15 | indexHTML: path.join(srcPath, 'index.html'), // 入口模板页面 16 | staticDir: path.join(rootPath, 'static') // 不需编译的静态资源 17 | }; 18 | 19 | module.exports = { 20 | commonPath: commonPath, 21 | entry: { 22 | app: path.join(srcPath, 'index.js'), 23 | vendor: [ 24 | 'history', 25 | 'react', 26 | 'react-dom', 27 | 'react-redux', 28 | 'react-router', 29 | 'react-router-redux', 30 | 'redux', 31 | 'redux-thunk' 32 | ] 33 | }, 34 | output: { 35 | path: commonPath.public, 36 | publicPath: '/static/' 37 | }, 38 | resolve: { 39 | extensions: ['', '.js', '.jsx', '.json'], 40 | alias: { } 41 | }, 42 | module: { 43 | loaders: [ 44 | { 45 | test: /\.js[x]?$/, 46 | loaders: ['react-hot', 'babel?cacheDirectory=true'], 47 | exclude: path.join(rootPath, 'node_modules') 48 | }, 49 | { 50 | test: /\.json$/, 51 | loader: 'json' 52 | }, 53 | { 54 | test: /\.html$/, 55 | loader: 'html' 56 | }, 57 | { 58 | test: /\.(png|jpe?g|gif|svg)$/, 59 | loader: 'url', 60 | query: { 61 | limit: 10240, // 10KB 以下使用 base64 62 | name: 'img/[name]-[hash:6].[ext]' 63 | } 64 | }, { 65 | test: /\.(woff2?|eot|ttf|otf)$/, 66 | loader: 'url-loader?limit=10240&name=[name]-[hash:6].[ext]' 67 | } 68 | ] 69 | }, 70 | plugins: [ 71 | new HtmlWebpackPlugin({ 72 | title: 'your app title', 73 | template: commonPath.indexHTML 74 | }), 75 | new webpack.DefinePlugin({ 76 | __DEV__: env === 'development', 77 | __PROD__: env === 'production' 78 | }) 79 | ] 80 | }; 81 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-dev-boilerplate", 3 | "version": "2.0.0", 4 | "description": "boilerplate", 5 | "main": "app/index.js", 6 | "scripts": { 7 | "start:pre":"webpack --config conf/webpack.dll.config.js", 8 | "start": "cross-env NODE_ENV=development node conf/server.dev.js", 9 | "build": "npm run clean && cross-env NODE_ENV=production webpack --progress --colors --config conf/webpack.prod.config.js", 10 | "lint": "eslint app", 11 | "clean": "rm -rf public/*", 12 | "test": "mocha --recursive --compilers js:babel-core/register --require ./test/setup.js", 13 | "test:watch": "npm run test -- --watch" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/GuoYongfeng/webpack-dev-boilerplate.git" 18 | }, 19 | "keywords": [ 20 | "react", 21 | "webpack", 22 | "es6", 23 | "babel" 24 | ], 25 | "author": "guoyongfeng", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/GuoYongfeng/webpack-dev-boilerplate/issues" 29 | }, 30 | "homepage": "https://github.com/GuoYongfeng/webpack-dev-boilerplate#readme", 31 | "dependencies": { 32 | "history": "^4.4.1", 33 | "react": "^15.3.2", 34 | "react-dom": "^15.3.2", 35 | "react-redux": "^4.4.6", 36 | "react-router": "^3.0.0", 37 | "react-router-redux": "^4.0.7", 38 | "redux": "^3.6.0", 39 | "redux-logger": "^2.7.4", 40 | "redux-thunk": "^2.1.0" 41 | }, 42 | "devDependencies": { 43 | "babel-core": "^6.7.2", 44 | "babel-eslint": "^6.0.0", 45 | "babel-loader": "^6.2.4", 46 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 47 | "babel-plugin-transform-runtime": "^6.6.0", 48 | "babel-preset-es2015": "^6.6.0", 49 | "babel-preset-react": "^6.5.0", 50 | "babel-preset-react-optimize": "^1.0.1", 51 | "babel-preset-stage-0": "^6.5.0", 52 | "babel-runtime": "^6.6.1", 53 | "browser-sync": "^2.18.5", 54 | "browser-sync-webpack-plugin": "^1.1.3", 55 | "connect-history-api-fallback": "^1.3.0", 56 | "copy-webpack-plugin": "^1.1.1", 57 | "cross-env": "^3.1.3", 58 | "css-loader": "^0.23.1", 59 | "eslint": "^2.8.0", 60 | "eslint-config-airbnb": "^8.0.0", 61 | "eslint-loader": "^1.3.0", 62 | "eslint-plugin-react": "^4.2.3", 63 | "event-source-polyfill": "0.0.7", 64 | "eventsource-polyfill": "^0.9.6", 65 | "expect": "^1.16.0", 66 | "express": "^4.14.0", 67 | "extract-text-webpack-plugin": "^1.0.1", 68 | "file-loader": "^0.8.5", 69 | "html-loader": "^0.4.4", 70 | "html-webpack-plugin": "^2.10.0", 71 | "jsdom": "^8.2.0", 72 | "json-loader": "^0.5.4", 73 | "less": "^2.6.1", 74 | "less-loader": "^2.2.2", 75 | "mocha": "^2.4.5", 76 | "node-sass": "^3.7.0", 77 | "open-browser-webpack-plugin": "0.0.2", 78 | "react-hot-loader": "^1.3.0", 79 | "sass-loader": "^4.0.0", 80 | "style-loader": "^0.13.0", 81 | "url-loader": "^0.5.7", 82 | "webpack": "^1.12.14", 83 | "webpack-dev-middleware": "^1.8.4", 84 | "webpack-dev-server": "^1.14.1", 85 | "webpack-hot-middleware": "^2.13.2" 86 | } 87 | } 88 | --------------------------------------------------------------------------------