摆脱create-react-app,来让我们自己搭建一个react脚手架

一. 初始化npm、安装webpack和react

  1. 创建一个文件夹REACT-CNODE-TEACH
    mkdir REACT-CNODE-TEACH
  2. 在文件夹中npm init(我们使用npm来管理依赖包)
    在这里插入图片描述
    一路点回车就行,当然你也可以去详细配置下工程信息。
  3. 装一个webpack
    在这里插入图片描述
  4. 一个react工程,怎么能不安装react?
    在这里插入图片描述

二. 客户端webpack配置文件

  1. 这个时候我们要配置一下webpack,我们先在工程根目录创建一个文件夹build,然后创建一个webpack配置文件webpack.config.js。这时,我们可以简单配置一下webpack:
const path = require('path')
const HTMLPlugin = require('html-webpack-plugin')

module.exports = {
    //应用入口
    entry: {
        app: path.join(__dirname, '../client/app.js')
    },

    //打包的文件路径
    output: {
        filename: '[name].[hash].js',
        path: path.join(__dirname, '../dist'),
        //静态资源输出路径
        publicPath: ''
    },

    //用于识别jsx
    module: {
        rules: [
            {
                test: /.jsx$/,//正则表达式
                loader: 'babel-loader'
            },
            {
                test: /.js$/,//正则表达式
                exclude: path.join(__dirname, '../node_modules'),
                loader: 'babel-loader'
            }
        ]
    },

    plugins: [
        //生成一个html文件,同时注入entry
        new HTMLPlugin()
    ]
}
  1. 这个时候我们就可以用webpack来编译工程了。为了操作方便,我们自定义一个npm命令:
    在这里插入图片描述

三. 安装和配置babel

  1. 安装babel
    在这里插入图片描述
  2. babel要想正常使用,还需要在工程根目录添加babel配置文件.babelrc.js
 {
    //babel默认编译es6 es7 es8 不认识jsx 需要配置
    "presets": [
        ["es2015", {"loose": true}],
        "react"
  ]
}
  1. babel中用到的包也要安装一下
    在这里插入图片描述
  2. 此时一个react工程最初的样子已经出来了
    在这里插入图片描述

四. 服务端webpack配置文件

还记得我们在client端是通过把<App/>渲染到document.body中,

//应用入口
import React from 'react'
import ReactDom from 'react-dom'//把react渲染成dom
import App from './App.jsx'

ReactDom.render(<App/>, document.getElementById('root'))

可是服务端是没有document.body的,这里暂且放一下,我们先来配置一下服务端webpack

const path = require('path')

module.exports = {
    target: 'node',//表示webpack打包出来的js是使用在哪个平台的
    //应用入口
    entry: {
        app: path.join(__dirname, '../client/server-entry.js')
    },

    //打包的文件路径
    output: {
        filename: 'server-entry.js',
        path: path.join(__dirname, '../dist'),
        //静态资源输出路径
        publicPath: '',
        libraryTarget: 'commonjs2'
    },

    //用于识别jsx
    module: {
        rules: [
            {
                test: /.jsx$/,//正则表达式
                loader: 'babel-loader'
            },
            {
                test: /.js$/,//正则表达式
                exclude: path.join(__dirname, '../node_modules'),
                loader: 'babel-loader'
            }
        ]
    },
}

接着来写服务端代码,这里用到了node的express框架

const express = require('express')

const ReactSSR = require('react-dom/server')

const fs = require('fs')

const path = require('path')

const template = fs.readFileSync(path.join(__dirname, '../dist/index.html'), 'utf8')

const serverEntry = require('../dist/server-entry').default

const app = express()

app.get('*', function(req, res) {
    const appString = ReactSSR.renderToString(serverEntry)
    res.send(template.replace('<app></app>', appString))
})

app.listen(3333, function() {
    console.log('listening on 3333')
})

服务端渲染的内容会替换前端模板html中的标签


<html>
    <head>
        <title>Document</title>
    </head>

    <body>
        <div id="root"><app></app></div>
    </body>
</html>

五. webpack dev server配置

它可以帮我们通过webpack启动一个服务,它的文件是存在在内存中的,每次有文件变化,它都会自动执行编译,这样就不需手动执行了。

六. hot module replacement配置

有了它,只要文件有变化,页面就会自动刷新

代码仓库在此

猜你喜欢

转载自blog.csdn.net/colinandroid/article/details/89116870