跳到主要內容 跳到文件導覽

Bootstrap 和 Webpack

使用 Webpack 在專案中包含並組合 Bootstrap 的 CSS 和 JavaScript 的官方指南。

想跳到最後嗎?twbs/examples 儲存庫 下載本指南的原始碼和工作示範。您也可以 在 StackBlitz 中開啟範例 以進行線上編輯。

設定

我們將從頭開始使用 Bootstrap 建立一個 Webpack 專案,因此在我們真正開始之前,有一些先決條件和前期步驟。本指南要求您已安裝 Node.js 並且熟悉終端機。

  1. 建立專案資料夾並設定 npm。我們將建立 my-project 資料夾,並使用 -y 參數初始化 npm,以避免它詢問我們所有互動式問題。

    mkdir my-project && cd my-project
    npm init -y
    
  2. 安裝 Webpack。接下來,我們需要安裝我們的 Webpack 開發相依項:Webpack 的核心 webpack、讓我們可以從終端機執行 Webpack 指令的 webpack-cli,以及讓我們可以執行本機開發伺服器的 webpack-dev-server。此外,我們將安裝 html-webpack-plugin,以便能夠將我們的 index.html 儲存在 src 目錄中,而不是預設的 dist 目錄。我們使用 --save-dev 來表示這些相依項僅供開發使用,不供實際應用。

    npm i --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin
    
  3. 安裝 Bootstrap。現在,我們可以安裝 Bootstrap。由於我們的下拉式選單、彈出視窗和工具提示依賴它進行定位,我們也會安裝 Popper。如果您不打算使用這些元件,您可以在這裡略過 Popper。

    npm i --save bootstrap @popperjs/core
    
  4. 安裝其他相依項。除了 Webpack 和 Bootstrap 之外,我們還需要更多相依項才能正確匯入和套件化 Bootstrap 的 CSS 和 JS 與 Webpack。其中包括 Sass、一些載入器和 Autoprefixer。

    npm i --save-dev autoprefixer css-loader postcss-loader sass sass-loader style-loader
    

現在我們已經安裝所有必要的相依項,我們可以開始建立專案檔案和匯入 Bootstrap。

專案結構

我們已經建立了 my-project 資料夾並初始化 npm。現在我們還要建立 srcdist 資料夾來完善專案結構。從 my-project 執行下列指令,或手動建立下方顯示的資料夾和檔案結構。

mkdir {src,src/js,src/scss}
touch src/index.html src/js/main.js src/scss/styles.scss webpack.config.js

完成後,完整的專案應如下所示

my-project/
├── src/
│   ├── js/
│   │   └── main.js
│   ├── scss/
│   │   └── styles.scss
│   └── index.html
├── package-lock.json
├── package.json
└── webpack.config.js

此時,所有內容都已放置在正確的位置,但 Webpack 無法運作,因為我們尚未填寫 webpack.config.js

設定 Webpack

在安裝相依項且專案資料夾已準備好讓我們開始編寫程式碼後,我們現在可以設定 Webpack 並在本地端執行專案。

  1. 在編輯器中開啟 webpack.config.js由於它是空白的,我們需要新增一些樣板設定檔,以便我們可以啟動伺服器。設定檔的這部分會告訴 Webpack 到哪裡尋找專案的 JavaScript,將編譯後的程式碼輸出到何處 (dist),以及開發伺服器應如何運作 (從 dist 資料夾中提取並進行熱更新)。

    'use strict'
    
    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      mode: 'development',
      entry: './src/js/main.js',
      output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
      },
      devServer: {
        static: path.resolve(__dirname, 'dist'),
        port: 8080,
        hot: true
      },
      plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' })
      ]
    }
    
  2. 接著我們填寫 src/index.html這是 Webpack 會在瀏覽器中載入的 HTML 頁面,以利用我們稍後步驟中會新增的 CSS 和 JS 程式碼。在我們執行此動作之前,我們必須提供一些內容讓它呈現,並包含前一步驟的 output JS。

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Bootstrap w/ Webpack</title>
      </head>
      <body>
        <div class="container py-4 px-3 mx-auto">
          <h1>Hello, Bootstrap and Webpack!</h1>
          <button class="btn btn-primary">Primary button</button>
        </div>
      </body>
    </html>
    

    我們在此使用 div class="container"<button> 包含一些 Bootstrap 造型,以便我們看到 Webpack 載入 Bootstrap 的 CSS 時的情況。

  3. 現在我們需要一個 npm 指令碼來執行 Webpack。開啟 package.json 並新增下方顯示的 start 指令碼 (你應該已經有測試指令碼)。我們將使用此指令碼來啟動本地的 Webpack 開發伺服器。你也可以新增下方顯示的 build 指令碼來建置專案。

    {
      // ...
      "scripts": {
        "start": "webpack serve",
        "build": "webpack build --mode=production",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      // ...
    }
    
  4. 最後,我們可以啟動 Webpack。從終端機中的 my-project 資料夾執行新增加的 npm 指令碼

    npm start
    
    Webpack dev server running

在本指南的下一部分和最後一部分中,我們將設定 Webpack 載入器並匯入所有 Bootstrap 的 CSS 和 JavaScript。

匯入 Bootstrap

將 Bootstrap 匯入 Webpack 需要在第一個區段安裝的載入器。我們已使用 npm 安裝它們,但現在需要設定 Webpack 以使用它們。

  1. webpack.config.js 中設定載入器。您的設定檔現在已完成,且應符合以下程式碼片段。此處唯一的新區段是 module 區段。

    'use strict'
    
    const path = require('path')
    const autoprefixer = require('autoprefixer')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      mode: 'development',
      entry: './src/js/main.js',
      output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
      },
      devServer: {
        static: path.resolve(__dirname, 'dist'),
        port: 8080,
        hot: true
      },
      plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' })
      ],
      module: {
        rules: [
          {
            test: /\.(scss)$/,
            use: [
              {
                // Adds CSS to the DOM by injecting a `<style>` tag
                loader: 'style-loader'
              },
              {
                // Interprets `@import` and `url()` like `import/require()` and will resolve them
                loader: 'css-loader'
              },
              {
                // Loader for webpack to process CSS with PostCSS
                loader: 'postcss-loader',
                options: {
                  postcssOptions: {
                    plugins: [
                      autoprefixer
                    ]
                  }
                }
              },
              {
                // Loads a SASS/SCSS file and compiles it to CSS
                loader: 'sass-loader'
              }
            ]
          }
        ]
      }
    }
    

    以下是我們需要所有這些載入器的簡述。style-loader 將 CSS 注入 HTML 頁面 <head> 中的 <style> 元素,css-loader 可協助使用 @importurl()postcss-loader 是 Autoprefixer 所需,而 sass-loader 允許我們使用 Sass。

  2. 現在,我們來匯入 Bootstrap 的 CSS。將下列內容新增至 src/scss/styles.scss 以匯入所有 Bootstrap 的 Sass 原始碼。

    // Import all of Bootstrap's CSS
    @import "bootstrap/scss/bootstrap";
    

    如果您需要,也可以個別匯入我們的樣式表。請閱讀我們的 Sass 匯入文件以取得詳細資訊。

  3. 接下來我們載入 CSS 並匯入 Bootstrap 的 JavaScript。將下列內容新增至 src/js/main.js 以載入 CSS 並匯入所有 Bootstrap 的 JS。Popper 會透過 Bootstrap 自動匯入。

    // Import our custom CSS
    import '../scss/styles.scss'
    
    // Import all of Bootstrap's JS
    import * as bootstrap from 'bootstrap'
    

    您也可以個別匯入 JavaScript 外掛程式,以降低套件大小

    import Alert from 'bootstrap/js/dist/alert'
    
    // or, specify which plugins you need:
    import { Tooltip, Toast, Popover } from 'bootstrap'
    

    閱讀我們的 JavaScript 文件以取得有關如何使用 Bootstrap 外掛程式的更多資訊。

  4. 大功告成!🎉在 Bootstrap 的 Sass 和 JS 原始碼完全載入後,您的本機開發伺服器現在應如下所示

    Webpack dev server running with Bootstrap

    現在您可以開始新增任何您要使用的 Bootstrap 元件。請務必查看完整的 Webpack 範例專案,了解如何包含其他自訂 Sass 並僅匯入您需要的 Bootstrap CSS 和 JS 部分,以最佳化您的建置。

生產最佳化

根據您的設定,您可能想要實作一些額外的安全性與速度最佳化,這對於在生產環境中執行專案很有用。請注意,這些最佳化並未套用於 Webpack 範例專案,而由您自行實作。

萃取 CSS

我們在上面設定的 style-loader 會將 CSS 方便地發射到套件中,因此不需要在 dist/index.html 中手動載入 CSS 檔案。不過,這種方法可能無法搭配嚴格的內容安全性政策,而且由於套件大小龐大,可能會成為應用程式的瓶頸。

若要將 CSS 分開,以便我們可以直接從 dist/index.html 載入它,請使用 mini-css-extract-loader Webpack 外掛程式。

首先,安裝外掛程式

npm install --save-dev mini-css-extract-plugin

然後在 Webpack 設定中實例化並使用外掛程式

--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,6 +3,7 @@
 const path = require('path')
 const autoprefixer = require('autoprefixer')
 const HtmlWebpackPlugin = require('html-webpack-plugin')
+const miniCssExtractPlugin = require('mini-css-extract-plugin')

 module.exports = {
   mode: 'development',
@@ -17,7 +18,8 @@ module.exports = {
     hot: true
   },
   plugins: [
-    new HtmlWebpackPlugin({ template: './src/index.html' })
+    new HtmlWebpackPlugin({ template: './src/index.html' }),
+    new miniCssExtractPlugin()
   ],
   module: {
     rules: [
@@ -25,8 +27,8 @@ module.exports = {
         test: /\.(scss)$/,
         use: [
           {
-            // Adds CSS to the DOM by injecting a `<style>` tag
-            loader: 'style-loader'
+            // Extracts CSS for each JS file that includes CSS
+            loader: miniCssExtractPlugin.loader
           },
           {

再次執行 npm run build 之後,將會有一個新的檔案 dist/main.css,其中包含 src/js/main.js 匯入的所有 CSS。如果您現在在瀏覽器中檢視 dist/index.html,樣式將會遺失,因為它現在位於 dist/main.css 中。您可以像這樣將產生的 CSS 包含在 dist/index.html

--- a/dist/index.html
+++ b/dist/index.html
@@ -3,6 +3,7 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="./main.css">
     <title>Bootstrap w/ Webpack</title>
   </head>
   <body>

萃取 SVG 檔案

Bootstrap 的 CSS 包含多個對 SVG 檔案的參考,透過內嵌的 data: URI。如果您為專案定義的內容安全性政策會封鎖影像的 data: URI,則這些 SVG 檔案將不會載入。您可以透過使用 Webpack 的資產模組功能萃取內嵌的 SVG 檔案來解決這個問題。

設定 Webpack 以萃取內嵌的 SVG 檔案,如下所示

--- a/webpack.config.js
+++ b/webpack.config.js
@@ -23,6 +23,14 @@ module.exports = {
   },
   module: {
     rules: [
+      {
+        mimetype: 'image/svg+xml',
+        scheme: 'data',
+        type: 'asset/resource',
+        generator: {
+          filename: 'icons/[hash].svg'
+        }
+      },
       {
         test: /\.(scss)$/,
         use: [

再次執行 npm run build 之後,您會發現 SVG 檔案已萃取到 dist/icons 中,並從 CSS 中正確地參考。


在此看到錯誤或過時內容嗎?請在 GitHub 上開啟一個問題。需要疑難排解的協助嗎?在 GitHub 上搜尋或開始討論