Skip to main content Skip to docs navigation

BootstrapとWebpack Bootstrap and Webpack

Webpackを使用してプロジェクトにBootstrapのCSSとJavaScriptを含めてバンドルする方法の公式ガイド。

最後までスキップしたいですか? このガイドのソースコードと動作デモをtwbs/examplesリポジトリからダウンロードできます。また、ライブ編集用にStackBlitzで例を開くこともできます。

Webpackとは?

Webpackは、モジュールとその依存関係を処理して静的アセットを生成するJavaScriptモジュールバンドラーです。複数のファイルと依存関係を持つ複雑なWebアプリケーションの管理を簡素化します。

セットアップ

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をインストールします。さらに、デフォルトのdistディレクトリの代わりにsrcディレクトリにindex.htmlを保存できるように、html-webpack-pluginをインストールします。--save-devを使用して、これらの依存関係が開発用のみであり、本番用ではないことを示します。

    npm i --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin
    
  3. Bootstrapをインストールします。 これでBootstrapをインストールできます。ドロップダウン、ポップオーバー、ツールチップは配置のためにPopperに依存しているため、Popperもインストールします。これらのコンポーネントを使用する予定がない場合は、ここでPopperを省略できます。

    npm i --save bootstrap @popperjs/core
    
  4. 追加の依存関係をインストールします。 WebpackとBootstrapに加えて、WebpackでBootstrapのCSSとJSを適切にインポートおよびバンドルするために、さらにいくつかの依存関係が必要です。これには、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.config.jsにまだ記入していないため、Webpackは機能しません。

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に記入します。 これは、後のステップで追加するバンドルされたCSSとJSを利用するためにWebpackがブラウザーで読み込むHTMLページです。その前に、レンダリングするものを与え、前のステップの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スタイリングを少し含めているため、BootstrapのCSSがWebpackによって読み込まれたときにわかります。

  3. 次に、Webpackを実行するためのnpmスクリプトが必要です。 package.jsonを開き、以下に示すstartスクリプトを追加します(すでにtestスクリプトがあるはずです)。このスクリプトを使用して、ローカル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',
                options: {
                  sassOptions: {
                    // Optional: Silence Sass deprecation warnings. See note below.
                    silenceDeprecations: [
                      'mixed-decls',
                      'color-functions',
                      'global-builtin',
                      'import'
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    }
    

    これらのローダーがすべて必要な理由を要約します。style-loaderは、HTMLページの<head>内の<style>要素にCSSを挿入します。css-loader@importurl()の使用を支援します。postcss-loaderはAutoprefixerに必要です。sass-loaderはSassを使用できるようにします。

    注: Sassの非推奨警告は、最新バージョンのDart SassでソースSassファイルをコンパイルするときに表示されます。これはBootstrapのコンパイルや使用を妨げるものではありません。長期的な修正に取り組んでいますが、その間、これらの非推奨通知は無視できます。

  2. 次に、BootstrapのCSSをインポートしましょう。 BootstrapのソースSassをすべてインポートするには、src/scss/styles.scssに以下を追加します。

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

    必要に応じて、スタイルシートを個別にインポートすることもできます。詳細については、Sassインポートドキュメントをお読みください

  3. 次に、CSSを読み込み、BootstrapのJavaScriptをインポートします。 CSSを読み込み、BootstrapのすべてのJSをインポートするには、src/js/main.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'
    

    Bootstrapのプラグインの使用方法の詳細については、JavaScriptドキュメントをお読みください

  4. これで完了です! BootstrapのソースSassとJSが完全に読み込まれたので、ローカル開発サーバーは次のようになります:

    Webpack dev server running with Bootstrap

    これで、使用したいBootstrapコンポーネントの追加を開始できます。追加のカスタムSassを含める方法と、必要なBootstrapのCSSとJSの部分のみをインポートしてビルドを最適化する方法については、完全なWebpack例プロジェクトを確認してください

本番最適化

セットアップによっては、本番環境でプロジェクトを実行するために役立ついくつかの追加のセキュリティと速度の最適化を実装することができます。これらの最適化はWebpack例プロジェクトには適用されておらず、実装はあなた次第であることに注意してください。

CSSの抽出

上記で設定したstyle-loaderは、CSSをバンドルに便利に出力するため、dist/index.htmlでCSSファイルを手動で読み込む必要がありません。ただし、このアプローチは厳格なコンテンツセキュリティポリシーでは機能しない場合があり、バンドルサイズが大きいためにアプリケーションのボトルネックになる可能性があります。

dist/index.htmlから直接読み込めるようにCSSを分離するには、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には、インラインdata: URIを介したSVGファイルへの複数の参照が含まれています。画像のdata: URIをブロックするコンテンツセキュリティポリシーをプロジェクトに定義すると、これらのSVGファイルは読み込まれません。Webpackのアセットモジュール機能を使用してインラインSVGファイルを抽出することで、この問題を回避できます。

次のように、インラインSVGファイルを抽出するようにWebpackを設定します:

--- 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から適切に参照されていることがわかります。


See something wrong or out of date here? Please open an issue on GitHub. Need help troubleshooting? Search or start a discussion on GitHub.