React-hot-loader: Breaks with `.mjs`

Created on 13 Nov 2018  路  5Comments  路  Source: gaearon/react-hot-loader

Description

react-hot-loader breaks the execution of any project that includes a .mjs file.

Expected behavior

One should be able to import .mjs files. These are more and more common. Eg. GraphQL is publishing .mjs files.

Actual behavior

It breaks the execution of the app (not the compilation). I think the main reason is that Webpack has a special kind of hidden mode for .mjs file and will entirely ignore any require (which react-hot-loader is injecting). For example, when using GraphQL:

Uncaught ReferenceError: require is not defined
    at eval (defineToJSON.mjs:4)
    at eval (defineToJSON.mjs:7)
    at Module.../node_modules/graphql/jsutils/defineToJSON.mjs (VM53 experiment.js:1900)
    at __webpack_require__ (VM53 experiment.js:725)
    at fn (VM53 experiment.js:102)
    at eval (definition.mjs:49)
    at Module.../node_modules/graphql/type/definition.mjs (VM53 experiment.js:2308)
    at __webpack_require__ (VM53 experiment.js:725)
    at fn (VM53 experiment.js:102)
    at eval (validate.mjs:5)

When inspecting the code, it is clear that require is not being properly compiled. Here is one of graphql modules as imported in my project:

__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "graphql", function() { return graphql; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "graphqlSync", function() { return graphqlSync; });
/* harmony import */ var _type_validate__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./type/validate */ "../node_modules/graphql/type/validate.mjs");
/* harmony import */ var _language_parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./language/parser */ "../node_modules/graphql/language/parser.mjs");
/* harmony import */ var _validation_validate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./validation/validate */ "../node_modules/graphql/validation/validate.mjs");
/* harmony import */ var _execution_execute__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./execution/execute */ "../node_modules/graphql/execution/execute.mjs");
(function () {
  var enterModule = require('react-hot-loader').enterModule;

  enterModule && enterModule(module);
})();

It should be __webpack__require__. The behaviour is intended in Webpack. I believe the new rule is that no require should never be injected in a .mjs file.

Environment

React Hot Loader version: 4.3.12

Run these commands in the project folder and fill in their results:

  1. node -v: v8.11.3
  2. npm -v: 5.6.0

Then, specify:

  1. Operating system: Mac OS 10.14.1
  2. Browser and version: Firefox 63.0.1, Safari 12.0.1, Google Chrome 70.0.3538.77

Reproducible Demo

https://github.com/QuentinRoy/react-hot-loader-mjs-crash

bug enhancement

Most helpful comment

const plugins = [
    ["react-hot-loader/babel", {safetyNet: false}]
  ];

The new (4.6.5) version is require friendly(initial issue), while disabling safety net makes it module friendly (strange, but you cant module.hot.accept in mjs)

I've just tested your demo - one change to babelrc and it works!

All 5 comments

It sounds like

if import is found in the file, then use import to get react-hot-loader, else use require.

Would affect both babel and webpack logic.

I'm facing the same issue, is there any workaround?

probably it's time to use a global variable :)

I'm sorry, but I don't understand what safetyNet controls exactly. Do I have to use safetyNet: true to make it work for mjs files? And what else does that do?

const plugins = [
    ["react-hot-loader/babel", {safetyNet: false}]
  ];

The new (4.6.5) version is require friendly(initial issue), while disabling safety net makes it module friendly (strange, but you cant module.hot.accept in mjs)

I've just tested your demo - one change to babelrc and it works!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Anahkiasen picture Anahkiasen  路  5Comments

lemonmade picture lemonmade  路  3Comments

esturcke picture esturcke  路  3Comments

niba picture niba  路  4Comments

theKashey picture theKashey  路  4Comments