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

How to enable tree shaking? #476

Open
vdboor opened this issue Mar 30, 2024 · 11 comments
Open

How to enable tree shaking? #476

vdboor opened this issue Mar 30, 2024 · 11 comments

Comments

@vdboor
Copy link

vdboor commented Mar 30, 2024

Somehow tree shaking isn't working for me. I end up with a JavaScript file of 40kB when I do:

import { Alert, Collapse } from 'bootstrap.native';

Doing the equivalent in Bootstrap 5 JS will give me a 13kB file:

import { Alert } from 'bootstrap/js/src/alert.js';
import { Collapse } from 'bootstrap/js/src/collapse.js';

WebPack is configured with:

{
  mode: 'production',

  optimization: {
    usedExports: true,  // tree shaking
    minimize: true,
    minimizer: [
      new TerserPlugin(),
    ]
  }
}

And my package.json has "sideEffects": false in it.

Is there anything I'm still doing wrong, or is this a bug in the package?

As a sidenote, I would have loved to use the old approach of importing from sub files directly. This is no longer possible due to the exports section in package.json.

@thednp
Copy link
Owner

thednp commented Mar 31, 2024

Yes, this happened during the Rollup => Vite migration. If I could find a solution, will let you know.

thednp added a commit that referenced this issue Mar 31, 2024
* update dependencies
* update Bootstrap CSS to 5.3.3
* attempt to fix tree shaking #476
@thednp
Copy link
Owner

thednp commented Mar 31, 2024

Please test @5.0.12 and let me know.

@valsor
Copy link

valsor commented Jun 29, 2024

Tree shaking isn't working with esbuild also. Is there any workaround to import only selected components from library?

@thednp
Copy link
Owner

thednp commented Jun 29, 2024

I will have to redo the entire tooling for this, build individual components and export them separately in package.json

@valsor
Copy link

valsor commented Jun 29, 2024

Is this on schedule already?

@thednp
Copy link
Owner

thednp commented Jun 29, 2024

Not at this time, no.

@thednp
Copy link
Owner

thednp commented Jul 21, 2024

@vdboor @valsor please test @5.0.13 and let me know. I've updated the tooling to re-enable tree-shaking.

FYI: you have to do import Button from 'bootstrap.native/button'.
I updated the wikies as well.

@verheyenkoen
Copy link

@thednp This doesn't seem to work for me. This code worked before and still works:

import { Toast } from "bootstrap.native";

const toast = Toast.getInstance(toastEl);
// toast is initialized

However the treeshaken version does not work:

import Toast from "bootstrap.native/toast";

const toast = Toast.getInstance(toastEl);
// toast is null

I've verified that the code stepped through the Toast constructor first in both examples.

I've even combined them in one example (during an htmx load event):

import htmx from "htmx.org/dist/htmx.esm.js";
import { Toast as DestructuredToast } from "bootstrap.native";
import TreeShakenToast from "bootstrap.native/toast";

htmx.onLoad((rootEl) => {
  rootEl.querySelectorAll(".toast").forEach((toastEl) => {
    let destructuredToast = DestructuredToast.getInstance(toastEl);
    let treeShakenToast = TreeShakenToast.getInstance(toastEl);

    console.log({ destructuredToast, treeShakenToast });
  });
});

With this result:
image

I can obviously do a null-check and construct it again but that shouldn't be necessary I guess.

Note: We use esbuild for bundling.

Another note: Since we're using HTMX, we use the initCallback method to initialise BSN on injected DOM content, like so:

import * as BSN from "bootstrap.native";

htmx.onLoad((el) => {
  // not necessary on initial load (DOMContentLoaded)
  if (el !== document.body) {
    BSN.initCallback(el);
  }
});

Since initCallback isn't "treeshakeable", I guess there's no real use for us to treeshake individual components in other places, since we'd still have the whole of BSN bundled by this import?

@thednp
Copy link
Owner

thednp commented Jul 26, 2024

Is your project a typescript based project? You might need to restart your Typescript server.

I tried playing around with tsup, might be a good solution for this multi exports tree-shake enabled feature.

Anyways, I'm open to any suggestion.

@verheyenkoen
Copy link

@thednp No, it's JS (with htmx). Hope to convert it to TS soon but still to discuss with other team members. We added BSN to benefit for other additional features. Would that matter anyhow (apart from maybe the import * as BSN from ... statements)?

@thednp
Copy link
Owner

thednp commented Jul 26, 2024

You can try, but I believe using Vite and Typescript will ensure the file loader is in place to handle these separate exports. There could also be some properties missing in your package.json, you might have to check on that.

Just FYI: I installed BSN in a separate project, initialized with Tooltip and it worked out of the box, keep in mind that project is using an identical Typescript and Vite tooling setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants