1. 程式人生 > >搭建 webpack、react 開發環境(一)

搭建 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 開發環境(二) 來繼續檢視。