擺脫create-react-app,來讓我們自己搭建一個react腳手架

Colin_Mindset發表於2019-04-09

一. 初始化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配置

有了它,只要檔案有變化,頁面就會自動重新整理

程式碼倉庫在此

相關文章