Contents
Install Bootstrap 4
Please note, Bootstrap 4 requires peer dependencies jquery
and tether
(for alpha) or popper.js
(for beta+).
Alpha instructions:
npm --save install bootstrap@next jquery tether
Beta+ instructions:
npm --save install bootstrap@next jquery popper.js
Create local Bootstrap 4 configuration
We need to import base Bootstrap 4 configuration and be able to remove some components to make js/css library lighter and also we need to be able to override any variable, mixin etc.
Create directory src/bootstrap
which will containt js/css import and overrides.
Main js import file src/bootstrap/bootstrap.js
should match with node_modules/bootstrap/Gruntfile.js
babel section.
Create js import file src/bootstrap/bootstrap.js
:
// If you don't have ES6 transpiler or have TypeScript then you could use distributed version but will loose module customization
import 'src/bootstrap/dist/js/bootstrap';
// If you have ES6 transpiler then you could code below and will be able to customize what modules will be included in the build.
/*
import 'bootstrap/js/src/alert';
import 'bootstrap/js/src/button';
import 'bootstrap/js/src/carousel';
import 'bootstrap/js/src/collapse';
import 'bootstrap/js/src/dropdown';
import 'bootstrap/js/src/modal';
import 'bootstrap/js/src/popover';
import 'bootstrap/js/src/scrollspy';
import 'bootstrap/js/src/tab';
import 'bootstrap/js/src/tooltip';
*/
Main css import file src/bootstrap/bootstrap.scss
should be a slightly tuned version of default main import file located in node_modules/bootstrap/scss/bootstrap.scss
.
Create css import file src/bootstrap/bootstrap.scss
:
// Site overrides
@import "variables";
// Core variables and mixins
@import "~bootstrap/scss/custom";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
// Reset and dependencies
@import "~bootstrap/scss/normalize";
@import "~bootstrap/scss/print";
// Core CSS
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
// Components
@import "~bootstrap/scss/animation";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/input-group";
@import "~bootstrap/scss/custom-forms";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/pagination";
@import "~bootstrap/scss/tags";
@import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/progress";
@import "~bootstrap/scss/media";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/responsive-embed";
@import "~bootstrap/scss/close";
// Components w/ JavaScript
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tooltip";
@import "~bootstrap/scss/popover";
@import "~bootstrap/scss/carousel";
// Utility classes
@import "~bootstrap/scss/utilities";
Create test override
Create test override in src/bootstrap/_varibales.scss
:
$enable-flex: true;
$brand-primary: #710000;
HTML to test if bootstrap overrides are working well:
<button class="btn btn-primary">Button should be red</button>
Import Library
Import tether and bootstrap custom import main files somewhere in src/main.js
or src/index.js
:
// Tether (required for Bootstrap 4.x Alpha)
// import 'tether';
// import 'tether/src/css/tether-theme-basic.sass'; // optional
// Popper.js (required for Bootstrap 4.x Beta+)
// Popper is auto imported by Bootstrap JS modules where it is needed
// Bootstrap 4.x
import './bootstrap/bootstrap';
import './bootstrap/bootstrap.scss';
Webpack Configuration
We need autoprefixer, scss and ES6 transpiler (optionally, for custom js library build) to be able to build Bootstrap 4.
JQuery (and Tether for Bootstrap v4.x Alpha) should be properly exported into globals.
webpack.config.js:
var webpack = require('webpack');
var sassLoader = isDevServer
? ['style-loader?sourceMap', 'css-loader?sourceMap', 'postcss-loader?sourceMap', 'sass-loader?sourceMap'].join('!')
: ExtractTextPlugin.extract(['css-loader?sourceMap', 'postcss-loader?sourceMap', 'sass-loader?sourceMap']);
// autoprefixer configuration based on Bootstrap 4.x ALPHA defaults
// var autoprefixerBrowsers = require('bootstrap/grunt/postcss').autoprefixer.browsers;
// autoprefixer configuration based on Bootstrap 4.x BETA defaults
var autoprefixerBrowsers = require('bootstrap/package.json').browserslist;
var config = {
...
module: {
loaders: [
{
test: /\.(scss|sass)$/,
loader: sassLoader
}
]
},
plugins: [
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'window.jQuery': 'jquery'
// For Bootstrap 4.x Alpha, for Beta+ is not needed
// 'Tether': 'tether'
// 'window.Tether': 'tether'
}),
],
postcss: function () {
return [
require('postcss-flexbugs-fixes'),
require('autoprefixer')({ browsers: autoprefixerBrowsers })
];
}
};
...
module.exports = config;
Customization
src/bootstrap/bootstrap.js
could be used to remove js components from library.
src/bootstrap/bootstrap.scss
could be used to remove css components from library.
src/bootstrap/*.scss
could be used to alter variables, mixins or components.
Try to keep the same file/folder structure under src/bootstrap
as you have under node_modules/bootstrap/scss
.
Test Repo
You could see example configuration in https://github.com/sormy/skeleton-react-ts
Great stuff Artem! Thanks. Just switching to Webpack from Gulp. Made my day a lot easier.
There’s something with the Tether still. I’m getting that popover isn’t a defined function…
“Create directory src/bootstrap which will containt js/css import and overrides.”
Are we copying these after they are installed from the node modules directory?
We are creating our own files and importing code from node_modules. That will allow us to decouple our changes from mainstream changes and will simplify upgrade for mainstream part.
Thanks for this!
For anyone stumbling upon this with Webpack 2.x which doesn’t allow passing custom parameters to the config, you can pass those same parameters in a file placed in src/bootstrap/postcss.config.js.
Can you explain the following line:
var autoprefixerBrowsers = require(‘bootstrap/grunt/postcss’).autoprefixer.browsers;
Thanks!
Use the same autoprefixer configuration as bootstrap’s default
uh, can you elaborate? why does
require(‘bootstrap/grunt/postcss’)
work? It is its not working for me since there is no ‘bootstrap/grunt/postcss’ module. Also, what is the autoprefixer config for bootstrap?You are right, in latest beta v4 autoprefixer’s list of browsers moved to package.json, so you could fix code as:
var autoprefixerBrowsers = require('bootstrap/package.json').browserslist;
Another change in bootstrap v4 beta is usage Popper.js intead of Tether.js
thank you much, Artem. I am brand new to webpack, and all this was very helpful, clear, and comprehensive,
Hey, thanks for the article but I cannot make it work with Bootstrap4 (beta.2).
Getting these errors: https://pastebin.com/4x2CGWtw
It is probably something simple but I am very new to webpack and js…
Could you have a look?
Thanks