1. 程式人生 > >從零開始使用 webpack5 搭建 react 專案

從零開始使用 webpack5 搭建 react 專案

> 本文的示例專案原始碼可以點選 [這裡](https://github.com/jacob-lcs/react-webpack5-template) 獲取 ## 一、前言 webpack5 也已經發布一段時間了,其模組聯邦、bundle 快取等新特性值得在專案中進行使用。經過筆者在公司實際專案中的升級結果來看,其提升效果顯著,熱更新時間由原來的 8s 減少到了 2s,會極大的提升開發幸福感。除此之外,webpack5 也帶來了更好的 tree shaking 演算法,專案的打包體積也會進一步減少,提升使用者體驗。 目前來看,create-react-app 腳手架還沒有適配 webpack5,如果你想熟悉下如何從零開始配置 webpack5 專案的話,不妨跟著文件操作一下。 ## 二、專案初始化 ### 2.1 初始化檔案結構 首先建立一個資料夾,進行 npm 初始化 ```bash mkdir react-webpack5-template cd react-webpack5-template # npm 初始化配置 npm init -y # 建立 webpack 配置檔案 touch webpack.common.js # 建立 babel 配置檔案 mkdir src && cd src # 建立入口檔案 touch index.js cd .. && mkdir build touch index.html ``` 在上述步驟執行完畢之後,你的目錄結構應該如下所示: ``` ├── src │   └── index.js ├── build │   └── index.html ├── webpack.common.js ├── .babelrc ├── package.json ``` 隨後安裝必要的依賴 ```bash npm i webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader path -D npm i react react-dom ``` ### 2.2 完善配置檔案 檔案結構生成完畢後,我們開始編寫程式碼。首先,在`index.js` 中寫入以下程式碼: ```jsx import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( 你好,React-webpack5-template
, document.getElementById('root') ); ``` 在` webpack.common.js` 中寫入以下內容: ```js const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = (env) => { return { mode: "development", entry: { index: './src/index.js' }, output: { // 打包檔案根目錄 path: path.resolve(__dirname, "dist/"), }, plugins: [ // 生成 index.html new HtmlWebpackPlugin({ filename: "index.html", template: "./build/index.html", }), ], module: { rules: [ { test: /\.(jsx|js)?$/, use: ["babel-loader"], include: path.resolve(__dirname, 'src'), }, ] }, devServer: { port: 8080, host: '0.0.0.0', }, } } ``` 在 index.html 中寫入以下程式碼: ```html Title
``` 在 .babalrc 中寫入以下程式碼: ```json { "presets": ["@babel/preset-react"] } ``` 然後在 package.json 中新增如下 script: ```diff "scripts": { "test": "echo \"Error: no test specified\" && exit 1", + "dev": "webpack serve --config webpack.common.js" }, ``` 隨後我們執行 `npm run dev` 就可以直接運行了,由於我們上面設定的 devServer 埠號為 8080,所以在瀏覽器中開啟 `localhost:8080` 即可看到如下效果: ![image-20210228004846012](https://file.lcs.show/image/20210228004903.png) 到這裡位置,我們的初步搭建已經完成了,但是我們在現有的專案中看到的 webpack 配置檔案不止這些,有 less、css 檔案的解析,image 等資原始檔的處理,還有一些優化項的配置等,接下來會一一介紹。 ## 三、功能性配置 上面我們已經做到可以將一個簡單的 React 專案執行起來了,接下來我們要做的是加一些功能。 ### 3.1 樣式檔案解析 在前端專案開發過程中,比較經常使用的是 css、less、scss、sass、stylus,下面我們就先僅對 less 進行配置,其餘的樣式檔案可參考 GitHub 原始碼。首先安裝 loader: ```bash npm i style-loader less-loader less css-loader postcss-loader postcss-normalize autoprefixer postcss-preset-env -D ``` 首先,在 webpack.common.js 頂部加入以下正則表示式,用來判斷樣式檔案: ```js // less/less module 正則表示式 const lessRegex = /\.less$/; const lessModuleRegex = /\.module\.less$/; ``` 然後在 webpack.common.js 中加入以下配置: ```js module: { rules: [ { test: lessRegex, use: ["style-loader", "css-loader", "postcss-loader", "less-loader"], sideEffects: true, }, ] } ``` 新增 postcss.config.js 檔案並配置: ```js const postcssNormalize = require('postcss-normalize'); module.exports = { plugins: [ [ "postcss-preset-env", { autoprefixer: { flexbox: "no-2009", }, stage: 3, } ], postcssNormalize(), require('autoprefixer') ({ overrideBrowserslist: ['last 2 version', '>
1%', 'ios 7'] }) ], }; ``` 然後我們在 src 目錄下新建 index.less 檔案,測試配置是否成功: ```less // index.less .title { text-align: center; color: coral; } ``` 重新執行專案後發現樣式生效,配置成功。 ![image-20210228102928287](https://file.lcs.show/image/20210228102930.png) 但是僅配置 less 是不夠的,我們日常在開發過程中經常用到 less module,在這裡我們進行如下配置,首先安裝 `react-dev-utils`: ```bash npm i react-dev-utils resolve-url-loader -D ``` 在 webpack.common.js 中進行如下配置: ```diff const getCSSModuleLocalIdent = require("react-dev-utils/getCSSModuleLocalIdent"); module: { rules: [ { test: lessRegex, + exclude: lessModuleRegex, use: ["style-loader", "css-loader", "postcss-loader", "less-loader"], sideEffects: true, }, + { + test: lessModuleRegex, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + modules: { + getLocalIdent: getCSSModuleLocalIdent, + } + } + }, + "postcss-loader", + "less-loader" + ], + } ] } ``` 接下來我們新建 index.module.less 來進行測試: ```less .font { color: red; } ``` 重新執行專案後樣式生效,並且 className 也發生了相應變化: ![image-20210228110624352](https://file.lcs.show/image/20210228110626.png) CSS、SCSS 與 SASS 的配置都大同小異,大家可以移步到我的 [GitHub](https://github.com/jacob-lcs/react-webpack5-template)。 ### 3.2 圖片地址解析 > 資源模組(asset module)是一種模組型別,它允許使用資原始檔(字型,圖示等)而無需配置額外 loader。 > > 在 webpack 5 之前,通常使用: > > - [`raw-loader`](https://webpack.docschina.org/loaders/raw-loader/) 將檔案匯入為字串 > - [`url-loader`](https://webpack.docschina.org/loaders/url-loader/) 將檔案作為 data URI 內聯到 bundle 中 > - [`file-loader`](https://webpack.docschina.org/loaders/file-loader/) 將檔案傳送到輸出目錄 > > 資源模組型別(asset module type),通過新增 4 種新的模組型別,來替換所有這些 loader: > > - `asset/resource` 傳送一個單獨的檔案並匯出 URL。之前通過使用 `file-loader` 實現。 > - `asset/inline` 匯出一個資源的 data URI。之前通過使用 `url-loader` 實現。 > - `asset/source` 匯出資源的原始碼。之前通過使用 `raw-loader` 實現。 > - `asset` 在匯出一個 data URI 和傳送一個單獨的檔案之間自動選擇。之前通過使用 `url-loader`,並且配置資源體積限制實現。 > > —— 引自 webpack5 中文文件 webpack5 內建 assets 型別,我們不需要額外安裝外掛就可以進行圖片等資原始檔的解析,配置如下: ```javascript { test: /\.(jpe?g|png|gif|svg|woff|woff2|eot|ttf|otf)$/i, type: "asset/resource", }, ``` 如此我們便可以處理引入的圖片資原始檔,可以根據自身需要進行拓展。 ## 四、效能優化 ### 4. 1 引入快取 前面提到,webpack5 引入了快取來提高二次構建速度,我們只需要在 webpack 配置檔案中加入如下程式碼即可開心快取 ```js cache: { type: 'filesystem', // 可選配置 buildDependencies: { config: [__filename], // 當構建依賴的config檔案(通過 require 依賴)內容發生變化時,快取失效 }, name: 'development-cache', }, ``` 重新執行專案後會發現 node_modules 目錄下會新增一個 .cache 資料夾: ![image-20210228114440107](https://file.lcs.show/image/20210228114441.png) 筆者在實際專案中測試,熱更新時間由原來的 8s 縮短到 2s 可以說是提升巨大。 ## 五、總結 到目前為止,配置工作算是已經完成了,本篇文章只是指導大家進行一些初始化配置,專案中肯定還有很多可以優化的地方,比如說分別配置 webpack.dev.js 以及 webpack.prod.js 以通過測試環境與正式環境的不同需求,在這裡就不細說,環境區分的相關配置我會上傳到 GitHub 中,如果你覺得專案對你有點用處的話,還請點個