Bootstrap: A more modular-based approach?

Created on 14 Jun 2019  Ā·  14Comments  Ā·  Source: twbs/bootstrap

It would be nice if, for version 5, Bootstrap could be ā€œmodularisedā€.

One of the criticisms of Bootstrap is that is contains everything but the kitchen sink; this would mitigate that criticism and allow discerning and conscientious developers to be able to pull in only the components they needed and keep their bundle sizes low.

The way I can envisage this working is, the individual components split into separate NPM packages, i.e. @bootstrap/alert, @bootstrap/badge, @bootstrap/breadcrumb, etc. Variables and mixins could be put in a @bootstrap/core or similar package.

The existing bootstrap package could function exactly as it does now (pulls everything in and gives you a Bootstrap build with every component), but developers (like me) could craft bundles with just the components we need, i.e.

@import "my-app-custom-variables";
@import "~@bootstrap/navbar";
@import "~@bootstrap/card";

Based on the above, it looks like each @bootstrap/* package would need to add the @bootstrap/core (or whatever it’s named) package as a dependency.

Of course, developers wanting to get something up and running quickly can still do the same as they have done:

@import "~bootstrap/scss/bootstrap";

I remember CSS wizard Harry Roberts did something similar for his ā€œInuitā€ CSS framework where the framework was broken into individual components that could be installed on an ad hoc basis. It would be nice if Bootstrap followed a similar approach so unnecessary components can be excluded from bundles and builds.

css

Most helpful comment

Update: Sass is going to move to a module system, which could solve this issue:
http://sass.logdown.com/posts/502818-request-for-comments-module-system-proposal

All 14 comments

The issue with this is that for example the cards depend on the variables, functions, mixins and reboot. If we're going to use the @import approach you mentioned above we'll probably end up with including the variables & mixins too much.

We might have a look at using the $enable- variables more. For example we now have a $enable-grid-classes variable to switch on/off the grid classes.

The issue with this is that for example the cards depend on the variables, functions, mixins and reboot.

@MartijnCuppens I foresaw that. Could each individual component not @import a ā€œbaseā€ component before its styles? Or will Sass literally pull in the same styles for every component that imports the base component?

For example:

// components/card.scss
@import "~@bootstrap/base";

// Card styles...

```scss
// components/carousel.scss
@import "~@bootstrap/base";

// Carousel styles...

```scss
@import "my-apps-custom-variables";

// Will this approach pull in the base component multiple times? Or just once?
@import "~@bootstrap/components/card";
@import "~@bootstrap/components/carousel";

If the individual components approach isn’t feasible and it _would_ import the base styles multiple times, then maybe offer an $enabled-components list or something? By default, every component’s included, but can be overridden by developers to specify only the components they need:

// Enable only the card and carousel components on top of base styles
$enabled-components: (
  "card",
  "carousel"
);

Each component could then check if it’s included in the $enabled-components list.

Or will Sass literally pull in the same styles for every component that imports the base component?

Yup, you can follow the discussion about a more modular approach here: https://github.com/sass/sass/issues/1094

Each component could then check if it’s included in the $enabled-components list.

I haven't double-checked this yet, but this doesn't seem to be supported either:
https://github.com/sass/sass/issues/451

I haven't double-checked this yet, but this doesn't seem to be supported either:
sass/sass#451

@MartijnCuppens I was more thinking that a component’s body could be wrapped in the $if statement?

I know this is about the idea and not a specific direction, but one thing to not is that there are definitely tools out there for publishing to multiple packages. We did this for Primer and have since opted to go back to the mono-package approach for simplicity’s sake, for both maintainers and developers.

I would love to maintain the simplicity of a single mono repo package with the best customization options.

I would love to maintain the simplicity of a single mono repo package with the best customization options.

Definitely.

@MartijnCuppens I was more thinking that a component’s body could be wrapped in the $if statement?

This would indent all our scss. Not really a fan of that, it would also make cherry picking changes from master to v4 imposible.

@mdo @MartijnCuppens Do you chaps have any suggestions, then? It would be nice if, as a developer, I could only import the component styles that I need in my applications, rather than Bootstrap being ā€œall or nothingā€.

@martinbean you can have a look at our getting started section which describes how to partially include Bootstrap.

@MartijnCuppens That’s what I’m currently doing, but it’s a bit of a pain to copy-and-paste @import statements. I was just exploring the possibility of a more friendlier approach.

I feel your pain, I don't really like it either but I'm afraid we're limited by the possibilities Sass provides right now.

What about an imperfect solution: divide .scss files into "something else depends on this" and "nothing else depends on this", and provide a "base.scss" which imports all of the former.

To be clear, such a division wouldn't just be core files (e.g. "bootstrap/functions") vs components. It would also include e.g. "bootstrap/buttons", assuming that "bootstrap/button-group" depends on it. (I don't know if it actually does, which is a large part of the difficulty, currently.)

This way the user can import "base.scss", and then have have a coarse-grain way of tuning the rest of the output file size.

Update: Sass is going to move to a module system, which could solve this issue:
http://sass.logdown.com/posts/502818-request-for-comments-module-system-proposal

@MartijnCuppens It seems the Sass team even used Bootstrap as an example of how it could be used šŸ˜„

https://github.com/sass/sass/blob/master/accepted/module-system.md

There are approaches that would work without needing to migrate to the sass module system.

Specifically instead of using partials for components wrap them in a mixin:

@mixin CreateButton() {
  ...button styles as normal

}

then they can be conditionally included:

// bootstrap.scss

@if $enable_button {
   @include CreateButton();
}

We do something similar in react-widgets, accepting a list of widgets you want included, then topographically sort them passed on dependencies and include them: https://github.com/jquense/react-widgets/blob/react-widgets%405.0.0-beta.20/packages/react-widgets/src/scss/react-widgets.scss

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andrade1379 picture andrade1379  Ā·  41Comments

mhawk0 picture mhawk0  Ā·  103Comments

rpkilby picture rpkilby  Ā·  65Comments

SweVictor picture SweVictor  Ā·  38Comments

markoheijnen picture markoheijnen  Ā·  56Comments