Creating a customized bundle with Bootstrap using the Rollup tool

In the official Bootstrap 5 documentation, it mentions that we can import pre-compiled js files from bootstrap/js/dist and create a custom bundle using tools like Webpack or rollup.

https://getbootstrap.com/docs/5.0/getting-started/javascript/#individual-or-compiled

The optimizing section of the documentation provides an example of how to import js files. https://getbootstrap.com/docs/5.0/customize/optimize/#lean-javascript

The issue: I have created a file called bootstrap.js

import 'bootstrap/js/dist/tooltip';

I only want to use the Tooltip plugin. Below is the configuration I am using for rollup

const plugins = [
    babel({
      exclude: 'node_modules/**',
      // Include the helpers in each file, at most one copy of each
      babelHelpers: 'bundled',
      presets: [
        [
          '@babel/preset-env',
          {
            loose: true,
            bugfixes: true,
            modules: false
          }
        ]
      ]
    }),
    nodeResolve()
]

const bundle = await rollup.rollup({
    input: './js/vendors/bootstrap.js',
    plugins,
})

await bundle.write({
    format: 'umd',
    file: './file.js'
})

After generating the file.js and including it in an HTML page, an error appears in the console stating

file.js:1727 Uncaught ReferenceError: process is not defined

I am also unable to initialize the Tooltip plugin using Bootstrap syntax new bootstrap.Tooltip results in an undefined bootstrap error.

To resolve this issue, I have resorted to importing these files from the js/src folder and exporting them as used in js/src/index.umd.js. However, following Bootstrap's official documentation on importing their plugin does not seem to work correctly.

Answer №1

Issue with Bootstrap Documentation

Although this may not be the desired solution, it appears that there is an error in Bootstrap's documentation.

When attempting to import for 'umd' output using the following syntax:

import Dropdown from '../../node_modules/bootstrap/js/dist/dropdown';

The build fails with the error message:

Error: 'default' is not exported by node_modules\bootstrap\js\dist\dropdown.js, imported by src\js\bootstrap-build.js

This is contradictory to Bootstrap's claim that files in bootstrap/js/dist use default exports (source).

Solution that Works (includes Popper):

If you are facing a build issue and seeking a resolution, here is what has worked for me.

Assuming all dependencies were installed via NPM as dev dependencies except for Bootstrap 5, which was installed using this command:

npm install bootstrap

This is my rollup.config.js:

import {terser} from 'rollup-plugin-terser';

export default {
    input: './src/js/bootstrap-build.js',
    output: {
        file: 'dist/js/bootstrap.umd.min.js',
        format: "umd",
        name: "bsbundle", // this is the name of the global object
        esModule: false,
        sourcemap: true,
    },
    plugins: [terser({compress: {drop_console: true, module: true}})]
};

This is the project's entry script, bootstrap-build.js, located in <project root>/src/js/:

import * as Popper from '../../node_modules/@popperjs/core/dist/umd/popper.js';

//imports from 'js/src/*'
import Modal from '../../node_modules/bootstrap/js/src/modal';
import Tab from '../../node_modules/bootstrap/js/src/tab';
import Dropdown from '../../node_modules/bootstrap/js/src/dropdown';
import Tooltip from '../../node_modules/bootstrap/js/src/tooltip';

export default {
  Dropdown,
  Modal,
  Tab,
  Tooltip
}

And the package.json:

{
  "name": "bscomponents",
  "version": "1.0.0",
  "description": "Project for building Bootstrap 5 components.",
  "main": "index.js",
  "scripts": {
    "build-bs": "rollup -c"
    },
  "keywords": [],
  "author": "",
  "license": "",
  "dependencies": {
    "bootstrap": "^5.1.3"
  },
  "devDependencies": {
    ...
  }
}

NPM build command:

NPM run build-bs

Build Note: The line importing Popper in the Bootstrap Dropdown and Tooltip source files is commented out.

The bundle includes Popper, Dropdown, Modal, Tab, and Tooltip.

File index.html in the project root for testing the bundle.

...

Development Environment:

  • Windows 10
  • Rollup v2.6
  • Node v16.10.0
  • NPM 8.1.3
  • Bootstrap 5.1.3

The resulting build bundle, including Popper, saves approximately 21kb compared to Bootstrap's minified distributed bundle.

Reported probable documentation issue on GitHub

Answer №2

Unsure how to break down your code - the entire dependency on Popper seems to be missing.

This is my approach (hint: I extracted only the essentials from the BS5 source code.)

If you are building on top of a modified version of Bootstrap 5:

File: build\rollup.config.mk.js:

'use strict'

const path = require('path')
const { babel } = require('@rollup/plugin-babel')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const replace = require('@rollup/plugin-replace')
const banner = require('./banner.js')

let fileDest = `bootstrap-mk`
const external = ['@popperjs/core']
const plugins = [
  babel({
    // Only transpile our source code
    exclude: 'node_modules/**',
     // Include the helpers in the bundle, at most one copy of each
    babelHelpers: 'bundled'
  })
]
const globals = {
  '@popperjs/core': 'Popper'
}

const rollupConfig = {
  input: path.resolve(__dirname, `../js/index.mk.umd.js`),
  output: {
    banner,
    file: path.resolve(__dirname, `../dist/js/${fileDest}.js`),
    format: 'umd',
    globals
  },
  external,
  plugins
}

rollupConfig.output.name = 'bootstrap'

module.exports = rollupConfig

... and also ...

File: js\index.mk.umd.js

import Tooltip from './src/tooltip'

export default {
  Tooltip
}

To compile, run:

rollup --config build/rollup.config.mk.js --sourcemap
in the command line, or add something similar to this in the packacge.json \ "scripts" section:

  "js-compile-mk": "rollup --config build/rollup.config.mk.js --sourcemap",

You can then execute npm run js-compile-mk in the command line.

The output will be a file named: dist\js\bootstrap-mk.js (and a map file)


If you prefer not to use a fork, but instead a node_modules sub-folder, make changes to the paths in the build\rollup.config.mk.js file.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize Ajax datatable to showcase information in a visually interactive format

I've been grappling with this problem for an entire day. Essentially, I have a table and I need to pass data in a multidimensional array $list through a datatable using AJAX. This way, I can JSON encode it and send it back for display: $('#table ...

A guide on how to group by multiple keys and calculate the sum of multiple property values within a JavaScript array using Node.js

Can you suggest the most efficient method to group by multiple keys and calculate the sum of multiple property values in a JavaScript array? For example: [ { Category: "Category 1", Subcategory: "Subcategory 1", Value1: "15&q ...

When utilizing the built-in filter in Angular 2 ag-grid, the Clear Filter button efficiently removes any text from the filter box without needing to refresh the

When using ag-Grid's default filter feature, I noticed that the clear filter button only clears the text box and does not automatically refresh the column, even when the 'clearButton' and 'applyButton' parameters are set to true. T ...

Guide on how to have two controllers execute identical tasks in Angular while modifying the appearance of the website

Trying to recreate Google's homepage functionality using Angular has been challenging for me. Despite watching Egghead videos and studying the API extensively, I couldn't find a specific example for this behavior. Here's what I aim to achiev ...

Can you provide the keycodes for the numpad keys: "/" and "." specifically for the libraries I am utilizing or any other library that does not overlook them?

I've hit a roadblock with my Chrome Extension development. Despite using two different methods to add keyboard functionality, the keys "/" for divide and "." for decimal on the keypad are just not registering. I've attempted to tackle this issue ...

Tips for disabling the default behavior by using preventDefault in JavaScript

I need help with removing the preventDefault() function and submitting the form in the else condition of my code. Does anyone know how to achieve this? if(email.val() != ""){ //check email e.preventDefault(); $.ajax({ ...

Looking for an API to retrieve random quotes and images from a website?

Greetings, my name is Antika. I recently embarked on a coding journey and have been focusing on learning HTML/CSS along with the basics of JS. Level of Expertise: Beginner During my exploration, I stumbled upon this intriguing website - . It stands out a ...

Can anyone provide guidance on how to make slideToggle move upwards with jQuery?

<div class="row"> <div class="col-lg-2" ></div> <div class="head" style="background-color: #1c94c4; text-align: center; cursor: pointer;"> Connect</div> <div class="chat" style="display: none;width:a ...

Material-UI's style is taking precedence over other styles that have been defined

Introduction Last week, I posted a similar query which touched on the same issue. However, as the solution seems to be different this time around, I am revisiting it in a new thread. Check out the updated version of the CodeSanbox Example that reflects t ...

What could be causing my bounce animation to begin 50 pixels higher than its intended starting point?

Trying to create a bouncing effect on text Check out my attempt here. It seems like the bug is in this area. @keyframes bounce{ 0%, 40%{ transform:scale(2,.5) translate(0,100px); } 45%,55%{ transform:translate(0,-50px); } 55%, 100%{ ...

No code is appearing on the page, just a blank space

Whenever I visit this page on the web, the screen shows up as empty and I've encountered similar issues with other JavaScript pages that I've created. This makes me wonder if there might be a missing piece of code or something else causing the pr ...

Learn how to efficiently reload a card in React upon submitting new data

Is there a way to automatically refresh the card component after submitting data without having to manually refresh the page? I've tried using useEffect but it's not updating the data even though the value is changing. Any suggestions on how to r ...

In React/Next.js, it seems that pressing the useState button twice is required in order for an event to trigger

When working with react/nextjs, I encountered an issue with a click event where I'm trying to use setState to modify an array. Strangely, the modification only takes effect after two clicks of the button. Here is the initial state array: const [array ...

Unable to make colors appear in HTML5 canvas using .fillStyle

Trying my hand at canvas for the first time to create a game. I have an image displaying, but strangely the fillStyle method doesn't seem to be working as expected (the canvas background remains white in Google Chrome). Just a note that in my code, t ...

Error: Attempting to access property 'setData' of an undefined object results in a TypeError [Slider]

I encountered an error with my slider that says Uncaught TypeError: Cannot read property 'setData' of undefined. The error occurs when I use material ui as a component along with redux-form. This issue happens specifically when the slider is bein ...

Encountering a Next.js event type issue within an arrow function

After creating my handleChange() function to handle events from my input, I encountered an error that I'm unsure how to resolve. Shown below is a screenshot of the issue: https://i.sstatic.net/fWJA2.png I am currently working with Next.js. In React ...

Error: The property 'ss' cannot be accessed because it is undefined

Our main source page will be index.html, while Employees.html is where our results end up. An error occurred: TypeError - Cannot read property 'ss' of undefined Error in the code: let rating = req.body.ss; Seeking assistance please >< C ...

Verifying the timestamp of file submission in a form

My goal is to create an HTML form that allows users to send a file to my server, while also recording the exact time they initiated the file transfer. However, I'm facing an issue where only the time the file is received is being logged, rather than w ...

When using Express, the XML response is returning an empty document

I'm experimenting with a simple API that returns XML response: const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const libxmljs = require("libxmljs"); const PO ...

The issue of elements flickering while being hidden and shown with jQuery has been observed in both Chrome and

Having trouble with a simple animation using jQuery? While it may work smoothly in Firefox, you might be experiencing flickering in Chrome and Edge. Check out this jsfiddle for reference: HTML <div id="boxes-wrapper"> <div class="box"></ ...