Skip to content

Integrating Bootstrap with Webpack in Middleman

This document explains how to configure Webpack to manage Bootstrap in a Middleman project, keeping all Webpack files organized under /source/assets and using MiniCssExtractPlugin to extract CSS in production.

Prerequisites

  • Ruby and Middleman installed
  • Node.js and npm installed

Target Folder Structure

my_project/
├── source/
│   ├── assets/             ← Webpack here
│   │   ├── src/
│   │   │   ├── index.js
│   │   │   └── styles.scss
│   │   ├── build/          ← Webpack output
│   │   ├── img/
│   │   └── webpack.config.js
│   ├── index.html.slim
│   └── layouts/
│       └── layout.slim
├── config.rb
└── package.json

Update your .gitignore File

# Middleman
.bundle
.cache
.sass-cache
build/
Gemfile.lock

# macOS
.DS_Store

# IDEs
.idea/
.vscode/

# Webpack (assets)
assets/build/
assets/node_modules/
assets/package-lock.json
assets/yarn.lock
assets/.parcel-cache/
assets/.webpack-cache/

Install Dependencies

Initialize npm

npm init -y

Install Webpack, Bootstrap, and Extract Plugin

npm install --save bootstrap @popperjs/core
npm install --save-dev webpack webpack-cli css-loader sass-loader sass babel-loader @babel/core @babel/preset-env mini-css-extract-plugin

Webpack Configuration

/source/assets/webpack.config.js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: path.resolve(__dirname, 'src/index.js'),
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'build'),
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({ filename: 'bundle.css' })
  ],
};

Webpack Source Files

/source/assets/src/index.js

import 'bootstrap/scss/bootstrap.scss';
import 'bootstrap';
import './styles.scss';

/source/assets/src/styles.scss

body {
  background-color: #f8f9fa;
}

package.json Scripts

"scripts": {
  "build": "webpack --config ./source/assets/webpack.config.js --mode production",
  "watch": "webpack --config ./source/assets/webpack.config.js --watch",
  "clean": "rm -rf node_modules package-lock.json && npm install"
}

Middleman Configuration

config.rb

set :css_dir, 'assets/build'
set :js_dir, 'assets/build'

Update Layout

source/layouts/layout.slim

doctype html
html
  head
    meta charset="utf-8"
    meta http-equiv="x-ua-compatible" content="ie=edge"
    meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"
    title = current_page.data.title || "Middleman"
    = stylesheet_link_tag "bundle"
    = javascript_include_tag  "bundle"

  body
    == yield

Compile Assets

To compile your bundle:

npm run build

Or to watch for changes:

npm run watch

Optional: Clean and Reinstall Node Modules

If you need to reset your Node environment:

npm run clean

This removes node_modules/ and package-lock.json, then reinstalls all dependencies.

Bootstrap Up & Running with Webpack in Middleman

Update your index.html.slim file:

---
title: 'Bootstrap with Webpack in Middleman'
---
.container.mt-5
  h1.text-primary Bootstrap Collapse Test
  button.btn.btn-info type="button" data-bs-toggle="collapse" data-bs-target="#demoCollapse"
    | Toggle Content
  #demoCollapse.collapse.mt-3
    .card.card-body
      | If you see this, Bootstrap JS is working!

Launch Middleman to serve your Project:

bundle exec middleman

Result

Your Middleman project now integrates Bootstrap via Webpack with extracted CSS, organized under /source/assets, and includes a maintenance script for clean rebuilds.