{"action":"created","issue":{"url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/8005","repository_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped","labels_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/8005/labels{/name}","comments_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/8005/comments","events_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/8005/events","html_url":"https://github.com/DefinitelyTyped/DefinitelyTyped/issues/8005","id":132015025,"number":8005,"title":"\"Export equals\" syntax when used with Webpack and Babel","user":{"login":"JakubJagoda","id":1622378,"avatar_url":"https://avatars.githubusercontent.com/u/1622378?v=3","gravatar_id":"","url":"https://api.github.com/users/JakubJagoda","html_url":"https://github.com/JakubJagoda","followers_url":"https://api.github.com/users/JakubJagoda/followers","following_url":"https://api.github.com/users/JakubJagoda/following{/other_user}","gists_url":"https://api.github.com/users/JakubJagoda/gists{/gist_id}","starred_url":"https://api.github.com/users/JakubJagoda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JakubJagoda/subscriptions","organizations_url":"https://api.github.com/users/JakubJagoda/orgs","repos_url":"https://api.github.com/users/JakubJagoda/repos","events_url":"https://api.github.com/users/JakubJagoda/events{/privacy}","received_events_url":"https://api.github.com/users/JakubJagoda/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-02-07T21:29:16Z","updated_at":"2016-02-11T14:26:36Z","closed_at":null,"body":"Before we start, a quick word on \"why would you use TS with Babel\"\r\n# Tl;dr for using Babel\r\nTypeScript does not currently support full set of features when compiled to ES5. For..of loops [are compiled to regular for loops](https://github.com/Microsoft/TypeScript/pull/2207), async/await support for ES5/ES3 is [not yet finished](https://github.com/Microsoft/TypeScript/issues/1664) and planned to be delivered in version 2.0. So in order to have these working in all today's browsers and environments, one can just set the TS output to es6 and then pass it further to Babel, which will take care of the rest.\r\n\r\n# Export equals\r\nHowever, this is a problem with TypeScript's specific \"export equals\" syntax. If used, then import of this module has to be imported using `import * as something` way. Let's look at simple example:\r\n```typescript\r\n//a.d.ts\r\ndeclare var A;\r\ndeclare module 'A' {\r\n   export = A;\r\n}\r\n\r\n//b.ts\r\nimport * as A from 'A';\r\n```\r\nthis is weird for me, as the handbook says \r\n>The export = syntax specifies a single object that is exported from the module\r\n\r\n but if you try to use `import A from 'A';` syntax you'll get an error telling you that this module has no default export. But okay, we can just simply use the `import * as` syntax instead.\r\n\r\n# Where's the problem\r\nIf we try to bundle the application using Webpack + TypeScript loader then everything is fine. If we also use Babel loader on the way (to cover the case I described in the first point), then it starts not be fine. Why? Because Babel handles `import * as` in a special way. It creates a plain empty object, and then fills it with all the exports as properties. **This causes different problems with various libraries**. So far I identified 3 of them (Bluebird, jQuery, d3), but I suppose there's more.\r\n\r\n## Bluebird, jQuery and probably other callables\r\nWith Bluebird and jQuery the main problem is that what is exported are functions. When it gets transpiled by Babel, these functions get replaced by objects. The objects has all the properties the functions had, but are not callable anymore, which makes it impossible to actually use these two libraries (a hack exists, but it doesn't apply to all the libs. I'll describe it later).\r\n\r\n## d3\r\nWith d3 the problem is a bit different. d3 does not export a callable, therefore we can still use it and everything seem to work fine. However, d3 uses a \"global\" place (`d3.event`) where it stores the object representing last triggered event. Let's not discuss if it's a bad idea and why it is, this is just the way this lib works. So, because of how Babel treats imports, `d3.event` that d3 uses internally and `d3.event` that we use in the module where we imported d3, do not refer to the same thing. Therefore, we are not able to access the information about triggered event.\r\n\r\n## demo\r\nHere is a repository that demonstrates the problem: https://github.com/JakubJagoda/dt-babel-problem\r\nJust clone it and follow the README.\r\n\r\n# How to solve it\r\nAll the problems I mentioned can be simply solved by changing the exports&import declaration from e.g.\r\n```typescript\r\n//export \r\nexport = d3\r\n\r\n//import \r\nimport * as d3 from 'd3'\r\n```\r\nto:\r\n```typescript\r\n//export \r\nexport default d3\r\n\r\n//import \r\nimport d3 from 'd3'\r\n```\r\nI think that conceptually it is reasonable to consider that these libraries export a single \"thing\" instead of a set of functions, as syntax `import * as x from 'x'` might suggest. Since it's an easy change I can open a PR which solves that at least for these 3 libraries (I expect there are more of them, but haven't spotted any yet) but first I want to know what the general opinion on that is. Maybe there is another way to solve this or any way to drop Babel but still using all TS features in ES5?\r\n\r\n# Bonus: the hack\r\nAs I mentioned before, a simple hack exist (at least for callability problem), but it requires the library to have a function that returns the library object itself (for example jQuery has `noConflict()`). So we create a file, for example jquery-fix.ts and put this inside:\r\n```typescript\r\nimport * as jQueryFactory from 'jquery';\r\nconst $ : JQueryStatic = <JQueryStatic>jQueryFactory.noConflict();\r\nexport default $;\r\n```\r\nand then, instead of importing `'jquery'` in our files, we import this module. Works for Bluebird too. However I'm not sure if a similar hack for d3-related problems exists, as well as for the libs that don't have functions returning the lib objects themselves."},"comment":{"url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/comments/182886640","html_url":"https://github.com/DefinitelyTyped/DefinitelyTyped/issues/8005#issuecomment-182886640","issue_url":"https://api.github.com/repos/DefinitelyTyped/DefinitelyTyped/issues/8005","id":182886640,"user":{"login":"JakubJagoda","id":1622378,"avatar_url":"https://avatars.githubusercontent.com/u/1622378?v=3","gravatar_id":"","url":"https://api.github.com/users/JakubJagoda","html_url":"https://github.com/JakubJagoda","followers_url":"https://api.github.com/users/JakubJagoda/followers","following_url":"https://api.github.com/users/JakubJagoda/following{/other_user}","gists_url":"https://api.github.com/users/JakubJagoda/gists{/gist_id}","starred_url":"https://api.github.com/users/JakubJagoda/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JakubJagoda/subscriptions","organizations_url":"https://api.github.com/users/JakubJagoda/orgs","repos_url":"https://api.github.com/users/JakubJagoda/repos","events_url":"https://api.github.com/users/JakubJagoda/events{/privacy}","received_events_url":"https://api.github.com/users/JakubJagoda/received_events","type":"User","site_admin":false},"created_at":"2016-02-11T14:26:36Z","updated_at":"2016-02-11T14:26:36Z","body":"@vvakame I proposed the solution in \"How to solve it\" section, did you read it? "}}