我的第一个正式react demo?

以前在看深入浅出react和redux的时候, 那个demo 总是用creat-react-app 创建的, 现在终于可以实现自己手动搭建一个简单的demo了。

1.首先新建一个文件夹, 执行npm init

2.安装各类插件如下:

{
  "name": "react_first",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack-dev-server --hot"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-react-hmre": "^1.1.1",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.20.2",
    "webpack-dev-server": "^3.1.9"
  },
  "dependencies": {
    "babel-loader": "^7.1.5",
    "react": "^16.5.2",
    "react-dom": "^16.5.2"
  }
}

3.配置.babelrc文件(windows下需要创建.babelrc.)后面有一个.啊

{
    "presets": [
        "es2015","react"
    ],
    "env":{
        "development":{
            "presets":["react-hmre"]
        }
    }
}

4.创建配置文件webpack.config.js

var path=require('path');
var webpack=require('webpack');
var HtmlwebpackPlugin=require('html-webpack-plugin');

var ROOT_PATH=path.resolve(__dirname);
var APP_PATH=path.resolve(ROOT_PATH,'app');
var BUILD_PATH=path.resolve(ROOT_PATH,'build');

module.exports= {
    entry:{
        app: path.resolve(APP_PATH,'app.jsx')
    },
    output:{
        path:BUILD_PATH,
        filename:'bundle.js'
    },
    devtool:'eval-source-map',
    devServer: {
        historyApiFallback: true,
        hot: true,
        inline: true,
        progress: true
    },
    resolve:{
        extensions:['.js','.jsx'],
        modules: [APP_PATH, 'node_modules'],
    },
    module:{
        rules:[
            {
                test:/\.jsx?$/,
                loaders:['babel-loader'],
                include:APP_PATH,
            }
        ]
    },
    plugins:[
        new HtmlwebpackPlugin({
            title:'my first react app'
        })
    ]
};

6.创建简单的app.jsx(在app目录下)

import React from 'react';
import ReactDOM from 'react-dom';

function App() {
  return (
    <div className="container">
      <h1>Hello React h111!</h1>
    </div>
  );
}

const app = document.createElement('div');
document.body.appendChild(app);
ReactDOM.render(<App />, app);

7.完工 直接运行npm run dev, 然后访问浏览器, 修改app.jsx里面h1的内容, 检查页面热加载

上面的demo 是用的webpack-dev-server 服务器,现在我们来搞一个 express服务器的demo,首先package.json如下:

{
  "name": "react-server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-react-hmre": "^1.1.1",
    "express": "^4.16.3",
    "webpack": "^4.20.2",
    "webpack-dev-middleware": "^3.4.0",
    "webpack-hot-middleware": "^2.24.2"
  },
  "dependencies": {
    "babel-loader": "^7.1.5",
    "react": "^16.5.2",
    "react-dom": "^16.5.2"
  }
}

在同级目录下新建webpack.config.js如下:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './index.js'
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/,
        include: __dirname
      }
    ]
  }
};

在同级目录下 新建server.js文件, 也就是package.json start 需要的那个服务器文件:

/* eslint-disable */
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');
var config = require('./webpack.config');

var app = new (require('express'))();
var port = 3000;

var compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
app.use(webpackHotMiddleware(compiler));

app.get("/", function(req, res) {
  res.sendFile(__dirname + '/index.html')
});

app.listen(port, function(error) {
  if (error) {
    console.error(error)
  } else {
    console.info("==> ????  Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port)
  }
});

最后新建src\App.js(因为App需要作为顶层组件,所以必须启用状态,也就是说这里不能用无状态方式, 即一个普通的function):

import React, {Component} from 'react';

export default class App extends Component{
    render(){
        return(
            <h1>hello world 232232332</h1>
        );
    }
}

index.js

import React from 'react';
import {render} from 'react-dom';
import App from './src/App';

render((<App />) ,document.querySelector("#root"));

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Example</title>
  </head>
  <body>
    <div >
    </div>
    <script src="/static/bundle.js"></script>
  </body>
</html>

.babelrc 和先前的哦诶之一样:

{
    "presets": [ "es2015","react"],
    "env": {
        "development":{
            "presets":["react-hmre"]
        }
    }
}