<commit_before>好记性不如烂笔头，之前陆续写过几篇关于玩物圈前端所用到技术栈的总结，现在在[玩物圈PC版](http://wwq.qq.com/mall/goods/detail.html?id=100002)上线之前，将玩物圈前端用到技术栈整体简单总结梳理下。

##1、webpack

![webpack.png](https://camo.githubusercontent.com/ebc085019011ababb0d35024824304831c7dc72a/68747470733a2f2f7765627061636b2e6769746875622e696f2f6173736574732f6c6f676f2e706e67)

webpack是一款模块加载器兼打包工具，具体使用参考[官方文档](http://webpack.github.io/docs/)，**很详细**。

项目中的主要作用：
- 模块管理：模块化管理js、css、image等文件
- 按照模板生成html：主要使用了html-webpack-plugin插件，按照模版生成html文件，并注入指定的chunks
- 静态资源管理，md5，路径重定位

生产配置
```
var webpack = require('webpack');
var path = require('path');
var entry = require('./entry.js');
var templateConfig = require('./html.template.config.js').pro;
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('vendor', 'static/js/vendor.[hash:8].js');

var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var config = {
  entry: entry,
  output: {
    path: __dirname + '/product',
    publicPath: 'http://cdn.xx.com/', 
    filename: 'static/js/[name].[chunkhash:8].js'
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],// 配置可以不书写的后缀名
    root: path.join(__dirname, 'public/') //配置绝对路径，alias、entry中会使用
  },
  module: {
    loaders: [
      {
        test: /\.js[x]?$/,
        include: path.resolve(__dirname, 'public'),
        exclude: /node_modules/,
        loader: 'babel-loader'
      }, {
        test: /\.(jpg|png|gif)$/,
        loader: 'url?limit=1024&name=static/images/[hash].[ext]'//小于1kb的图片转化为base64，css中其他的图片地址会被体会为打包的地址，此处用到了publicPath
      },
      {test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap')}
    ]
  },
  plugins: [
    commonsPlugin,
    new ExtractTextPlugin('static/css/[name].[chunkhash:8].css'),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    commonsPlugin
  ]
};

for (var i = 0; i < templateConfig.length; i++) {
  config.plugins.push(new HtmlWebpackPlugin(templateConfig[i]));
}

module.exports = config;

```

参考文档：
- [官方文档](http://webpack.github.io/docs/)
- [阮一峰 react-babel-webpack-boilerplate](https://github.com/ruanyf/react-babel-webpack-boilerplate)

##2、Babel

![babel.png](https://raw.githubusercontent.com/babel/logo/master/babel.png)

[Babel](https://babeljs.io/)是一个广泛使用的转码器，可以将ES6代码转为ES5代码，JSX语法代码转为ES5代码。
项目中主要使用Babel将源代码ES6、JSX转码为ES5。

##3、React

![](https://facebook.github.io/react/img/logo.svg)

React提供应用的 View 层，表现为组件，具体参考[官方文档](http://facebook.github.io/react/docs/getting-started.html)

主要知识点：
- JSX （可选的）
- 组件（props、state、生命周期、事件、Form、几个api）
- Virtual Dom

我的总结文章：
- [官方文档](http://facebook.github.io/react/docs/getting-started.html)
- [React入门总结(JSX与组件)](https://segmentfault.com/a/1190000004657228)

##4、Redux（单向数据流）

Redux 是 JavaScript 状态容器，提供可预测化的状态管理。本身跟react没有任何关系。

Redux 除了和 React 一起用外，还支持其它界面库。它体小精悍（只有2kB）且没有任何依赖。

![](http://km.oa.com/files/photos/pictures/201602/1456318094_69_w933_h747.png)

###4.1、基本思想
- Action（普通Action、异步Action）
  - 普通Action，本质是JS普通对象
  - 异步Action，使用了 Thunk middleware 异步 action
- Reducer
  - ( previousState, action ) => newState 
  - 处理数据逻辑
  - 拆分和合并reducer（用 ES6 的 import、export 语法，非常方便）
- Store
 - 联系Action与Reducer的对象，为应用提供state

###4.2、中间件Middleware：

类似 Express 或 Koa 框架中的中间件。它提供的是位于 action 被发起之后，到达 reducer 之前的扩展。
中间件的设计使用了非常多的函数式编程的思想，包括：高阶函数，复合函数，柯里化和ES6语法，源码仅仅20行左右。
项目中主要使用了三个中间件，分别解决不同的问题。
- thunkMiddleware：处理异步Action
- apiMiddleware：统一处理API请求。一般情况下，每个 API 请求都至少需要 dispatch 三个不同的 action（请求前、请求成功、请求失败），通过这个中间件可以很方便处理。
- loggerMiddleware：开发环境调试使用，控制台输出应用state日志

我的总结文章：
- [Redux：一种更优雅的 Flux 实现](http://km.oa.com/group/24792/articles/show/252335)
- [单向数据流之 Flux](http://km.oa.com/group/24792/articles/show/252333)

参考：
- [redux中文文档](http://camsong.github.io/redux-in-chinese/)

##5、react-redux
<commit_msg>Update 玩物圈PC版前端技术栈总结.md<commit_after>好记性不如烂笔头，之前陆续写过几篇关于玩物圈前端所用到技术栈的总结，现在在[玩物圈PC版](http://wwq.qq.com/mall/goods/detail.html?id=100002)上线之前，将玩物圈前端用到技术栈整体简单总结梳理下。

##1、webpack

webpack是一款模块加载器兼打包工具，具体使用参考[官方文档](http://webpack.github.io/docs/)，**很详细**。

项目中的主要作用：
- 模块管理：模块化管理js、css、image等文件
- 按照模板生成html：主要使用了html-webpack-plugin插件，按照模版生成html文件，并注入指定的chunks
- 静态资源管理，md5，路径重定位

生产配置
```
var webpack = require('webpack');
var path = require('path');
var entry = require('./entry.js');
var templateConfig = require('./html.template.config.js').pro;
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('vendor', 'static/js/vendor.[hash:8].js');

var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var config = {
  entry: entry,
  output: {
    path: __dirname + '/product',
    publicPath: 'http://cdn.xx.com/', 
    filename: 'static/js/[name].[chunkhash:8].js'
  },
  resolve: {
    extensions: ['', '.js', '.jsx'],// 配置可以不书写的后缀名
    root: path.join(__dirname, 'public/') //配置绝对路径，alias、entry中会使用
  },
  module: {
    loaders: [
      {
        test: /\.js[x]?$/,
        include: path.resolve(__dirname, 'public'),
        exclude: /node_modules/,
        loader: 'babel-loader'
      }, {
        test: /\.(jpg|png|gif)$/,
        loader: 'url?limit=1024&name=static/images/[hash].[ext]'//小于1kb的图片转化为base64，css中其他的图片地址会被体会为打包的地址，此处用到了publicPath
      },
      {test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap')}
    ]
  },
  plugins: [
    commonsPlugin,
    new ExtractTextPlugin('static/css/[name].[chunkhash:8].css'),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    commonsPlugin
  ]
};

for (var i = 0; i < templateConfig.length; i++) {
  config.plugins.push(new HtmlWebpackPlugin(templateConfig[i]));
}

module.exports = config;

```

参考文档：
- [官方文档](http://webpack.github.io/docs/)
- [阮一峰 react-babel-webpack-boilerplate](https://github.com/ruanyf/react-babel-webpack-boilerplate)

##2、Babel

[Babel](https://babeljs.io/)是一个广泛使用的转码器，可以将ES6代码转为ES5代码，JSX语法代码转为ES5代码。
项目中主要使用Babel将源代码ES6、JSX转码为ES5。

##3、React

React提供应用的 View 层，表现为组件，具体参考[官方文档](http://facebook.github.io/react/docs/getting-started.html)

主要知识点：
- JSX （可选的）
- 组件（props、state、生命周期、事件、Form、几个api）
- Virtual Dom

我的总结文章：
- [官方文档](http://facebook.github.io/react/docs/getting-started.html)
- [React入门总结(JSX与组件)](https://segmentfault.com/a/1190000004657228)

##4、Redux（单向数据流）

Redux 是 JavaScript 状态容器，提供可预测化的状态管理。本身跟react没有任何关系。

Redux 除了和 React 一起用外，还支持其它界面库。

![](http://km.oa.com/files/photos/pictures/201602/1456318094_69_w933_h747.png)

###4.1、基本思想

可以参考[Redux：一种更优雅的 Flux 实现](https://segmentfault.com/a/1190000004660632)

- Action（普通Action、异步Action）
  - 普通Action，本质是JS普通对象
  - 异步Action，使用了 Thunk middleware 异步 action
- Reducer
  - ( previousState, action ) => newState 
  - 处理数据逻辑
  - 拆分和合并reducer（用 ES6 的 import、export 语法，非常方便）
- Store
 - 联系Action与Reducer的对象，为应用提供state

###4.2、中间件Middleware：

类似 Express 或 Koa 框架中的中间件。它提供的是位于 action 被发起之后，到达 reducer 之前的扩展。
中间件的设计使用了非常多的函数式编程的思想，包括：高阶函数，复合函数，柯里化和ES6语法，源码仅仅20行左右。
项目中主要使用了三个中间件，分别解决不同的问题。
- thunkMiddleware：处理异步Action
- apiMiddleware：统一处理API请求。一般情况下，每个 API 请求都至少需要 dispatch 三个不同的 action（请求前、请求成功、请求失败），通过这个中间件可以很方便处理。
- loggerMiddleware：开发环境调试使用，控制台输出应用state日志

参考：
- [redux中文文档](http://camsong.github.io/redux-in-chinese/)
- [Redux：一种更优雅的 Flux 实现](https://segmentfault.com/a/1190000004660632)

##5、react-redux

{'fraction_non_alphanumeric': 0.16742019454719825, 'fraction_numerical': 0.0413755308946431, 'mean_word_length': 4.816733067729084, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 11, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2358895', 'n_tokens_mistral': 3827, 'n_tokens_neox': 3914, 'n_words': 346}