0%

[ReactJS] 從頭建立一個 ReactJS 專案

前言

已經有許多套件 (如:CRA、Next.js) 幫忙將 ReactJS 的開發環境包好,讓前端工程師不需花心力在 Webpack 與 Babel 的設定上,對初學者來說是友善的。但相信到一定的程度後,會想要從頭建立一個 ReactJS 專案,藉此了解每個依賴包的作用。因此這篇文章記錄如何從頭設定 Babel、Webpack 讓 ReactJS 可以正常運作,讓未來的自己與讀者們可以從中複習與學習。

專案成品 GitHub

Node.js

先確認有安裝 Node.js,若沒有可先至官方網站根據自己的作業系統下載並安裝,至終端機確認 Node 版本

1
2
[wrxue@p ~]$ node -v
v14.17.5

初始化 Node 專案

建立一個名稱為 react-from-scratch 的目錄並初始化

1
2
3
[wrxue@p ~]$ mkdir react-from-scratch
[wrxue@p ~]$ cd react-from-scratch
[wrxue@p react-from-scratch]$ npm init -y

初始化使用 npm init -y 是偷懶的方式,讓我們可以跳過填寫專案資訊的步驟,直接建立專案,至於專案的資訊等到之後回頭來修改 package.json 即可。讀者也可以選擇使用 npm init 認真的將專案資訊透過問答方式填寫完成。

ReactJS

ReactJS 安裝

不用多說,要用 ReactJS 開發就一定要安裝它啊!

1
[wrxue@p react-from-scratch]$ npm install react react-dom
  • react:ReactJS 主要功能皆包含在內。
  • react-dom:可說是 ReactJS 與 DOM 之間的橋樑,通常只會用到 ReactDOM.render() 函式。

ReactJS 程式碼

建立 ./src/App.js,輸出一個 App 元件

1
2
3
4
5
6
7
import React from "react";

const App = () => {
return <h1>從頭開始建立 ReactJS 專案成功!</h1>
}

export default App;

建立 ./src/index.js,使用 App 元件並使用 ReactDOM.render() 將其顯示在網頁上

1
2
3
4
5
6
7
8
9
import React from "react";
import ReactDOM from "react-dom";

import App from './App';

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

Babel

Babel 安裝

Babel 是寫 ES6 以上的語法或 ReactJS 時,常常會用到的一個套件,扮演著轉譯 (transpiling,有些人會說編譯,個人認為是不對的說法) 的角色,將這些尚未普及的語法轉譯為 ES5 語法,使瀏覽器可以順利執行。也因此,Babel 是需要安裝的

1
[wrxue@p react-from-scratch]$ npm install --save-dev @babel/core @babel/preset-react
  • @babel/core:使用 Babel 執行轉譯動作的關鍵套件。
  • @babel/preset-react:Babel preset 則是一組含有特定目標語法集合,例如:preset-react 可以使 Babel 將目標語法 jsx 轉譯成 createElement

Babel 設定

Babel 在預設的情況下不會做任何事,需要透過 .babelrc 檔案來告訴它應該做甚麼,因此先於專案根目錄建立 .babelrc 檔案,並且內容如下,意思是跟 Babel 說:「請幫我使用 preset-react 這組語法集合轉譯程式碼。」

1
2
3
{
"presets": ["@babel/preset-react"]
}

Webpack

Webpack 安裝

Webpack 可以幫我們將各種資源 (.js/.sass/.png...等等) 打包為可以發布的狀態,一個專案只需設定一次,便能夠讓我們只專注於 ReactJS 應用開發的部分,這麼方便的套件是必須要安裝的

1
[wrxue@p react-from-scratch]$ npm install --save-dev webpack webpack-cli babel-loader html-webpack-plugin
  • webpack:包含 Webpack 主要功能的套件。
  • webpack-cli:Webpack 4 以上已將 CLI 從 webpack 獨立出來並命名為 webpack-cli
  • babel-loader:Webpack 在打包過程中,可透過 babel-loader 來載入 Babel 轉譯指定檔案。
  • html-webpack-plugin:一個簡化建立 HTML 檔案的套件,特別是當每次 bundle 出來的 js 檔名都包含雜湊值 (Hash Value) 時,特別有用。

