从零开始搭建React同构应用(一)

从零开始搭建React同构应用(一)

前言

毕业入职公司后开始搞React,从刚开始只会简单的setState,到后面webpack复杂的配置,Redux,Server Render,都一一上手。期间遇到不少问题,踩过不少坑,最近想以blog的方式把本身开发React同构应用的历程记录下来,一方面能够和你们分享下使用React的经验,另外一方面也算是对本身一年来工做的小总结。javascript

主要内容

  • webpack配置java

  • babel-loader的配置node

  • 在浏览器环境中使用async函数react

代码

这边文章的Demo我已经上传至Githubwebpack

安装webpack

npm install webpack -Dgit

这里要说明的一点是,webpack通常是全局安装,不过接下来的项目采用npm命令来编译配置,npm run command执行时会自动添加node_modules/.bin目录至PATH环境变量,所以不用担忧找不到命令。es6

配置webpack.config.js

先建立一个最简单的webpack配置文件。github

const path = require('path');
//入口文件
let entry = {
    index: './module/index/Index_entry.js'
};

//浏览器端的配置
let browserConfig = {
    entry,
    output: {
        path: path.join(__dirname, 'build'),
        publicPath: '/build',
        filename: "js/[name].bundle.js",
        chunkFilename: "js/[id].bundle.js"
    },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: `babel`,
            }
        ]
    }
};

module.exports = [browserConfig];

这里我将entrybrowserConfig独立开来,module.exports导出的是一个数组,这是为了方便后面server render的配置。web

更详细的配置说明,能够参照webapck的官方文档,这里就不一一说明了。npm

babel的配置

babel能作什么

通常我在开发React app的工做中有三个需求

  • 将JSX转换成ES5语法

  • 将ES7转换成ES5语法

  • 启用async函数的支持

安装babel-loader

先安装babel-corebabel-loader

npm install --save-dev babel-loader babel-core

在我刚刚学习webpack的时候,天真的觉得装完这两个包,就能够转码JSX了,结果就是一直报错,提示说不识别JSX语法。。。弄的我疑惑了好久。。。后来才知道,装完上面两个包以后,还须要进一步的配置(presets),好比指定babel将当前的es7的代码转换到 es2015 的代码,将JSX语法 <Component/> 转换成React.createElement(Component)等等。

配置.babelrc

babel官方预先设定了6个经常使用的presets,咱们日常须要的是babel-preset-es2015babel-preset-react

npm install --save-dev babel-preset-es2015 babel-preset-react

在项目根目录建立.babelrc。固然这里也能够在webpack.config.js中的loaders配置。不过我的以为在.babelrc中配置会更清晰一些。

{
  "presets": [
    "react",
    "es2015"
  ]
}

这样前两个需求就能够完美解决了,哈哈。

启用async函数

regenerator函数让咱们有把异步的函数写成同步的能力,使得代码的可维护性和可阅读性大大提升,而async则是regenerator的语法糖,通常来讲regenerator函数的执行是须要co做为其执行器的,而async函数不用,所以使用起来更加方便优雅。关于async函数的知识能够参考阮一峰大神的书籍ECMAScript 6 入门

若是如今用上面的配置,直接使用regenerator函数的话,会报regeneratorRuntime is not defined错误,这个错误以前也是困扰过我,后面才知道,regenerator没法直接被编译成es5的代码。必须添加polyfill,即regeneratorruntime库才能运行。

先安装对应的babel plugin,这个插件默认会帮咱们把async函数转换成regenerator函数。

npm install babel-plugin-transform-regenerator

代码转换好了后,代码运行时还要一个包 regenerator-runtime/runtime

npm i regenerator-runtime -S

而后在用到async函数的文件头部添加

import 'regenerator-runtime/runtime';

好比在Index.jsx

import React from 'react';
import 'regenerator-runtime/runtime';

export default class extends React.Component {
    constructor() {
        super();

        this.state = {
            pageData: 'loading'
        }
    }

    getAsyncData() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({
                    code: 200,
                    msg: 'success',
                    data: 'hello!'
                })
            }, 2000)
        });
    }

    async componentDidMount() {

        let data = await this.getAsyncData();

        this.setState({
            pageData: data.data
        })

    }

    render() {
        return (
            <div>
                data: {this.state.pageData}
            </div>
        )
    }

}

.babelrc修改为以下所示

{
  "presets": [
    "react",
    "es2015"
  ],
  "plugins": [
    "transform-regenerator"
  ]
}

至此,babel能够完美解决咱们上面提出的3个需求啦。让咱们能够先编译试试。
如今package.json中添加

"scripts": {
    "watch": "webpack -d -w --progress --colors"
  },

执行npm run watch

ok,编译成功

搭建一个简单的静态文件服务器

推荐使用anywhere,详细配置在这

npm i anywhere -g

添加npm script

"scripts": {
    "watch": "webpack -d -w --progress --colors",
    "test-server": "anywhere -s -p 8000 -d ./build"
  },

咱们启动HTTP服务器

npm run test-server

打开http://127.0.0.1:8000/,正常的话以下图所示

你们想亲自尝试的能够fork一份代码研究,哈哈。

第一次写文章,你们多多包涵,有什么错误尽管指出来,^_^。

相关文章
相关标签/搜索