搭建 webpack、react 開發環境(一)
基本介紹
Webpack 是一個前端資源載入/打包工具。它將根據模組的依賴關係進行靜態分析,然後將這些模組按照指定的規則生成對應的靜態資源,它可以將多種靜態資源 JavaScript、css、less 等轉換成一個靜態檔案,減少了頁面的請求。
React 起源於 Facebook 的內部專案,用來架設 Instagram 的網站,它是一個用於構建使用者介面的 JAVASCRIPT 庫,主要用於構建UI,很多人認為 React 是 MVC 中的 V(檢視)。由於擁有較高的效能,程式碼邏輯非常簡單,所以在全球範圍內的使用率都比較高。
這一次為了更好的學習 webpack 環境的構建和開始 React 的開發,工程搭建將會以實現一個 todolist 為目標,將每一個節點作為一個 commit,以便更直觀的檢視實現一個功能點所需要做的事情,同時也使得選擇所需的依賴變得更簡單可行。
你可以點選 show me the code 來檢視和 Fork 此專案,如果你需要檢視更多關於 Angular或Vue 開發環境的搭建可以點選 檢視更多 來進行檢視,歡迎大家一起學習和交流。
安裝配置 webpack 基礎
- 首先新建工程目錄,這裡我們給專案名稱取名為 webpack-react,對其進行建立並進入該目錄:
$ mkdir webpack-react && cd webpack-react
然後進行初始化生成 package.json 檔案(其中記錄定義了這個專案所需要的各種模組,以及專案的配置資訊,比如比如名稱、版本、許可證等元資料):$ yarn init
根據提示我們可以設定相關資訊,或者一路預設(回車)即可,當然如果你只要生成預設的,我們可以在執行初始化時命令時加上一個引數:$ yarn init -y
即可。 - 然後安裝 webpack,由於我們使用的是 webpack4+ 的版本,所以我們還需要安裝 CLI:
$ yarn add webpack webpack-cli --dev
當我們使用 yarn add 時,不僅會安裝對應的包,並會將包的資訊寫進 yarn.lock 檔案,從事該專案的其他開發人員在執行 yarn或yarn install 時將獲得與您相同的依賴項。在 webpack 4 不是必須要有配置檔案的,所以此時如果我們在 index.js 中新增內容直接執行 webpack 就可以進行打包,因為在 webpack 4 中預設入口檔案為 ./src/index.js,默認出口檔案為 ./dist/main.js。
安裝完成之後我們來對 webpack 進行簡單的配置,首先我們在 package.json 同級目錄下建立 config 目錄用於放置部分配置檔案,現在我們在 config 目錄下新建 webpack.base.config.js 檔案,用來存放開發模式和生產模式公共的配置檔案,建立 webpack.dev.config.js 檔案,用來存放開發模式下的配置檔案,建立 webpack.build.config.js 檔案,用來存放生產模式下的配置檔案:
$ mkdir config $ cd config $ touch webpack.base.config.js webpack.dev.config.js webpack.build.config.js
現在我們先向共同的配置檔案 webpack.base.config.js 中寫入以下內容:
const path = require('path'); module.exports = { // 入口配置 entry: { main: path.join(__dirname, '../src/index.js'), }, // 輸出配置 output: { filename: 'js/[name].js', // 輸出檔案的檔名 path: path.join(__dirname, '../dist'), // 輸出檔案所在目錄 } };
如配置中所示,現在我們去對應的目錄下建立對應的入口檔案 index.js,並在其中輸出“Hello world”:
// index.js console.log('打包成功');
- 剛剛我們建立三個配置檔案,為了將兩個模式下的配置檔案與公共配置檔案結合起來,我們需要安裝和使用 webpack-merge 來進行合併:
$ yarn add webpack-merge --dev
這裡我們先對開發模式下的配置檔案進行配置:
// 引入公共配置 const webpackBaseConfig = require('./webpack.base.config'); // 合併配置的外掛 const webpackMerge = require('webpack-merge'); module.exports = webpackMerge(webpackBaseConfig, { // 指定模式 mode: 'development', // devtool由 webpack 直接提供,將打包後的檔案中的錯誤對映到最初對應的檔案中,便於除錯 devtool: 'cheap-module-eval-source-map' });
順便我們也把生產模式下也簡單的配置一下,有時候我們也可以打包一下,檢視打包後文件存放的名稱和路徑等,以檢測書寫錯誤導致一些錯誤,當然現在我們只需要對其進行簡單的配置:
// 引入公共配置 const webpackBaseConfig = require('./webpack.base.config'); // 合併配置的外掛 const webpackMerge = require('webpack-merge'); module.exports = webpackMerge(webpackBaseConfig, { // 指定模式 mode: 'production' });
- 使用 webpack-dev-server 構建本地伺服器:webpack-dev-server 提供了一個簡單的 web 伺服器,並且能夠實時重新載入。它的使用也比較簡單,首先我們對其進行安裝:
$ yarn add webpack-dev-server --dev
由於它直接開發模式下會被用到,所以我們直接去開發模式的配置檔案(webpack.dev.config.js)下進行配置:
const path = require('path'); // 引入公共配置 const webpackBaseConfig = require('./webpack.base.config'); // 合併配置的外掛 const webpackMerge = require('webpack-merge'); module.exports = webpackMerge(webpackBaseConfig, { // 指定模式 mode: 'development', // devtool由 webpack 直接提供,將打包後的檔案中的錯誤對映到最初對應的檔案中,便於除錯 devtool: 'cheap-module-eval-source-map', // 對 webpack-dev-server 進行配置 devServer: { //本地伺服器所載入的頁面所在的目錄 contentBase: path.join(__dirname, "../dist"), /* 伺服器的主機號,預設是 localhost * 將該地址設為電腦的 ip 地址,區域網內的移動裝置通過訪問該地址下的30埠即可訪問 web 應用 */ host: 'localhost', // 埠 port: 3000, /* 設定編譯後文件的路徑,導致最後的檔案檔案地址為:http://localhost:3000/dist/index.js * * publicPath: 'http://localhost:3000/', */ /* 應對返回404頁面時定向到特定頁面 * * historyApiFallback: { * rewrites: [{ * from: /./, * to: '/404.html' * }] * }, */ // 熱模組替換機制 //- hot: true, /* 預設為 true, 意思是,在打包時會注入一段程式碼到最後的 js 檔案中,用來監視頁面的改動而自動重新整理頁面 * 當為 false 時,網頁自動重新整理的模式是 iframe,也就是將模板頁放在一個 frame中 * * inline: true, */ // 為 true 時,dev server 第一次會自動開啟瀏覽器 open: true, /* 對所有的伺服器資源採用 gzip 壓縮 * 對 JS,CSS 資源的壓縮率很高,可以極大得提高檔案傳輸的速率 * 但是需要服務端要對檔案進行壓縮,客戶端進行解壓,增加了兩邊的負載 * * compress: true */ disableHostCheck: true } });
- 因為我們構建的是一個 web 應用,所以我們還需要對 .html 檔案編譯的支援,這樣也可以更直觀的看清我們 webpack 工作的情況,為此我們需要安裝 html-webpack-plugin 以及 html-loader 載入器:
$ yarn add html-webpack-plugin html-loader --dev
因為該配置在兩種模式下都需要使用,所以我們在公共配置檔案中進行配置:
const path = require('path'); const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = { // 入口配置 entry: { main: path.join(__dirname, '../src/index.js'), }, // 輸出配置 output: { filename: 'js/[name].js', // 輸出檔案的檔名 path: path.join(__dirname, '../dist'), // 輸出檔案所在目錄 }, // 載入器 module: { rules: [{ test: /\.html$/, use: [{ loader: "html-loader", options: { minimize: true } }] }] }, // 外掛管理 plugins: [ //建立 .html 並自動引入打包後的檔案 new HTMLWebpackPlugin({ filename: 'index.html', template: 'index.html', // 參照最初建立的 .html 來生成 .html inject: true, // 引入根路徑下的 favicon.ico favicon: path.resolve('favicon.ico') }) ] };
當然我們在這裡還需要在對應的目錄下建立 index.html,也就是在根目錄下:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>webpack-react</title> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="root">Hello world</div> </body> </html>
- 在安裝和配置完上面的基本資訊之後,最後我們需要來使用上面做的一切準備,首先我們需要設定 NPM 指令碼(NPM Scripts)。開啟我們最初初始化專案時生成的 package.json 檔案,在對應的 script 欄位下進行配置:
"scripts": { "dev": "webpack-dev-server --config config/webpack.dev.config.js", "build": "webpack --config config/webpack.prod.config.js" }
Npm 中允許在 package.json 檔案裡面,使用 scripts 欄位定義指令碼命令。它是一個物件,它的每一個屬性,都對應一段指令碼。
每當執行 npm run,就會自動新建一個 Shell,在這個 Shell 裡面執行指定的指令碼命令,新建的這個 Shell,會將當前目錄的 node_modules/.bin 子目錄加入 PATH 變數,執行結束後,再將 PATH變數恢復原樣,所以當前目錄的 node_modules/.bin 子目錄裡面的所有指令碼,都可以直接用指令碼名呼叫,而不必加上路徑。
因為我們的配置檔案不在根目錄下,在這裡我們通過 --config 來指定執行指令碼路徑,現在我們就可以使用 npm run dev 開啟 web 應用,如果前面的操作正確的化你將看到頁面上顯示“Hello world”的字樣,並且控制檯中輸入“編譯成功”的字樣。
配置支援 ES6、JSX
如今在前端開發中 Javascript 主要是用 ES6 編寫的,但並不是所有的瀏覽器都知道如何處理 ES6,因此我們需對 ES6 進行轉換。
在 webpack 的 loader(載入器)中,babel-loader 正是這樣一個用於將 ES6 及以上版本轉譯至 ES5 的神器,要使用它我們還需要安裝一些依賴:
$ yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react --dev
然後需要在公共配置檔案中 rules 屬性配置 babel-loader 的相關資訊:
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
最後我們需要在根目錄下建立 .babelrc 檔案寫入以下內容:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
現在我們就可以在專案中使用 ES6或著是JSX 語法啦。
配置支援 React、React-dom
首先我們將根目錄下 index.html 檔案中的 "Hello world"文字刪掉,然後在 ./src/index.js 檔案中寫入下面的內容:
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
return (
<div>
<p>Hello world</p>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
顯然儲存後執行服務會報錯,因為到目前位置我們的專案還不支援 React、React-dom,為了進行 React 開發,首先我們要安裝如下依賴:
$ yarn add react react-dom
安裝完成之後,再啟動專案,會發現剛剛刪除的 "Hello world"文字再次出現了,而且是通過 React 來實現的,到此 webpack-react 最基礎的開發環境就搭建好了,但是 webpack 方面還有許多配置和一些需要優化的地方,所以我們將在下篇文章裡繼續記錄開發環境的搭建過程,你可以點選 搭建 webpack、react 開發環境(二) 來繼續檢視。