Webpack 設定

於專案根目錄建立內容如下的 webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
entry: {
index: './src/index.js',
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'WRXUE 手把手從頭開始建立 ReactJS 專案',
template: 'template.html'
}),
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: ['babel-loader']
}
]
}
}
  • entry:使用 Webpack 打包時,第一個要進入的檔案為 ./src/index.js
  • output:輸出檔案相關設定。
    • filename:打包完成的檔案應該有的檔名形式,方括號 ([]) 內的字串是將會被替代的字串。
    • path:打包後的檔案輸出的目錄。
  • plugins:使用外掛套件 html-webpack-plugin 協助打包,它可以自動將打包好的 js 自動補進 html 檔案做引用 (例如:<script defer="defer" src="index.49aa003bf7e7b451d135.js"></script>),毋須每次檔名有更動就需要手動輸入。
  • module.rules:Webpack 會依據指定的 rule 處理對應的檔案。
    • test:檔名的匹配模式,即只要結尾為 .js.jsx 的檔案皆為匹配成功。
    • use:若匹配,則使用 babel-loader 來處理匹配成功的檔案。

html-webpack-plugin 可以使用模板來建立 html 檔案,因為在 ReactJS 中通常會需要 <div id="root"></div> 來作為根結點,因此於專案根目錄建立 template.html,其內容如下

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
  • htmlWebpackPlugin.options:在 webpack.config.js 中會將一個物件傳給 html-webpack-plugin 套件,在模板中可透過 EJS 語法來存取對應的值。

scripts

在 package.json 檔案中的 scripts 加上啟用 webpack 的指令

1
2
3
4
5
6
...
"scripts": {
...
"build": "webpack"
},
...

執行 Webpack 打包應用程式

1
2
3
4
5
6
7
8
[wrxue@p react-from-scratch]$ npm run build

> react-from-scratch@1.0.0 build ~/react-from-scratch
> webpack

asset index.b637f7a49c9b2904dcbd.js 127 KiB [emitted] [immutable] [minimized] (name: index) 1 related asset
asset index.html 381 bytes [emitted] [compared for emit]
orphan modules 200 bytes [orphan] 1 module

使用瀏覽器開啟 ./dist/index.html 且能看到結果即代表 ReactJS 開發環境建置成功。

ReactJS 專案建立完成ReactJS 專案建立完成

結語

筆者猜測多數人應該是從 CRA 開始接觸 ReactJS 的開發,再慢慢地去瞭解 Webpack、Babel 等這些關鍵套件的使用。因為筆者自己也不例外,所以想藉由這個機會從頭開始建立一個 ReactJS 開發環境,並明確的理解每個套件的分工。過程中拜讀許多前輩產出的文獻,不乏將原理說明清楚的好文,也因此對於 ReactJS 專案背後的運作更為清晰,同時將有用的文獻紀錄下來供讀者參考。

參考文獻

  1. React vs ReactDOM?

  2. babel vs babel-core vs babel-loader vs babel-preset-2015 vs babel-preset-react vs babel-polyfill

  3. React Day12 - Babel介紹

  4. install webpack VS install webpack-cli?

  5. Getting Started | webpack

  6. Output | webpack

  7. HtmlWebpackPlugin

  8. <div id="root"></div> not transfering in webpack build

  9. Don't use create-react-app: How you can set up your own reactjs boilerplate.

  10. Create React App from Scratch like a Pro

很高興能在這裡幫助到您,歡迎登入 Liker 為我鼓掌 5 次,或者成為我的讚賞公民,鼓勵我繼續創造優質文章。
以最優質的內容回應您的鼓勵