twbs / bootstrap

The most popular HTML, CSS, and JavaScript framework for developing responsive, mobile first projects on the web.
https://getbootstrap.com
MIT License
168.38k stars 78.55k forks source link

Tree shaking not working with RollupJS #37575

Open astagi opened 1 year ago

astagi commented 1 year ago

Prerequisites

Describe the issue

I can't make tree shaking working using Bootstrap. If I try something like

import { Button } from 'bootstrap'

I get the whole library included in my bundle.

Reduced test cases

The Rollup.js configuration I'm using is the following:

// rollup.config.js

import { babel } from '@rollup/plugin-babel'
import scss from 'rollup-plugin-scss'
import uglify from '@lopatnov/rollup-plugin-uglify'
import nodeResolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import injectProcessEnv from 'rollup-plugin-inject-process-env'

export default [
  {
    input: 'demo.entry.js',
    output: {
      file: 'dist/js/demo.bundle.min.js',
      format: 'iife',
      compact: true
    },
    plugins: [
      babel({
        babelHelpers: 'bundled',
        exclude: 'node_modules/**',
      }),
      scss({
        output: 'dist/css/demo.min.css',
        outputStyle: 'compressed',
        sourceMap: true,
      }),
      nodeResolve(),
      commonjs(),
      injectProcessEnv({
        NODE_ENV: 'production',
      }),
      uglify()
    ],
  }
]

What operating system(s) are you seeing the problem on?

macOS

What browser(s) are you seeing the problem on?

Chrome

What version of Bootstrap are you using?

v5.1.3

XhmikosR commented 1 year ago

You should import the individual component from the dist/js folder or try the newly added index.esm.js file.

Unsure how we can improve this, any suggestions welcome.

astagi commented 1 year ago

Hi @XhmikosR @julien-deramond,

index.esm.js is the problem. As you can declare in package.json, the index file for modules is dist/js/bootstrap.esm.js

  "module": "dist/js/bootstrap.esm.js",

This file contains class declarations and some code to make components working, however the whole Bootstrap gets imported when I try to do something like

import { Alert, Tooltip } from 'bootstrap'

I created a little demo here with a detailed README to show the problem I'm experiencing with the current version of Bootstrap and a possible solution using a patched version of the library. Basically I can't get tree shake working on my project unless I change the way you create the esm file (single index.esm.js and then a single file for each component, e.g. src/alert.js, src/tooltip.js)

Also I've created a PR (https://github.com/twbs/bootstrap/pull/37733) to fix this problem, if you think it's ok for you please review it and I'll be happy to make all the changes it needs. I removed the minified esm, I don't know if it's useful, I optimize the final code in the project where I use Bootstrap.

This approach has been also implemented and tested in Bootstrap-Italia the official library of the Italian Government to implement the current design specifications.

benwallis commented 1 year ago

I ran into this too - https://stackoverflow.com/questions/75661065/bootstrap-javascript-in-webpack-5-only-working-as-esm Maybe related to using babel-preset-env

MattiJarvinen commented 1 month ago

Still current.

erwinheldy commented 3 weeks ago

Try bootstrap-esm, I created it because of this issue; if this issue is resolved, I will deprecate bootstrap-esm.