{"action":"created","issue":{"url":"https://api.github.com/repos/twbs/bootstrap/issues/19017","repository_url":"https://api.github.com/repos/twbs/bootstrap","labels_url":"https://api.github.com/repos/twbs/bootstrap/issues/19017/labels{/name}","comments_url":"https://api.github.com/repos/twbs/bootstrap/issues/19017/comments","events_url":"https://api.github.com/repos/twbs/bootstrap/issues/19017/events","html_url":"https://github.com/twbs/bootstrap/issues/19017","id":128385844,"number":19017,"title":"Bootstrap JavaScript modules API design questions/issues","user":{"login":"petetnt","id":7641760,"avatar_url":"https://avatars.githubusercontent.com/u/7641760?v=3","gravatar_id":"","url":"https://api.github.com/users/petetnt","html_url":"https://github.com/petetnt","followers_url":"https://api.github.com/users/petetnt/followers","following_url":"https://api.github.com/users/petetnt/following{/other_user}","gists_url":"https://api.github.com/users/petetnt/gists{/gist_id}","starred_url":"https://api.github.com/users/petetnt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/petetnt/subscriptions","organizations_url":"https://api.github.com/users/petetnt/orgs","repos_url":"https://api.github.com/users/petetnt/repos","events_url":"https://api.github.com/users/petetnt/events{/privacy}","received_events_url":"https://api.github.com/users/petetnt/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/twbs/bootstrap/labels/js","name":"js","color":"ffc40d"},{"url":"https://api.github.com/repos/twbs/bootstrap/labels/v4","name":"v4","color":"563d7c"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-01-24T10:08:17Z","updated_at":"2016-03-24T21:03:08Z","closed_at":null,"body":"As a part of #17325, I have been doing the initial legwork of having better modularization for the Bootstrap modules. Currently it is rather painful to get the dependencies working properly when trying to minimize global variables and it's pretty much impossible to hand pick the features you want (without hacking on the source).\r\n\r\nSolving #17325 is relatively easy to handle: adding `import jQuery from \"jquery\"`, `import Tether from \"tether` and adding both of those to `package.json`. The tricky part comes when the user needs (or wants) a bit more control over the Bootstrap modules. Bootstrap has always* been automagical: you add the `bootstrap.js` file and suddenly you have all the features the framework uses at hand through the HTML markup binding. Or you could just use the provided JS API's.\r\n\r\nAs modular JavaScript has gotten more and more popular in the past few years, the developers have gotten accustomed to fine-grained control over the source files, into a situation where not everything has to be dumped to the page and then it *just works*. Like in https://github.com/twbs/bootstrap/issues/17325#issuecomment-137025922, the obvious choice would be allowing to import the files one by one and use them as you want to:\r\n\r\n```\r\n  import { Modal, Popover } from \"bootstrap\"\r\n```\r\n\r\nIn my [bs-modules](https://github.com/petetnt/bootstrap/blob/petetnt/bs-modules/js/src/index.js) branch this sort of works right now: `Modal` will be modal and Popover will be popover. The real issues begin here:\r\n\r\n#### IIFE's and re-exporting\r\n\r\nAll the components are wrapped in to IIFE's\r\n\r\n```\r\n   const Foo = ((foo) => { })(bar)\r\n```\r\n\r\nWhen we re-export the files in [index.js](https://github.com/petetnt/bootstrap/blob/petetnt/bs-modules/js/src/index.js) the exported files are executed from top to bottom and all of the IIFE's get triggered. Consider something like this:\r\n\r\n```\r\n  import $ from 'jquery'\r\n  import { Tooltip } from 'bootstrap'\r\n  console.log(Tooltip) // Tooltip\r\n  console.log(Modal) // undefined\r\n  console.log($.fn.tooltip) // Tooltip\r\n  console.log($.fn.modal) // Modal\r\n```\r\n\r\nNot entirely sure what would be the best way to avoid this. Most likely creating some kind of `init`-methods that are IIFE'd in the compiled version (`bootstrap.js`) that could be called manually when importing, or \r\nmaking the end users initialize their own components (throught something like `Tooltip($(\".foo\"), {config: options, here: yup})`.\r\n\r\n#### Pretranspiled or raw sources\r\n\r\nCurrently the distributed modules are transpiled with Babel and wrapped into UMD-wrappers. `npm.js` file is created by Grunt which requires all the modules. Now the userland can use the modules without transpilation, but if you are creating something this ES2015 this seems a bit redundant as you most likely have your own transpilation process going on. #18934 asks for where the source files are and I agree: the raw sources should be included. Which leads to the question, should the UMD-modules be included too? Some of the options:\r\n\r\n- Only offer the raw ES2015 and mention in the docs that transpilation is most likely needed and show ways how to do it\r\n  - Lowest maintenance cost, dist modules === src modules\r\n  - Configure [popular bundlers in repo](https://github.com/petetnt/bootstrap/blob/petetnt/bs-modules/package.json#L88)\r\n  - Might cause headaches to some end users?\r\n- Offer ES2015 files and the transpiled ones. UMD files could be imported with `bootstrap/umd` and the ES2015 files `bootstrap`  \r\n  - Increased maintenance cost\r\n  - Most robust\r\n- Offer separate packages for the 2015 and UMD flavors\r\n\r\n#### Opinions?\r\n\r\nAny opinions about either of these or the modularization in ? We are getting quite to the release (or end of the alpha, I assume) and these are quite big choices. Like in https://github.com/twbs/bootstrap/issues/17325#issuecomment-134876486 there was some discussion about people not complaining about the dependencies not being there and @vejersele replying how most people were not using Bootstrap via `npm` because it was *hard* and that's most likely true. It would be a shame if that happened to `v4` too: I really want to use Bootstrap in most of my projects, but at its current state it's near impossible to get it to integrate with my apps in a way that I would consider somewhat standard. \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/twbs/bootstrap/issues/comments/201019848","html_url":"https://github.com/twbs/bootstrap/issues/19017#issuecomment-201019848","issue_url":"https://api.github.com/repos/twbs/bootstrap/issues/19017","id":201019848,"user":{"login":"cvrebert","id":419884,"avatar_url":"https://avatars.githubusercontent.com/u/419884?v=3","gravatar_id":"","url":"https://api.github.com/users/cvrebert","html_url":"https://github.com/cvrebert","followers_url":"https://api.github.com/users/cvrebert/followers","following_url":"https://api.github.com/users/cvrebert/following{/other_user}","gists_url":"https://api.github.com/users/cvrebert/gists{/gist_id}","starred_url":"https://api.github.com/users/cvrebert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cvrebert/subscriptions","organizations_url":"https://api.github.com/users/cvrebert/orgs","repos_url":"https://api.github.com/users/cvrebert/repos","events_url":"https://api.github.com/users/cvrebert/events{/privacy}","received_events_url":"https://api.github.com/users/cvrebert/received_events","type":"User","site_admin":false},"created_at":"2016-03-24T21:03:07Z","updated_at":"2016-03-24T21:03:07Z","body":"@danimalweb Please read the 3rd bullet point of https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md#using-the-issue-tracker"}}