Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getInteropBlock() to work with null prototype objects #3420

Merged
merged 2 commits into from Mar 6, 2020
Merged

getInteropBlock() to work with null prototype objects #3420

merged 2 commits into from Mar 6, 2020

Conversation

jdalton
Copy link
Contributor

@jdalton jdalton commented Mar 5, 2020

…e objects

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

List any relevant issue numbers:

Description

Currently, rollup attempts to detect how exports should be generated based on the exported values from the module entry.

  1. If there is a default export, export the default property as-is.
  2. If there is a named export (named), rollup returns an object with the named property.
  3. If there are both a default export and a named export (named), rollup returns an object with the default and the named property. It's important to note that if no output.exports property is set, rollup warns in this case.

On the other hand, when importing the default value from an external module, rollup injects some interop code extract the code right default value. This interop checks the presence of the default property on the exported object using module.hasOwnProperty('default').

I recently ran into a case where the interop code throws an error because hasOwnProperty is not defined on the external module. This happens because the module (module/a) has a single default export and the default export value has no prototype. In this case, if another module (module/b) imports the default export the interop code will throw because hasOwnProperty is not defined on the object.

/* `module/a` original code */
export default { __proto__: null, name: 'a' };

/* `module/a` generated code */
define('module/a', function () { 'use strict';
  var main = { __proto__: null, name: 'a' };
  return main;
});
/* `module/b` original code */
import a from 'module/a';
console.log(a.name);

/* `module/b` generated code */
define('module/b', ['module/a'], function (a) { 'use strict';
  a = a && a.hasOwnProperty('default') ? a['default'] : a;
  //              ^ throws here because a does inherit from object!
  console.log(a.name);
});

@jdalton
Copy link
Contributor Author

jdalton commented Mar 5, 2020

I need to follow-up with a test specifically for the null prototype case. Current PR has just existing tests modified.

Update: Added unit test to test this case specifically ✅

@codecov
Copy link

codecov bot commented Mar 5, 2020

Codecov Report

❗ No coverage uploaded for pull request base (master@85c54ee). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #3420   +/-   ##
=========================================
  Coverage          ?   93.29%           
=========================================
  Files             ?      172           
  Lines             ?     6114           
  Branches          ?     1823           
=========================================
  Hits              ?     5704           
  Misses            ?      218           
  Partials          ?      192
Impacted Files Coverage Δ
src/finalisers/shared/getInteropBlock.ts 100% <ø> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 85c54ee...c8390d0. Read the comment docs.

Copy link
Member

@lukastaegert lukastaegert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thanks!

@lukastaegert
Copy link
Member

Update: Added unit test to test this case specifically ✅

Very welcome, and important to document why we do it this way, thanks a lot!

@lukastaegert lukastaegert merged commit eeda078 into rollup:master Mar 6, 2020
@jdalton jdalton deleted the has-own-property-compat branch March 6, 2020 18:13
@jdalton
Copy link
Contributor Author

jdalton commented Mar 6, 2020

Thank you @lukastaegert!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants