此係列更多的是個人對環境構建的一些記錄,純屬個人的自娛自樂順便做個分享,可以當做一個 React 的入門練習。
文末tip:–save 與 --save-dev 區別
**注:**需要注意的是此類講步驟的文章由於第三方庫的升級更新,具有一定的時限性,僅做參考。本人也會不定期更新最新的一些步驟和新的坑吧~
目標
命令行鍵入 npm start
,訪問 localhost:8080
可以訪問到一個 hello world
的頁面。
可能這個看着很簡單,不過當時我在自己配置的時候也是廢了一些功夫,如果覺得簡單可以跳過這一節(文末總結處有此節代碼)
步驟
1. init 項目
- 新建文件夾並進入
mkdir react-cli
cd react-cli
- npm init 根據步驟填寫配置信息(具體的配置項不說啦,可以一路回車下來,只是要它生成一個
package.json
文件)
npm init
2.修改文件目錄
在 react-cli
文件夾下,新建一個 src
文件夾,src
文件夾裏建一個 app.js
.
+-- src 程序目錄
| +-- app.js 入口文件
3. 安裝 webpack
工慾善其事必先利其器,前端開發選擇一款適合的前端構造工具是非常必要的,這裏我們使用 Facebook 開源的 webpack
來搭建一個完全不依賴服務器的開發環境。
常見的前端構造工具(傳送門)
回到項目目錄 react-cli
文件夾下
npm install webpack -D
新建 webpack.config.js
文件,根據 webpack 文檔編寫配置文件,下面附一個最基本的,之後會不斷往裏面填配置的
var path = require('path')
module.exports = {
// 入口 入口文件是 ./app/index.js
entry: path.join(__dirname, './app/index.js'),
// 出口 文件會輸出到 dist 文件夾,輸出的文件名叫 bundle.js
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
}
path 是 node.js 的內置模塊,不建議直接寫路徑,而是利用
path.join()
進行目錄拼接(看一看 Node.js 的文件路徑)
entry
、output
及之後會提到的概念這裏不涉及講解,自行去 webpack 官方手冊學習。
因爲我們在 entry 配置中設了 ./app/index.js
,所以我們先在項目根目錄建一個 app 文件夾,再在裏面新建一個 index.js
文件
在命令行運行:
webpack --config webpack.config.js
我們會發現在項目目錄下會自動生成 bundle
文件夾和 bundle.js
文件
運行
webpack
需全局安裝 webpack,如報錯運行npm install webpack webpack-cli -g
此時,在 client/dist
文件夾下新建一個 index.html
index.html
的內容如下:
<!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>Document</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
並且在 src/app.js
中填寫:
document.getElementById('root').innerHTML = 'hello world'
然後訪問 index.html 可以看到 hello world
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-L71a6kne-1572072671124)(https://github.com/zwkkkk1/react-cli/blob/chapter-1/doc/assets/image/chapter-1/QQ20181031-155238.png)]
請注意 URL,我們並不是用 localhost:8080
訪問的頁面,而且還沒有使用 React
4. 引入 React
接下來我們引入 React
npm install react react-dom --save
再在 src/app.js
加入 react 代碼
import React from 'react'
import ReactDom from 'react-dom'
ReactDom.render(<div>hello world</div>,
document.getElementById('root'))
重新進行 webpack
webpack --config webpack.config.js
這裏會報錯:
因爲 <div>hello world</div>
的 jsx 語法,我們的瀏覽器可不認識這個,我們需要引入 babel 去編譯我們的 React 代碼
引入 babel
babel 把用最新標準編寫的 JavaScript 代碼向下編譯爲可以隨處可用的版本
npm install babel-loader@7 babel-core@6 babel-preset-react babel-preset-env babel-preset-stage-0 -D
如果報版本之類的問題,請根據提示下載指定版本的
babel-core
或babel-loader
babel-loader@8
對應的是babel-core@7
babel-loader@7
對應的是babel-core@6
(我使用的是babel-loader@7
)
我們先來看看我們下載的一連串 babel 的作用吧
- babel-core Babel 的核心代碼
- babel-loader 解析 js 的 loader
- babel-preset-react 用於解析 jsx 語法
- babel-preset-env 取代之前的
babel-preset-es2015
babel-preset-es2016
等包,解析 ES6 等語法 - babel-preset-stage-0 用於解析 ES7 提案
項目目錄下新建 .babelrc
文件輸入:
{
"presets": [
"env",
"react",
"stage-0"
]
}
webpack.config.js
加入配置:
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader?cacheDirectory=true'],
}
]
}
下面是兩個性能優化的點
1. cacheDirectory
cacheDirectory
默認爲 false
,當進行設置時,指定的目錄將用來緩存 loader 的執行結果。之後的 webpack 構建,將會嘗試讀取緩存,來避免每次執行時,可能產生的、高性能消耗的 Babel 重新編譯過程。
像我們上面設置的 babel-loader?cacheDirectory=true
或是設置爲空值 babel-loader?cacheDirectory
,默認緩存目錄在 node_modules/.cache/babel-loader
2.exclude
我們設置的 exclude: /node_modules/
,表示 babel-loader
不會檢查 node_module
文件夾。
因爲 node_module
下的第三方庫都是提前編譯打包好的,我們需要避免重複去編譯它們。
引入上面的 babel 後,重新編譯,再次訪問 index.html
,同樣可以看到 hello world,下一節我們來看看如何用 localhost:8080
訪問頁面
5. 引入 webpack-dev-server
簡單來說,webpack-dev-server
是一個小型的 Node.js 服務器,可以爲 webpack 打包生成的資源文件提供 Web 服務(只用於開發環境)
下載 webpack-dev-server
devServer: {
port: 8080,
contentBase: path.join(__dirname, './dist'),
historyApiFallback: true,
}
port
、contentBase
的概念很容易理解,看一下手冊就可以了,我們來講一講 historyApiFallback
。
簡單說,historyApiFallback
任意的 404
響應都會被替代爲 index.html
,沒有設置的話在使用 React Router 的時候可能會遇到問題。
然後運行 webpack-dev-server --config webpack.config.js
有可能會報找不到 webpack-dev-server 命令 npm install webpack-dev-server -g
就 ok 了~
這裏可能會報錯:
The CLI moved into a separate package: webpack-cli
Please install 'webpack-cli' in addition to webpack itself to use the CLI
-> When using npm: npm i -D webpack-cli
-> When using yarn: yarn add -D webpack-cli
internal/modules/cjs/loader.js:583
throw err;
^
Error: Cannot find module 'webpack-cli/bin/config-yargs'
根據提示下載 webpack-cli
,npm install webpack-cli -D
也有可能報 Error: listen EADDRINUSE 127.0.0.1:8080
,這裏在前面 webpack.config.js
中將 8080 換成其他端口就好了
然後訪問 localhost:8080
(或其他端口) 就能看到 hello world 了。
大功告成,不過我們的目標中可是要 npm start
,下一節我們看看怎麼設置 npm start
6. 修改 Npm Scripts
在常見前端構建工具中,我們已經看到 npm scripts
了,我們可以在 package.json
文件裏使用 scripts 字段定義任務,來方便我們鍵入的操作
{
"scripts": {
"start: "webpack-dev-server --config webpack.config.js"
}
}
設置好後我們就可以 npm start
了~
tip1: --save 與 --save-dev 區別
我們在前面下載軟件時常會用 npm install --save
,時常會用 npm install -D
,下面我說說兩者區別(npm install -D
是 npm install --save-dev
的簡寫)
--save-dev
指將包信息添加到package.json
的devDependencies
屬性下,表示開發時依賴的包- 像各種 loader、前面只用於開發環境的 webpack-dev-server、webpack、webpack-cli 還有測試相關 npm 包都是放在
devDependencies
下 --save
指將報信息添加到package.json
的dependencies
屬性下,表示發佈時依賴的包。- 像 React、Vue、Angular、jQuery 等,代碼編譯打包後仍需要依賴的庫(框架)放在
dependencies
下
另外,如不特別指定即 npm install
,包信息會默認添加到 dependencies
下
總結
程序雖然很簡單,不過對於初學者來說獨自來擼還是會碰到問題的,麻雀雖小五臟俱全。