Bootstrap and Webpack
Webpackを使ってBootstrapのCSSとJavaScriptをプロジェクトに取り込み、バンドルする方法を解説した公式ガイドです。
設定
Bootstrapを使ったWebpackプロジェクトをゼロから構築するため、実際に始める前にいくつかの前提条件と前段階があります。このガイドでは、Node.jsをインストールし、ターミナルをある程度使いこなしている必要があります。
-
プロジェクトフォルダを作成し、npmを設定します。
my-project
を作成し、npmがすべての対話的な質問をしないように、-y
引数で初期化することにします。mkdir my-project && cd my-project npm init -y
-
Webpackをインストールします。 次に、Webpackの開発用依存ファイルをインストールする必要があります。: Webpackのコアとなる
webpack
、ターミナルからWebpackコマンドを実行するためのwebpack-cli
、ローカル開発サーバーを実行するためのwebpack-dev-server
です。この依存関係がプロダクションではなく開発専用であることを伝えるため--save-dev
を使います。npm i --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin
-
Bootstrapをインストールします。 これでBootstrapをインストールすることができました。ドロップダウン、ポップオーバー、ツールチップの配置はPopperに依存しているので、Popperもインストールします。これらのコンポーネントを使用する予定がない場合は、ここでPopperを省略することができます。
npm i --save bootstrap @popperjs/core
-
追加の依存関係をインストールします。 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を初期化しました。次に、src
とdist
フォルダを作成して、プロジェクトの構造を完成させます。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を設定し、ローカルでプロジェクトを実行できるようにします。
-
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' }) ] }
-
次に、
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で読み込まれたときに表示されるようにしています。 -
あとは、Webpackを実行するためのnpmスクリプトが必要です。
package.json
を開き、以下に示すstart
スクリプトを追加します(すでにテストスクリプトはあるはずです)。このスクリプトを使用して、ローカルのWebpack開発サーバーを起動することにします。{ // ... "scripts": { "start": "webpack serve", "build": "webpack build --mode=production", "test": "echo \"Error: no test specified\" && exit 1" }, // ... }
-
そして、最後にWebpackを起動します。 ターミナルにある
my-project
フォルダから、新しく追加したnpmスクリプトを実行します:npm start
このガイドの最後となる次のセクションでは、Webpackローダーをセットアップし、BootstrapのすべてのCSSとJavaScriptをインポートします。
Bootstrapをインポートする
BootstrapをWebpackにインポートするには、最初のセクションでインストールしたローダーが必要です。npmでインストールしましたが、今度はWebpackがそれらを使用するように設定する必要があります。
-
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
はHTMLページの<head>
内の<style>
要素にCSSを注入し、css-loader
は@import
とurl()
の使用を助け、postcss-loader
はAutoprefixerに必要で、sass-loader
でSassを使えるようにします。 -
では、BootstrapのCSSをインポートしてみましょう。 Bootstrapの全てのソースSassを取得するには
src/scss/styles.scss
に以下を追加してください。// Import all of Bootstrap's CSS @import "bootstrap/scss/bootstrap";
また、必要であれば、スタイルシートを個別にインポートすることもできます。詳しくは、Sass importのドキュメントをご覧ください。
-
次に、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'
Bootstrapのプラグインの使用方法については、JavaScriptのドキュメントをお読みください。
-
で、終了です! 🎉 BootstrapのソースであるSassとJSが完全に読み込まれ、ローカルの開発サーバーはこのような状態になりました。
これで、使用したいBootstrapコンポーネントを追加し始めることができます。カスタムSassを追加して、BootstrapのCSSとJSの必要な部分のみをインポートしてビルドを最適化する方法については、Webpackの完全なサンプルプロジェクトを必ずチェックしてください。
プロダクションの最適化
あなたのセットアップによっては、プロダクションでプロジェクトを実行するのに便利な追加のセキュリティと速度の最適化を実装したい場合があります。これらの最適化はWebpackのサンプルプロジェクトでは適用されないので、実装するのはあなた次第であることに注意してください。
CSSを抽出する
上記で設定した style-loader
は、CSSをバンドルに出力するので、手動でdist/index.html
にあるCSSファイルを読み込む必要がありません。しかし、この方法は厳格なContent Security Policyでは機能しないかもしれませんし、バンドルサイズが大きいためアプリケーションのボトルネックになるかもしれません。
CSSを分離してdist/index.html
から直接読み込めるようにするには、Webpackプラグインのmini-css-extract-loader
を使用します。
まず、プラグインをインストールします:
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
を再度実行すると、src/js/main.js
でインポートしたCSSをすべて含むdist/main.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から正しく参照されていることが確認できます。
何か間違っていたり、古くなっていたりしませんか?GitHubで課題を開いてください。トラブルシューティングのヘルプが必要ですか?GitHubで検索するか、ディスカッションを開始してください。