學習 React、JSX、ES2015、Babel、Webpack 等等現代化的前端開發觀念時,會需要安裝很多工具、設定多個檔案、用到許多指令。
大部份教學文章只講「怎麼設定這些」而沒說明「為何要設定這些」。照著做完感覺很不放心。
最近我試著搞懂「為何要設定這些」,跟大家分享一下這個逐步搞懂的過程。
前言
這篇文章假設你想要開始用 React 開發,希望搞懂相關的前端環境與設定。
如果你想知道用 React 到底有什麼好處,可以參閱以下連結:
Introducing JSX、Thinking in React、簡單聊一下 ONE-WAY DATA FLOW、TWO-WAY DATA BINDING 與前端框架
接下來,這篇文章會以試著寫一個陽春的 App 元件作為範例,內含 ChildA 跟 ChildB 兩個元件。
讓我們開始吧!
第一步:直接在 html 檔內開發 React 給瀏覽器執行
我們先用原始的開發方法硬搞看看!
用 script 標籤直接從 CDN 引入 react.js 跟 react-dom.js 檔案。
然後試著寫一個陽春的 App 元件,內含 ChildA 跟 ChildB 兩個元件。
這個 html 檔內容會像這樣:
Should Render Here
結果瀏覽器無法執行 React 相關的程式碼!
原因有兩個:
1. 瀏覽器看不懂 ES2015 的語法(class、extends)
2. 瀏覽器看不懂那個像是把 html 寫在 js 裡面的 JSX 語法
該怎麼辦呢?
第二步:用 Babel 讓瀏覽器能看懂 ES2015 與 JSX 語法
我們可以使用 Babel 套件來來編譯 ES2015 與 JSX 的程式碼,讓瀏覽器能夠看懂。
只要在 html 內加上這行:
然後在要編譯的 script 加上 type=’text/babel’ 即可:
Should Render Here
然而,這樣做卻又產生3個新的問題:
1. 有N個檔案,就要打編譯指令N次,太累了
2. 透過 script 標籤引入N個檔案,會增加伺服器負擔、也會增加用戶端等待時間
3. babel 相關的程式碼都移出瀏覽器了,react.js 跟 react-dom.js 卻還是在瀏覽器內引入
第一個問題還算簡單,可以改成輸入指定資料夾的指令,就可一次編譯:
./node_modules/.bin/babel src/ -d dist/ --presets es2015,react
但是第二三個問題就棘手得多。
有鑑於此,需要找方法一次解決這三個問題:設法一口氣全部編譯、封裝成單一檔案、並且函式庫統一用NPM在伺服器端安裝與管理吧!
第四步:使用 webpack 來解決這些整合問題
webpack 會利用 babel-loader 套件來呼叫核心的 babel-core,所以先分別安裝它們:
npm install --save-dev babel-core
npm install --save-dev babel-loader
npm install --save-dev webpack
我們不會透過命令列去使用 babel 了,既然用不到就先把它移除吧:
npm uninstall babel-cli
我們也不會用 script 標籤引入 react.js 跟 react-dom.js 檔案了。一口氣全部編譯時會用到,所以用NPM安裝它吧:
npm install --save-dev react
npm install --save-dev react-dom
前面說過 babel 版本 6 以後預設不支援 ES2015 與 JSX,現在不透過命令列設定 presets 的話,就需要建立 .babelrc 檔案去開啟支援:
{ "presets": ["es2015", "react"] }
然後為了讓 webpack 在一口氣全部編譯成一個檔案時,能看懂檔案跟套件之間的相依性,因此需要按照 ES2015 的 import/export 語法寫清楚。
例如原本的 App.jsx 就要改寫成這樣:
import React from 'react'; import ChildA from './ChildA.jsx'; import ChildB from './ChildB.jsx'; export default class App extends React.Component { render() { return (); } }Hello App!
src 資料夾內的檔案都要進行改寫。
最後建立 webpack.config.js 來設定檔案路徑,並指定使用 babel-loader 來幫忙編譯:
var path = require('path'); module.exports = { module: { loaders: [{ loader: 'babel-loader', }] }, entry: './src/index.jsx', output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist/') } }
就可以透過命令列執行 webpack了:
./node_modules/.bin/webpack
這段指令有點長,可以把它放進 package.json 的 scripts 欄位:
"scripts": { "build": "webpack" },
之後就可以用下列指令來進行編譯工作了:
npm run build
會得到我們要的結果:一個檔案搞定一切!
Should Render Here
大功告成!終於搞定我們想要的所有效果!
結語
本篇文章提到的內容,根據不同的套件版本,實務上有多種方式去安裝、設定達到同樣效果。
但是核心觀念是共通的!
可以此為基礎,探索更多的現代前端開發方法,學習更多工具的功能與設定!
(完)
(Photo via 8 Kome, CC licensed.)