{"action":"created","issue":{"url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/92","repository_url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs","labels_url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/92/labels{/name}","comments_url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/92/comments","events_url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/92/events","html_url":"https://github.com/rollup/rollup-plugin-commonjs/pull/92","id":174099764,"number":92,"title":"[WIP] BREAKING: interop, take 2","user":{"login":"Rich-Harris","id":1162160,"avatar_url":"https://avatars.githubusercontent.com/u/1162160?v=3","gravatar_id":"","url":"https://api.github.com/users/Rich-Harris","html_url":"https://github.com/Rich-Harris","followers_url":"https://api.github.com/users/Rich-Harris/followers","following_url":"https://api.github.com/users/Rich-Harris/following{/other_user}","gists_url":"https://api.github.com/users/Rich-Harris/gists{/gist_id}","starred_url":"https://api.github.com/users/Rich-Harris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Rich-Harris/subscriptions","organizations_url":"https://api.github.com/users/Rich-Harris/orgs","repos_url":"https://api.github.com/users/Rich-Harris/repos","events_url":"https://api.github.com/users/Rich-Harris/events{/privacy}","received_events_url":"https://api.github.com/users/Rich-Harris/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2016-08-30T19:08:01Z","updated_at":"2016-09-03T15:07:38Z","closed_at":"2016-08-31T21:29:52Z","pull_request":{"url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/pulls/92","html_url":"https://github.com/rollup/rollup-plugin-commonjs/pull/92","diff_url":"https://github.com/rollup/rollup-plugin-commonjs/pull/92.diff","patch_url":"https://github.com/rollup/rollup-plugin-commonjs/pull/92.patch"},"body":"This supersedes #91. Summary:\r\n\r\n* Sourcemaps are no longer generated for CommonJS modules (explanation below)\r\n* Transformed modules are smaller, largely because namespaces are no longer needlessly generated\r\n* The default export of a transformed CommonJS module is `module.exports`, or, if `exports.__esModule === true`, `exports.default` (previously it would always use `.default` if it was present)\r\n* If a CommonJS module imports another CommonJS module, `.default` interop *no longer takes place* – this fixes bugs like rollup/rollup#866\r\n\r\nI won't lie: the approach here feels a little bit crazy. I think that's just the price of having good (and efficient) interop.\r\n\r\nBefore the explanation, a couple of comparisons:\r\n\r\n## Basic CommonJS importing\r\n\r\n### Source\r\n\r\n```js\r\n// main.js\r\nvar foo = require( './foo' );\r\nmodule.exports = foo * 2;\r\n\r\n// foo.js\r\nmodule.exports = 21;\r\n```\r\n\r\n### Before\r\n\r\n```js\r\n'use strict';\r\n\r\nfunction interopDefault(ex) {\r\n  return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;\r\n}\r\n\r\nfunction createCommonjsModule(fn, module) {\r\n  return module = { exports: {} }, fn(module, module.exports), module.exports;\r\n}\r\n\r\nvar foo = createCommonjsModule(function (module) {\r\nmodule.exports = 21;\r\n});\r\n\r\nvar foo$1 = interopDefault(foo);\r\n\r\n\r\nvar require$$0 = Object.freeze({\r\n  default: foo$1\r\n});\r\n\r\nvar main = createCommonjsModule(function (module) {\r\nvar foo = interopDefault(require$$0);\r\nmodule.exports = foo * 2;\r\n});\r\n\r\nvar main$1 = interopDefault(main);\r\n\r\nmodule.exports = main$1;\r\n```\r\n\r\n### After\r\n\r\n```js\r\n'use strict';\r\n\r\nfunction createCommonjsModule(fn, module) {\r\n  return module = { exports: {} }, fn(module, module.exports), module.exports;\r\n}\r\n\r\nvar require$$0 = createCommonjsModule(function (module) {\r\nmodule.exports = 21;\r\n});\r\n\r\nvar main = createCommonjsModule(function (module) {\r\nvar foo = require$$0;\r\nmodule.exports = foo * 2;\r\n});\r\n\r\nmodule.exports = main;\r\n```\r\n\r\n## Inline require statements\r\n\r\n\r\n### Source\r\n\r\n```js\r\n// main.js\r\nmodule.exports = function () {\r\n  return require( './multiply' )( 2, require( './foo' ) );\r\n};\r\n\r\n// multiply.js\r\nmodule.exports = function ( a, b ) {\r\n  return a * b;\r\n};\r\n\r\n// foo.js\r\nmodule.exports = 1;\r\n```\r\n\r\n### Before\r\n\r\n```js\r\n'use strict';\r\n\r\nfunction interopDefault(ex) {\r\n  return ex && typeof ex === 'object' && 'default' in ex ? ex['default'] : ex;\r\n}\r\n\r\nfunction createCommonjsModule(fn, module) {\r\n  return module = { exports: {} }, fn(module, module.exports), module.exports;\r\n}\r\n\r\nvar multiply = createCommonjsModule(function (module) {\r\nmodule.exports = function ( a, b ) {\r\n  return a * b;\r\n};\r\n});\r\n\r\nvar multiply$1 = interopDefault(multiply);\r\n\r\n\r\nvar require$$1 = Object.freeze({\r\n  default: multiply$1\r\n});\r\n\r\nvar foo = createCommonjsModule(function (module) {\r\nmodule.exports = 1;\r\n});\r\n\r\nvar foo$1 = interopDefault(foo);\r\n\r\n\r\nvar require$$0 = Object.freeze({\r\n  default: foo$1\r\n});\r\n\r\nvar main = createCommonjsModule(function (module) {\r\nmodule.exports = function () {\r\n  return interopDefault(require$$1)( 2, interopDefault(require$$0) );\r\n};\r\n});\r\n\r\nvar main$1 = interopDefault(main);\r\n\r\nmodule.exports = main$1;\r\n```\r\n\r\n### After\r\n\r\n```js\r\n'use strict';\r\n\r\nfunction createCommonjsModule(fn, module) {\r\n  return module = { exports: {} }, fn(module, module.exports), module.exports;\r\n}\r\n\r\nvar require$$1 = createCommonjsModule(function (module) {\r\nmodule.exports = function ( a, b ) {\r\n  return a * b;\r\n};\r\n});\r\n\r\nvar require$$0 = createCommonjsModule(function (module) {\r\nmodule.exports = 1;\r\n});\r\n\r\nvar main = createCommonjsModule(function (module) {\r\nmodule.exports = function () {\r\n  return require$$1( 2, require$$0 );\r\n};\r\n});\r\n\r\nmodule.exports = main;\r\n```\r\n\r\n## How it works\r\n\r\nBasically, when you import a CommonJS module from an ES module, you're no longer importing the module itself but a proxy, which imports the *actual* CommonJS module but with a prefixed ID (`\\0commonjs-required:/path/to/cjs-module.js`). The proxy handles the ES <-> CJS interop – deciding whether `module.exports` or `exports.default` should be the default export, and adding named exports – while the module itself (with the prefixed ID) *always* just has a single default export which is `module.exports`. Its dependencies are re-declared as prefixed imports.\r\n\r\nMeanwhile, if a module with a prefixed ID (i.e., imported by a proxy or a CommonJS module) *isn't* a CommonJS module, we need a different kind of interop layer, which imports the underlying ES module and exports-as-default *either* its default export (if there is one) *or* the entire namespace. That way, we don't need to reify namespaces for everything that a CommonJS module imports, only ES modules.\r\n\r\nAn unfortunate side-effect of this is that sourcemaps no longer work for CommonJS modules, because the source code lives in virtual modules, which get excluded. I haven't been able to think of a good solution to this. Honestly, I think it's a small trade-off for more reliable interop and more efficient code, given that sourcemaps are mostly useful when you're debugging your own code.\r\n\r\nI think this covers all the bases. @rollup/collaborators and others – would welcome any feedback on this before we commit to this road! Sorry for the rambly and complex explanation.\r\n"},"comment":{"url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/comments/244551611","html_url":"https://github.com/rollup/rollup-plugin-commonjs/pull/92#issuecomment-244551611","issue_url":"https://api.github.com/repos/rollup/rollup-plugin-commonjs/issues/92","id":244551611,"user":{"login":"piuccio","id":680284,"avatar_url":"https://avatars.githubusercontent.com/u/680284?v=3","gravatar_id":"","url":"https://api.github.com/users/piuccio","html_url":"https://github.com/piuccio","followers_url":"https://api.github.com/users/piuccio/followers","following_url":"https://api.github.com/users/piuccio/following{/other_user}","gists_url":"https://api.github.com/users/piuccio/gists{/gist_id}","starred_url":"https://api.github.com/users/piuccio/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/piuccio/subscriptions","organizations_url":"https://api.github.com/users/piuccio/orgs","repos_url":"https://api.github.com/users/piuccio/repos","events_url":"https://api.github.com/users/piuccio/events{/privacy}","received_events_url":"https://api.github.com/users/piuccio/received_events","type":"User","site_admin":false},"created_at":"2016-09-03T15:07:38Z","updated_at":"2016-09-03T15:07:38Z","body":"Glad to know that more bytes can be saved. For correctness I should mention that the savings on react are due mostly to #93, while the savings on preact can certainly be attributed to this PR. Thanks for the great work."}}
{"actor":{"display_login":"piuccio"}}