iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

Three.js 學習日誌系列 第 22

Day21 - 使用Webpack 5打造Three.js的Boilerplate(二)

  • 分享至 

  • xImage
  •  

Day21 - 使用Webpack 5打造Three.js的Boilerplate(二)

這裡是「Three.js學習日誌」的第21篇,這篇的內容是要講解Webpack的操作與Webpack config的編寫方法。這系列的文章假設讀者看得懂javascript,並且有Canvas 2D Context的相關知識。

3. Webpack的基本用法

首先我們要知道幾件事:

  1. Webpack必須要在有安裝Node.js的環境下執行
  2. Webpack本身需要透過CLI介面來執行,CLI必須要被全域安裝,或者是以devdependency的形式安裝在node_modules
  3. WebpackCLI會根據專案裡面的webpack.config.js這個文件,來決定要怎麼打包專案
  4. 我們必須手動建立並編寫webpack.config.js這個檔案

其實絕大多數網路上關於Webpack的問題討論,基本都是在討論webpack.config.js的寫法。

所以我們接下來要簡單介紹一下怎麼樣寫一份webpack.config.js

3-1 webpack.config.js的基本架構


想要學習怎麼編寫webpack.config.js

第一步就是要先記下EOMMP這五個英文字。


  • E就是我們剛剛提到的Entry

  • O代表Output,意思是打包出來的檔案要輸出到哪裡。

  • 第一個M代表Mode,意思是當前我們是在哪一種模式底下做打包。

  • 第二個M就是我們剛剛提到的Module

  • P則代表Plugin,意思是插件

下面這是一個常見的webpack.config.js檔案,內容看起來的樣子。

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  //這邊是E
  entry: { 
    main:['./src/js/index.js','./src/scss/index.scss'] 
  }, 
  // 這邊是O
  output: {
    filename: 'js/[name].[chunkhash].js', //輸出的檔案名稱格式
    path: resolve(__dirname, 'build'),
  },
   // 這邊是M(1)
  mode: 'development', // 值可以是'development'或是'production'
   // 這邊是M(2)
  module: {
    rules: [
      //...
    ]
  },
  // 這邊是P
  plugins: [
    new HtmlWebpackPlugin({
     template: './index.html'
    })
  ]
}

3-2 webpack.config.js的各屬性解釋

這邊請容我再解釋一下幾個關於上面這段webpack.config.js的細節。

3-2-a. entry屬性的解釋

webpack 官方文件: 點我

entry可以填入專案中用用到的entry files

我們會把多個entry files構成的集合體稱為Chunk

這邊的main:['./src/js/index.js','./src/scss/index.scss'] 換句話說就是:

「我們在這個專案中有個叫做mainchunk,它是由index.jsindex.scss所構成。

3-2-b. output屬性的解釋

webpack 官方文件: 點我

我們可以在上面的output欄位中看到path: resolve(__dirname, 'build')這樣的寫法。

這一段的resolve__dirname其實是node.js提供的方法還有變數。

resolve的用途是將一系列路徑路徑段解析為絕對路徑(詳細請見文件)。

__dirname則是代表webpack.config.js所位於的資料夾名稱(詳細請見文件)。

3-2-c. mode屬性的解釋

webpack 官方文件: 點我

mode表示我們當前是在哪一種模式底下做打包。

基本上可以選擇為,development(開發模式) 或 production(生產模式)。

不同的模式採用的打包方式會不同,產生的結果其細節也會不一樣。

例如我們可以選擇只在生產模式下對打包的檔案進行極小化,以減少檔案容量。

3-2-d. module.rules 的解釋

webpack 官方文件: 點我

這個部分主要是去定義當webpack偵測到資源的時候,要怎麼去載入編譯這個資源。

例如假設我們如果要載入.SCSS資源。最簡單的方式就是像下面這樣設置:

module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      },
    ]
},

我們可以注意到這邊的use使用了三個Loader,分別是style-loadercss-loadersass-loader。 但實際上這三個Loader的執行順序並不是由上往下,而是由下往上。意思也就是說當webpack偵測到SCSS資源的時候:

  • sass-loader會去把SCSS轉譯為CSS
  • CSS-loader會去偵測CSS內部的url()@import轉換成require(),目的是為了讓js可以認知到CSS內部有使用其他資源。
  • style-loader則是把CSS插入DOM

上面的寫法只是一個範例,實際上我們會因為需要應對專案的各種需求去決定module.rules的寫法,而不同類型的資源往往也會有不同的Loader需要使用。(而且就算同樣是要載入SCSS資源,不同的專案需求下可能也出現好幾種寫法)

通常Loader會是由webpack社群的使用者一起協力開發,不過像這樣的開源插件常常有的毛病就是:更新可能不及時(或是作者人間蒸發),所以通常要選用 Loader插件的時候,都要盡量觀察插件NPM頁面/Github Repo的更新狀況和健康程度,要升級版本時也最好都要先確認過Patch note。

3-2-e. plugin屬性的解釋

webpack 官方文件: 點我

