Importing Bootstrap (Any Node Modules) Into Your Gulp Sass Workflow

Allure Web Solutions Code Snippet

Below is the structure for adding bootstrap, or any other node module SCSS. The hardest part was to get the syntax correctly for the imports and knowing that you need to add node_modules directory to the SASS Path.

Folder Structure (Demo)

project-root/
├── index.html
├── styles/
│   ├── autoload
│       ├── _bootstrap.scss
│   └── style.scss
└── scripts/

Style.scss

I like to glob in SCSS, but you can point directly to your _bootstrap.scss file.

/** Import everything from autoload */
@import "./autoload/**/*";

_Bootstrap.scss

Import whichever components of Bootstrap you would like to use.

@import 'bootstrap/bootstrap';

Gulpfile.js

You can add Bower to sassPaths as well.

// SASS Paths
var sassPaths = ['./node_modules'];

// Demo Sass Task
// compile sass and use postcss
gulp.task('sass', function () {
    return gulp.src(sassFiles)
        .pipe(glob())
        .pipe(sass({includePaths: sassPaths}))
        .pipe(sass().on('error', sass.logError))
        .pipe(sourceMaps.write('maps'))
        .pipe(gulp.dest(buildFolder + '/css'))
});

Package.json

Last step is to add bootstrap + dependencies to your node_modules. Here are some ways to do it:

// Bootstrap
npm i --save-dev bootstrap@4 jquery popper.js


// Using YARN
yarn add --dev bootstrap@4 jquery popper.js

Importing Only Specific Bootstrap Components

Sometimes we don’t want to import the entire bootstrap functionality. In the example below we can see what we’d do differently to import only Bootstrap Breakpoints.

The _bootstrap.scss file will look like this:

// FROM: @import '~bootstrap/scss/_functions'
// Ascending
// Used to evaluate Sass maps like our grid breakpoints.
@mixin _assert-ascending($map, $map-name) {
    $prev-key: null;
    $prev-num: null;
    @each $key, $num in $map {
        @if $prev-num == null {
            // Do nothing
        } @else if not comparable($prev-num, $num) {
            @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
        } @else if $prev-num >= $num {
            @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
        }
        $prev-key: $key;
        $prev-num: $num;
    }
}

// Starts at zero
// Another grid mixin that ensures the min-width of the lowest breakpoint starts at 0.
@mixin _assert-starts-at-zero($map) {
    $values: map-values($map);
    $first-value: nth($values, 1);
    @if $first-value != 0 {
        @warn "First breakpoint in `$grid-breakpoints` must start at 0, but starts at #{$first-value}.";
    }
}

// Grid breakpoints
// FROM: @import '~bootstrap/scss/_variables'
// Define the minimum dimensions at which your layout will change,
// adapting to different screen sizes, for use in media queries.

$grid-breakpoints: (
    xs: 0,
    sm: 576px,
    md: 768px,
    lg: 992px,
    xl: 1200px
) !default;

@include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
@include _assert-starts-at-zero($grid-breakpoints);

@import 'bootstrap/scss/mixins/breakpoints';

 

Mike Doubintchik

Author Mike Doubintchik

More posts by Mike Doubintchik

Leave a Reply