I suspect that you were bundling two instances of jQuery. The $.fn.modal was attaching to a different instance than the one you were trying to access.
What ProvidePlugin does is shim modules with imports automatically. When you specify jquery: "jquery/src/jquery" as an option, you’re saying: "add import jQuery from 'jquery/src/jquery' everywhere jQuery is referenced in these other modules I’m bringing into my app, including bootstrap! That means webpack can rewrite the source code of imported modules, including 3rd parties, in your build. (I think it’s kind of cool that webpack can do this sort of thing, but I can see why it comes across as dark magic).
Your own import 'jquery' line is pointing to a different file: you can find the path listed in the main entry in jquery’s package.json file:
main: "dist/jquery.js"
This file is packaged for use directly in browsers. It obviously can work in webpack, as you’ve demonstrated, but it includes a lot of “module-ization” stuff (more offically, a Universal Module Definition) that webpack can already handle for you. The file jquery/src/jquery is structured as an ES module and is more suitable for use in webpack—that’s why tutorials probably pointed you to used it. When you try to import both though, webpack is likely treating these imports as two different modules in your runtime.
Changing the ProvidePlugin to jQuery: 'jquery'and $: 'jquery' fixed the issue because now the “auto” imports are pointing to the same module as your own import jQuery from 'jquery'.
Another way to fix the issue (again, I suspect) is you could have changed your import to match: import jQuery from 'jquery/src/jquery' within your application.js file.
Anyhow, I’m speculating since I don’t have access to your source, but I think that’s what’s going on and, that it’s likely moving the import prior to @rails/ujs had no effect (but I could be missing something). Hope that’s helpful!