Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A more modular-based approach? #28900

Closed
martinbean opened this issue Jun 14, 2019 · 15 comments
Closed

A more modular-based approach? #28900

martinbean opened this issue Jun 14, 2019 · 15 comments
Labels

Comments

@martinbean
Copy link
Contributor

martinbean commented Jun 14, 2019

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.

@MartijnCuppens
Copy link
Member

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.

@martinbean
Copy link
Contributor Author

martinbean commented Aug 9, 2019

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...
// components/carousel.scss
@import "~@bootstrap/base";

// Carousel styles...
@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.

@MartijnCuppens
Copy link
Member

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: sass/sass#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:
sass/sass#451

@martinbean
Copy link
Contributor Author

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?

@mdo
Copy link
Member

mdo commented Aug 10, 2019

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.

@MartijnCuppens
Copy link
Member

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.

@martinbean
Copy link
Contributor Author

martinbean commented Aug 12, 2019

@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”.

@MartijnCuppens
Copy link
Member

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

@martinbean
Copy link
Contributor Author

@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.

@MartijnCuppens
Copy link
Member

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.

@jonathanhefner
Copy link
Contributor

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.

@MartijnCuppens
Copy link
Member

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

@martinbean
Copy link
Contributor Author

@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

@jquense
Copy link
Contributor

jquense commented Oct 22, 2020

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

@mdo
Copy link
Member

mdo commented Apr 12, 2022

I think this will be covered by migrating to the Sass module system in v6, so closing as a duplicate of #29853.

@mdo mdo closed this as completed Apr 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants