记一次改造react脚手架的过程

Posted 糊糊糊糊糊了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次改造react脚手架的过程相关的知识,希望对你有一定的参考价值。

公司突然组织需要重新搭建一个基于node的论坛系统,前端采用react,上网找了一些脚手架,或多或少不能满足自己的需求,最终在基于YeoManreact脚手架generator-react-webpack上搭建改造,这里作为记录。

代码在这里:github

另外推荐地址:react-starter-kit

简单文件夹结构

├── README.md                       # 项目README文件
├── conf                            # 配置文件夹
│   └── webpack                     # webpack配置(下面包括开发、生产、测试环境的配置)
├── karma.conf.js                   # karma测试配置文件
├── node_modules                    # 包文件夹
├── package.json                    # 包描述文件
├── src                             # 源文件夹
│   ├── actions                     # redux actions文件夹
│   ├── client.js                   # 客户端启动文件
│   ├── components                  # 项目组件(下面分为业务组件和公共组件)
│   ├── config                      # 环境配置文件夹(指明当前环境)
│   ├── containers                  # 入口容器
│   ├── exports.js                  # 常用组件的exports文件,可以忽略
│   ├── images                      # 图片
│   ├── index-release.html          # 生产环境模板文件
│   ├── index.html                  # 开发环境入口html
│   ├── reducers                    # redux reducers文件夹
│   ├── routes                      # 路由配置
│   ├── sources                     # 资源文件(可忽略)
│   ├── static                      # 静态文件(可以存放第三方库)
│   ├── stores                      # redux stores文件夹
│   ├── styles                      # 全局样式文件夹
│   └── views                       # 视图文件夹
├── test                            # 测试文件夹
│   ├── actions                     # 测试actions
│   ├── components                  # 测试组件
│   ├── config                      # 测试配置(检测环境)
│   ├── loadtests.js                # 加载测试文件
│   ├── reducers                    # 测试reducers
│   ├── sources                     # 测试资源(flux datasource)
│   └── stores                      # 测试stores
└── webpack.config.js               # webpack配置入口文件

整体应用技术

  • react
  • redux
  • react-router(4.0.0^,可以换成2x或者3x)
  • eslint
  • karma + mocha
  • immutable(可选)

在原始脚手架上新增

  • 路由(react-router)
  • 调试工具(react devTools)
  • 增加文件分类(images/fonts/media)
  • 生产配置增加文件hash,公共库拆分
  • 添加异步middleware,统一处理全局状态
  • 改造Actions/Reducers

改造过程

拆分生产环境公共库,生成文件hash

this.config = {
    cache: false,
    devtool: \'source-map\',
    entry: {
        main: [\'./client.js\'],
        vendor: [\'react\', \'react-dom\', \'redux\', \'react-redux\', \'react-router-dom\',
                 \'react-router-redux\', \'react-css-modules\', \'history\']
    },
    plugins: [
        new webpack.DefinePlugin({
          	\'process.env.NODE_ENV\': \'"production"\'
        }),
        new webpack.optimize.AggressiveMergingPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        new webpack.optimize.CommonsChunkPlugin({
          	name: \'vendor\',
          	minChunks: Infinity
        }),
        new HtmlWebpackPlugin({
            filename: path.resolve(\'./dist/index.html\'),
            template: path.resolve(\'./src/index-release.html\'),
            inject: \'body\'
        })
    ]
};

this.config.output.filename = \'[name].[chunkhash].js\';

主要在entry上做了文章,将公共库分离成vendor,同时配合CommonsChunkPlugin进行代码抽离。最后将output的文件名加上chunkhash`,这样在新打包的文件不会被浏览器缓存策略而缓存

基本配置文件区分静态文件目录

{
    test: /\\.(png|jpg|gif|ico|swf|xap)$/,
    loaders: [
        {
            loader: \'file-loader\',
            query: {
              	name: \'images/[name].[ext]\'
            }
        }
    ]
}

主要使用query配置,区分不同文件目录。fonts/media相同道理配置即可

组件区分

├── bussiness
│   └── README.md
└── common
    ├── README.md
    ├── Template.js
    ├── YeomanImage.js
    └── button

主要区分业务组件和公共组件。当然你也可以不区分,引用常用的公共库如蚂蚁金服的react前端库,进行改造。如果你需要自己写组件的话,个人愚见还是区分一下。

加入immutable

加入这个看个人意愿,加入之后必定会造成一定的学习以及开发成本,但是对redux来说,运用这个库是再好不过的了,具体表现在数据的不可变性,即每次的数据都会是一个新的,不会在原始引用的数据上进行重新操作,以免造成数据污染。

// reducers/items.js
const initialState = fromJS({
    items: [
        {
            "forum_name": "武汉大学",
            "user_level": 12,
            "user_exp": 5301,
            "id": 30996,
            "is_like": 1,
            "favo_type": 2
        },
      	// ...
    ]
});

function reducer(state = initialState, action) {
    switch (action.type) {
        case GET_ITEMS:
            return state;
        default:
            return state;

    }
}

// views/Home.js
render() {
    const list = items.get(\'items\');
  	// ...
  	{
      list.map((l, index) => {
        return (
            <tr key={ `list${index}` }>
                <td>{ l.get(\'forum_name\') }</td>
                <td>{ l.get(\'user_level\') }</td>
                <td>{ l.get(\'user_exp\') }</td>
                <td>{ l.get(\'is_like\') === 0 ? \'是\' : \'否\' }</td>
                <td>{ l.get(\'favo_type\') }</td>
            </tr>
          );
		})
	}
}

如果不清楚immutable,可以自行百度、谷歌。

使用路由,拆分views文件夹

加入react-router,脚手架中是没有生成路由的(可能有吧,只是楼主没有找到

以上是关于记一次改造react脚手架的过程的主要内容,如果未能解决你的问题,请参考以下文章

记一次drools5的性能优化过程

记一次debug过程

记一次 React Native 大版本升级过程——从0.40到0.59

记一次webpack4+react+antd项目优化打包文件体积的过程

记一次企业级爬虫系统升级改造:文本分析与数据建模规则化处理

73 记一次 sprintboot 项目改造之后处理不了 websocket 消息