React入門系列 - 2 編寫第一個Hello world的React程式

yodfz發表於2019-01-09

2.1 採用create react app 編寫

create-react-app專案 [點選前往Github] 是facebook推出的入門初始化專案,適合新手第一次使用,無需進行各種配置,完美的實現了開箱即用理念。

2.1.1 建立專案

npx create-react-app my-app
cd my-app
npm start
複製程式碼

npx命令是npm在5.x版本之後推出的一個增強功能,它幫助開發者可以臨時下載專案進行執行之後,會自動刪除這個臨時下載的專案。不會在全域性專案中生成檔案。

上面的命令,表示,下載create-react-app專案,並且執行這個專案,在my-app目錄中建立新專案。

Alt text

2.1.2 執行專案

建立完成之後,進入 my-app 目錄。執行npm語句,進行本地開發預覽。

我們進入這個建立好的資料夾my-app,執行npm run start即可進入本地開發預覽了。

Alt text

如圖所示,我們已經在本地埠3000上執行了這個程式。快開啟你的瀏覽器檢視一下吧。

2.2 手動配置webpack編寫

這個章節有點超綱,有興趣的同學可以仔細閱讀一下。這一節是針對有興趣深入瞭解的同學的,如果你現在一下子還是無法理解這些知識,建議後面再來回顧。

2.2.1 建立專案

我們首先建立一個webpack-app資料夾。然後使用VS Code開啟這個目錄。 使用Ctrl+~鍵開啟控制檯,如果無法開啟說明熱鍵已經被佔用了。點選選單的 檢視 -> 終端

第一步先輸入npm init 建立前端專案的配置檔案。

Alt text

直接一路回車到結束。

2.2.2 安裝必要的開發包

安裝react,react-dom兩個包

npm install --save-dev react react-dom
複製程式碼

安裝webpack

npm install --save-dev webpack-cli webpack webpack-dev-server
複製程式碼

2.2.3 編寫一個react的hello world

首先我們編寫一個HelloWorld的React元件

import React, { PureComponent } from 'react'

export default class index extends PureComponent {
  render() {
    return (
      <div>
        Hello world React!
      </div>
    )
  }
}

複製程式碼

但是這僅僅是一個元件,我們需要一個HTML頁面來容納React的元件。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Helloworld React</title>
</head>
<body>
    <div id="app"></div>
</body>
</html>
複製程式碼

到這一步,React需要準備的東西已經完成了。

我們需要來編寫webpack對這個專案進行打包,而webpack對開發提供的DevServer的支援,讓我們來看一看,到底怎麼做的。

我們在專案根目錄中建立一個名為'webpack.config.js'的檔案。

const path = require('path')

module.exports = {
    mode:'development',
    entry: './src/index.js',
    context: __dirname,
    target: 'web',
    devServer: {
        proxy: {},
        contentBase: path.join(__dirname, 'public'),
        historyApiFallback: true,
        hot: true,
        noInfo: true,
        port: 3000
    }
}
複製程式碼

配置完webpack.config.js檔案之後,我們將在packageInfo.json中的scripts節點加入一個新的命令。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
  },
複製程式碼

我們在終端執行npm run dev之後,你將會在控制檯中看到如下內容。

Alt text

webpack編譯之後告訴我們,它無法識別JSX格式。這個問題就延伸出了,我們該如何對現代化的前端進行配置。

現在對於前端程式碼的轉換,通常採用的是babel轉譯。我們來看看編譯react需要哪些外掛。點此檢視babel如何配置webpack

  1. 首先,我們需要安裝babel,在終端輸入npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
  2. 我們修改webpack.config.js檔案,讓他看起來像這樣
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',
    entry: './src/entry.js',
    context: __dirname,
    target: 'web',
    devServer: {
        proxy: {},
        contentBase: path.join(__dirname, 'public'),
        port: 3000
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    plugins: [
        new HtmlWebpackPlugin(
            Object.assign({}, {
                inject: true,
                template: __dirname + '/public/index.html',
            })
        ),
    ]
}
複製程式碼
  1. 在根目錄建立.bablerc檔案,這個檔案是用於配置babel編譯的,在檔案中輸入以下內容。
{
    "presets": ["@babel/preset-env","@babel/preset-react"]
}
複製程式碼
  1. 不知道你是否注意到了,我修改了entry入口檔案。因為僅僅一個React元件並無法正常執行,我們需要告知React框架,我們將元件注入在哪個DOM下,這個檔案可以配置全域性的Store、路由、全域性的設定等。我們在src目錄下建立entry.js,下面是entry.js檔案的原始碼。
import React from 'react';
import ReactDOM from 'react-dom';
import Index from './index';

ReactDOM.render(<Index />, document.querySelector('#app'));
複製程式碼

程式碼非常的簡單,就是呼叫ReactDOM將React元件渲染到了id為app的節點下。

OK,現在我們再次執行npm run dev,你將會看到webpack編譯成功的提示,我們現在開啟瀏覽器,輸入http://localhost:3000,你將會看到執行編譯成功的網頁。

Alt text

2.2.4 webpack加入HMR支援(熱更新)

大家有沒有發現,我們現在這個專案修改了之後,是需要重新整理整個頁面的。並沒有那種很高階很大氣的動態重新整理?

現在我們就將熱更新加入我們的專案中。

我們將webpack.config.js檔案做如下修改

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack')

module.exports = {
    mode: 'development',
    entry: [
        'webpack/hot/dev-server',
        './src/entry.js'
    ],
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    context: __dirname,
    target: 'web',
    devServer: {
        proxy: {},
        contentBase: path.join(__dirname, 'public'),
        hot: true,
        port: 3000
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader"
        }]
    },
    plugins: [
        new HtmlWebpackPlugin(
            Object.assign({}, {
                inject: true,
                template: __dirname + '/public/index.html',
            })
        ),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin()
    ]
}
複製程式碼

注意到了麼,我們新增了NamedModulesPluginHotModuleReplacementPlugin兩個外掛。還在devServer節點中加入了hot:true,並且追加了output節點。

然後,我們將entry.js檔案修改為這樣:

import React from 'react';
import ReactDOM from 'react-dom';
import Index from './index';

ReactDOM.render( < Index / > , document.querySelector('#app'));
if (module.hot) {
    module.hot.accept()
}
複製程式碼

我們再次使用npm run dev執行專案,然後修改index.js檔案中的字串,你會發現,現在是無重新整理更新頁面內容了。

2.2.5 webpack優化打包速度

我們在package.jsonscripts節點中加入一條新語句"webpack":"webpack",然後來看一看現在專案預設的打包速度是多少時間。

Alt text

耗時:2211ms

2.2.5.1 babel快取

我們修改webpack.config.js檔案中的babel配置項

 module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: "babel-loader?cacheDirectory=true"
        }]
    },
複製程式碼

babel-loader後面加入了cacheDirectory=true,再次執行編譯,第一次你會發現速度並沒有優化,這是因為還沒有建立快取檔案,但是第二次速度就提升了20%。

Alt text

耗時:1644ms (-500ms)

其他的包括抽取公共元件,加入hash等等策略我們以後再細聊。

原始碼下載地址:github.com/yodfz/learn…

原文地址:www.yodfz.com/detail/35/2…

相關文章