bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Bootstrap collapse close animation breaks when builiding in Angular's production mode

Open qbus00 opened this issue 3 years ago • 18 comments

Prerequisites

Describe the issue

I don't know if this can be treated as a bug of Bootstrap, it's just a specific usage of Javascript but I think it's worth to mention it here.

There is an issue with close animation of collapse panel when running Angular project with Bootstrap in production mode. You can check it here: https://github.com/qbus00/angular-bootstrap-collapse-test

I have reported a bug to Angular-CLI team - https://github.com/angular/angular-cli/issues/22635 - but they have closed it describing it as "by design".

Quote from reply (can be also found under aforementioned link):

Hi, I investigated this morning and this seems to be caused by pure_getters terser option. Bootstrap relies on side effects example https://github.com/twbs/bootstrap/blob/a5483a8a96eaa88b4da7e432e0b925d0f3943dc3/js/src/collapse.js#L182 therefore in this case it is expected that the code breaks during runtime. There are a couple of resolutions for this that you can read more about in https://github.com/angular/angular-cli/issues/11439#issuecomment-433141561 Closing as this is working as intended.

As I understand it's because Bootstrap's JS is using getters not only to access property but also modifies something, which when running minification breaks the functionality.

Is there something you can do about that? Maybe rewrite this portion of Javascript - instead of getters maybe just a simple function would fix this?

Mixture of Angular and Bootstrap is not something uncommon....

Reduced test cases

  1. Clone: https://github.com/qbus00/angular-bootstrap-collapse-test
  2. "npm install"
  3. "ng serve --configuration production"
  4. run browser
  5. click on CLICK ME button
  6. expand animation works
  7. click again CLICK ME button
  8. collapsing animation does not work
  9. stop ng serve
  10. repeat steps 3 to 9 but instead of "ng serve --configuration production" run "ng serve"
  11. collapsing animation now works (no optimization of bootstrap.js file)

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

Windows, macOS, Android, iOS, Linux

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

Chrome, Firefox, Microsoft Edge, Opera

What version of Bootstrap are you using?

5.1, 5.0

qbus00 avatar Feb 03 '22 10:02 qbus00

@twbs/js-review Any thoughts?

mdo avatar Apr 12 '22 20:04 mdo

Hi qbus00! I think something I tried earlier could be used as a workaround. I'm new to Angular and everything related to web development, so I'm aware this might not be the best approach.

I first read your bug report and saw that the recommended "solution" was to opt-out from the uglify optimizations implemented by Angular. I tried it but the size of my project exceeded the 1MB budget so I ended up not doing that and I enabled the optimizations back.

However by checking the terminal output where the raw sizes are shown, I noticed that scripts.js did not increase or reduce it's size while uglify was turned off with Bootstrap JS being the only script. This made me realize that bootstrap.min.js was not taking advantage of any optimizations.

I then thought: "What if I copy the contents of the minified file from node_modules, and paste it a line below in the scripts.js file after the app is built?"

Well, I did that and it looks like it worked! I deployed my app to GitHub Pages making sure building was skipped, and the collapse animation started working again (visible for mobile only).

The app is based on this Angular tutorial by Fireship if anyone is wondering, great guide!

Anyways, I hope this helps you and everyone else struggling with this small problem.

ghost avatar May 08 '22 05:05 ghost

Hi qbus00! I think something I tried earlier solves this issue. I'm new to Angular and everything related to web development, so I'm aware this might not be the best approach but hey! It solves the animation problem after all.

So I first read your bug report and saw that the recommended "solution" was to opt-out from the uglify optimizations implemented by Angular. I tried it but the size of my project exceeded the 1MB budget so I ended up not doing that and I enabled the optimizations back.

However by checking the terminal output where the raw sizes are shown, I noticed that scripts.js did not increase or reduce it's size while uglify was turned off with Bootstrap JS being the only script. This made me realize that bootstrap.min.js was not taking advantage of any optimizations.

I then thought: "What if I copy the contents of the minified file from node_modules, and paste it a line below in the scripts.js file after the app is built?"

Well, I did that and it looks like it worked! I deployed my app to GitHub Pages making sure building was skipped, and the collapser started working as it should. You can see the solution in action here (collapsible menu visible for mobile only).

The app is based on this Angular tutorial by Fireship if anyone is wondering, great guide!

Anyways, I hope this workaround helps you and everyone else struggling with this small problem.

Well, this is what I have done in my project too in my project some time ago but this does not resolve a bug - as you said it's just a workaround.

