Skip to content

How to use Bootstrap 4 and Sass (and jQuery)

John Hamman edited this page May 10, 2016 · 17 revisions
  1. npm install css-loader node-sass resolve-url-loader sass-loader style-loader url-loader --save-dev
  2. npm install bootstrap-loader@1.0.8 --save
  3. npm install jquery --save
  4. npm install bootstrap@4.0.0-alpha.2 --save
  5. npm install tether --save
  6. Add this .bootstraprc to your project (to the root)
  7. Added autoprefixer to webpack.config.js (to use with postcss - optional):
    const autoprefixer = require('autoprefixer');

    postcss: [autoprefixer],  // this is inside module.exports object
  1. Add loaders to webpack.common.js:
        { test: /\.scss$/, loaders: ['style', 'css', 'postcss', 'sass'] },
        { test: /\.(woff2?|ttf|eot|svg)$/, loader: 'url?limit=10000' },
        // Bootstrap 4
        { test: /bootstrap\/dist\/js\/umd\//, loader: 'imports?jQuery=jquery' }
  1. Add jQuery plugin to webpack.common.js (to plugins array): At the top with the others
/*
 * Webpack Plugins
 */
...
const ProvidePlugin = require('webpack/lib/ProvidePlugin'); 
        // var ProvidePlugin = require('webpack/lib/ProvidePlugin');
        // require the plugin
        new ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery',
            "Tether": 'tether',
            "window.Tether": "tether"
        })
  1. Add to the vendor.ts:
    import 'jquery';
    import 'bootstrap-loader';
  1. Add some Bootstrap markup to your home.html to see that it works

Resulting webpack.config.js (make same changes to webpack.prod.config.js for production build):

// @AngularClass

/*
 * Helper: root(), and rootDir() are defined at the bottom
 */
var path = require('path');
// Webpack Plugins
var ProvidePlugin = require('webpack/lib/ProvidePlugin');
var DefinePlugin = require('webpack/lib/DefinePlugin');
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const autoprefixer = require('autoprefixer');

var metadata = {
    title: 'Angular2 Webpack Starter',
    baseUrl: '/',
    host: 'localhost',
    port: 3000,
    ENV: ENV
};
/*
 * Config
 */
module.exports = {
    // static data for index.html
    metadata: metadata,
    // for faster builds use 'eval'
    devtool: 'source-map',
    debug: true,

    entry: {
        'polyfills': './src/polyfills.ts',
        'main': './src/main.ts' // our angular app
    },

    // Config for our build files
    output: {
        path: root('dist'),
        filename: '[name].bundle.js',
        sourceMapFilename: '[name].map',
        chunkFilename: '[id].chunk.js'
    },

    resolve: {
        // ensure loader extensions match
        extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html'] // <-- include .scss
    },

    module: {
        preLoaders: [{ test: /\.ts$/, loader: 'tslint-loader', exclude: [/node_modules/] }],
        loaders: [
            // Support for .ts files.
            {
                test: /\.ts$/,
                loader: 'ts-loader',
                exclude: [/\.(spec|e2e)\.ts$/]
            },

            // Support for *.json files.
            { test: /\.json$/, loader: 'json-loader' },

            // Support for CSS as raw text
            { test: /\.css$/, loader: 'raw-loader' },

            // support for .html as raw text
            { test: /\.html$/, loader: 'raw-loader', exclude: [ root('src/index.html') ] },

            // if you add a loader include the resolve file extension above

            { test: /\.scss$/, loaders: ['style', 'css', 'postcss', 'sass'] },

            { test: /\.(woff2?|ttf|eot|svg)$/, loader: 'url?limit=10000' },

            // Bootstrap 4
            { test: /bootstrap\/dist\/js\/umd\//, loader: 'imports?jQuery=jquery' }
        ]
    },

    // sassResources: path.resolve(__dirname, "./node_modules/bootstrap/scss"),

    postcss: [autoprefixer], // <--- postcss

    plugins: [
        new CommonsChunkPlugin({ name: 'vendor', filename: 'vendor.bundle.js', minChunks: Infinity }),
        // static assets
        new CopyWebpackPlugin([{ from: 'src/assets', to: 'assets' }]),
        // generating html
        new HtmlWebpackPlugin({ template: 'src/index.html' }),
        // replace
        new DefinePlugin({
            'process.env': {
                'ENV': JSON.stringify(metadata.ENV),
                'NODE_ENV': JSON.stringify(metadata.ENV)
            }
        }),
        // jQuery, Tether
        new ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery',
            "Tether": 'tether',
            "window.Tether": "tether"
        })
    ],

    // Other module loader config
    tslint: {
        emitErrors: false,
        failOnHint: false
    },
    // our Webpack Development Server config
    devServer: {
        port: metadata.port,
        host: metadata.host,
        historyApiFallback: true,
        watchOptions: { aggregateTimeout: 300, poll: 1000 }
    },
    // we need this due to problems with es6-shim
    node: { global: 'window', progress: false, crypto: 'empty', module: false, clearImmediate: false, setImmediate: false }
};

// Helper functions

function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}

function rootNode(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return root.apply(path, ['node_modules'].concat(args));
}

If you want to change Bootstrap's sass variable and use in your project, do the following:

  • webpack config:
{ test: /.scss$/, loaders: ['raw-loader','sass-loader'] },
  • component:
 styles: [require('./component.scss')],
  • .bootstraprc file:
preBootstrapCustomizations: ./path/to/your/custom/variables.scss

Clone this wiki locally