老實說plugin這個屬性並沒有一個一定的解釋。

這個欄位就是用來讓我們導入一些插件,這些插件會在webpack建構打包內容的時候造成影響。

這邊我們可以介紹幾個常用的插件:

  • webpack.DefinePlugin: 這是一個webpack官方內建的插件,我們可以用它來定義在不同的mode時,產生不同的值作為環境變數。

  • MiniCssExtractPlugin: 這是一個可以用來把module.rules中偵測到的CSS字串資源抽取出來成為獨立的CSS檔案。

  • CopyPlugin : 這是一個可以把指定資料夾裡面的內容,複製到另外一個資料夾的插件,通常會使用這個插件,大多是因為有些檔案需要在不被轉譯的情況下使用,所以必須要繞過module.rules>Loader的階段,直接把檔案複製到output的路徑上。

  • HtmlWebpackPlugin: 這個插件可以透過傳入Entry Chunk的名稱,還有一個html模板的路徑,來把Entry Chunk的內容跟該html模板合併輸出一個html檔案。(意思就是可以把Entry Chunk裡面的jscss塞到目標的html裡面,變成一個有導入樣式表和JS的html檔)。

除了上述這些以外當然還有很多其他的Plugin,狀況跟Loader一樣。

4. 筆者自行開發的模板「webpack-template」,其使用方法介紹

老實說 ~ 筆者其實沒有打算一步一步的去講解到底怎麼樣去寫好一個webpack模板。

這邊可能讓大家失望了QQ

但畢竟競賽的主題不是webpack,而是Three.js,而且如果真的要講完「webpack-template」的開發過程,我預估大概也要講到賽程結束...

因此關於webpack操作的細節,我只打算點到上面為止。

如果真的對如何建立自己的webpack模板有興趣,我很推薦你去看看這系列的影片

但是由於在接下來幾天中,筆者小弟我都會使用我自己開發的webpack模板:「webpack-template」來進行範例的實作。所以我打算在這邊講解一下我所開發的「webpack-template」的使用方法,還有一部分的機制與原理。

4-1 首先當然是下載/安裝的方法

Github Repository: https://github.com/mizok/webpack-template


  1. 請先登入Github後移步至上述的Repository地址,然後點擊畫面中的綠色"Use this template"按鈕

img

  1. 接下來就會進入建立Repository的頁面,Github將會直接使用筆者開發的webpack-template作為模板來在您的帳號名下建立一個Repository

img

  1. 建立好Repository後就可以git clone下來。

git操作的部分如果不熟悉,可以看看這邊

4-2「webpack-template」介紹

這個模板主要使用的技術/語言有:

  • webpack5 (作為主打包程序)
  • typescript
  • scss
  • ejs (作為主樣板語言)

Github Repo上面,您其實可以隨時檢閱英文的Readme文件,而若有問題,也歡迎隨時發布ISSUE或投遞PR ~


4-2-a 基本NPM Script

  • npm run build : 會呼叫webpackCLI工具執行專案打包
  • npm run dev : 會使用內置的webpack-dev-server來模擬專案的Hosting,用途類似VScode Live Server
  • npm run deploy : 會使用gh-pages這個插件把專案打包後部署到Github Page

4-2-b 打包/編譯流程圖

img

4-2-c 重點機制:「由檔案名生成Entry Chunks/HtmlWebpackPlugin Instance」

在「webpack-template」中,當使用者按下Enter送出npm run build指令後,首先會先在webpack.config.ts裡面碰到一層判斷。

這層判斷會去根據當前每個./src/pages/底下的EJS檔案的命名方式,來決定要生成哪些Entry Chunks

例如:

  • index.ejs 會使程序判斷必須要生成一個被命名為indexEntry Chunks
  • index.main.ejs 會使程序判斷必須要生成一個被命名為mainEntry Chunks

而當如果專案備程序判定將生成了一個名為"xx"的Entry Chunks時,我們就必須要在:

  • ./src/ts 底下補上一個名為xx.ts的檔案(作為ts entry)
  • ./src/scss 底下補上一個名為xx.scss的檔案(作為scss entry)

4-2-d 靜態檔案的堆放處: ./static資料夾

我們之前提到的CopyPlugin,會把在./src/static資料夾底下的所有檔案,一併複製到./dist/static

通常我們會把一些.pdf或是.obj.mtl.gltf等外部3D模型檔案堆放在這個資料夾,以避免它們被Loader 加載到。

其他像是有關於EJS的寫作方法、環境變數的取用之類的Tips,都可以在Repo的README進行查閱~ 這邊就不多做說明。

小結

對於webpack/「webpack-template」的介紹就差不多在這先打住。
明天我們將著手從一個空白的「webpack-template」模板來改造成為我們在接下來的天數會使用到的Three.js Boilerplate !

延伸資源


上一篇
Day20 - 使用Webpack 5打造Three.js的Boilerplate(一)
下一篇
Day22 - 使用Webpack 5打造Three.js的Boilerplate(三)
系列文
Three.js 學習日誌31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言