qbus00 avatar May 13 '22 10:05 qbus00

Yes, you are correct. I changed my wording and have updated my comment, glad to know you also got it to work

ghost avatar May 13 '22 17:05 ghost

@GeoSot @julien-deramond is this fixed easily without breaking anything else? If so, could we land it in v5.2.2 maybe?

Otherwise, if we can't fix it in the source code, we might as well disable the related terser option?

XhmikosR avatar Sep 28 '22 04:09 XhmikosR

Having the same problem in my Angular14 project after the production build. So I have added temporary "configurations":{"optimization": false} in the angular.json file then it is working fine for me.

I am new to angular so I am not sure if this is valid or not.

urmik-zwt avatar Oct 07 '22 14:10 urmik-zwt

It's valid, but you are totally disabling production optimizations altogether which is bad for production.

I'm still not sure what we can do to fix this.

XhmikosR avatar Nov 13 '22 13:11 XhmikosR

I am still having the issue with Angular 15.1.2 and Bootstrap 5.2.

eliferd avatar Mar 17 '23 17:03 eliferd

Still having the issue with Angular 15.2.6 and Bootstrap 5.2.

Animation works fine in dev environment But in prod environment, collapse close animation is broken

Dev Environment Prod Environment
2023-04-09-dev-env 2023-04-09-prod-env
Dev:Animation on close is ok Prod: No animation on close

mohamed-badaoui avatar Apr 09 '23 17:04 mohamed-badaoui

Unsure how we can work around this? If anyone has any non-breaking suggestions, please make a PR and CC me.

XhmikosR avatar Apr 09 '23 18:04 XhmikosR

As @rarb1t said, by now the only way to make it work is to use a workaround: Use a shell script to replace angular optimized bootstrap script with original bootstrap minified file and run it after ng build inside dockerfile

Run script in Dockerfile

...
# keep original bootstrap file
RUN docker/prod/build/copy-bootstrap-js.sh
...

Shell script: copy-bootstrap-js.sh

#!/bin/sh
error() {
    printf '\33[1;37;41mERROR: %s\033[0m\n\n' "$*"
    exit 1
}

bootstrapJsFile=/app/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js;

# check if bootstrapJsFile exists
if [ ! -f "$bootstrapJsFile" ]; then
  error 'ERROR: bootstrap file not found.\n'
fi;

# Search script files and copy orginal bootstrap file 
scripts=`find /app/dist -name 'scripts.*.js'`
for script in $scripts; do
  cp -p "$bootstrapJsFile" "$script";
done;

mohamed-badaoui avatar Apr 17 '23 07:04 mohamed-badaoui

I'm having the same issue, is there any fix without disabling Angular's prod optimizations?

danilobassi8 avatar Oct 18 '23 12:10 danilobassi8

Has there been any update on this issue yet?

harrisonwlee avatar Jan 03 '24 18:01 harrisonwlee

I was having the same problem in my Angular16 project after the production build. So I have added "configurations":{"optimization": false} in the angular.json for production mode in the file then it is working fine for me.

gayatrisuslade26 avatar Mar 01 '24 18:03 gayatrisuslade26

I'll say it again in case people miss it: https://github.com/twbs/bootstrap/issues/35776#issuecomment-1312736536

I'd be more than happy to accept a PR that fixes the issue, ideally accompanied with tests.

XhmikosR avatar Mar 02 '24 08:03 XhmikosR

Having the same issue with Angular v17.3.0 / Bootstrap v5.3.3 It's unbelievable this is failing and not fixed yet by Angular or Bootstrap teams. Disabling 'optimization' for a project in Production only for this silly thing makes me angry to be honest...

There's another alternative workaround, which is including the bootstrap source from the index.html as described here: https://stackoverflow.com/questions/70159067/angular-bootstrap-accordion-animation-is-not-working-on-close-in-production

It makes me angry too...

pablovargasosorio avatar Mar 21 '24 07:03 pablovargasosorio

This worked for me: ngbAccordion works perfectly with 'optimization'. It's easy to change from 'accordion' to 'ngbAccordion' in the HTML (if you have ngBootstrap installed in your project)

More info: https://ng-bootstrap.github.io/#/components/accordion/overview

pablovargasosorio avatar Mar 21 '24 09:03 pablovargasosorio

Hi, I hope this help some of you: I migrated last week to Angular 17 and changed the builder to Esbuild, and it is working as expected now.

danilobassi8 avatar Mar 21 '24 12:03 danilobassi8