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

Cannot load UMD module created with transform-es2015-modules-umd as an ES module. #10476

Open
MicahZoltu opened this issue Sep 21, 2019 · 3 comments · May be fixed by #10477

Comments

@MicahZoltu
Copy link

commented Sep 21, 2019

Bug Report

Current Behavior
If you apply the transform-es2015-modules-umd plugin to a module, the resulting code cannot be executed as an ES module.

The problem stems from the fact that the generated code passes this as the first parameter to the UMD function. When executed as an ES module, this is undefined at the script scope so undefined gets passed into the UMD function. globalThis and window are both defined in the browser context (I haven't tested NodeJS), so the UMD module can still function if something besides this was passed in to the UMD function.

Input Code

<!DOCTYPE html>
<html lang='en'>
	<head><meta charset='utf-8'></head>
	<body>
		<script type='module' src='my-module.js'></script>
	</body>
</html>

Original ES module (my-module.mjs):

export default 42;

Generated UMD module (my-module.js):

(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["exports"], factory);
  } else if (typeof exports !== "undefined") {
    factory(exports);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod.exports);
    global.input = mod.exports;
  }
})(this, function (_exports) {
  "use strict";

  Object.defineProperty(_exports, "__esModule", {
    value: true
  });
  _exports.default = void 0;
  var _default = 42;
  _exports.default = _default;
});

Expected behavior/code
The module would execute when loaded as an ES module.

Babel Configuration (.babelrc, package.json, cli command)

{ 
  globals: { 
    "webextension-polyfill": "browser", 
  }, 
  exactGlobals: true, 
}

Environment

  • Babel version(s): "babel-plugin-transform-es2015-modules-umd": "^6.24.1"
  • Node/npm version: Unknown
  • OS: Unknown
  • Monorepo: No.
  • How you are using Babel: Grunt

Possible Solution
Change the UMD function call to pass globalThis || window || this as the first parameter, rather than passing this as the first parameter. This change will make the module fully functional when loaded as an ES module, while still retaining the current behavior when loaded as a script.

Additional context/Screenshots
The problem showed up for me over at the webextension-polyfill page, spelunking lead me to realize the problem is with Babel, which that project uses for transpiling to UMD.
mozilla/webextension-polyfill#202

@babel-bot

This comment has been minimized.

Copy link
Collaborator

commented Sep 21, 2019

Hey @MicahZoltu! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."

MicahZoltu added a commit to MicahZoltu/babel that referenced this issue Sep 21, 2019
Fixes babel#10476 
Note: This PR should be considered pseudocode and used as an illustration of the proposed fix.  I do not know nearly enough about this project to know if this is an appropriate solution to the problem, nor do I have the confidence to update the tests appropriately.
@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

commented Sep 21, 2019

UMD can't be compatible with ES modules. It isn't possible to create a file which is compatible with ES modules and with RequireJS/AMD, because the first one uses syntax which isn't supported in scripts.

@MicahZoltu

This comment has been minimized.

Copy link
Author

commented Sep 21, 2019

To be clear, I'm not suggesting spitting out something that uses ES module syntax. I'm suggesting simply passing globalThis || window || this to the UMD function call site instead of this. That alone makes it so you can call a UMD module generated by Babel from an ES module context.

MicahZoltu added a commit to MicahZoltu/babel that referenced this issue Sep 24, 2019
Fixes babel#10476
Note: This PR should be considered pseudocode and used as an illustration of the proposed fix.  I do not know nearly enough about this project to know if this is an appropriate solution to the problem, nor do I have the confidence to update the tests appropriately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.