react-hot-loader breaks the execution of any project that includes a .mjs file.
One should be able to import .mjs files. These are more and more common. Eg. GraphQL is publishing .mjs files.
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.
React Hot Loader version: 4.3.12
Run these commands in the project folder and fill in their results:
node -v: v8.11.3npm -v: 5.6.0Then, specify:
It sounds like
if
importis found in the file, then useimportto get react-hot-loader, else userequire.
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!
Most helpful comment
The new (4.6.5) version is
requirefriendly(initial issue), while disabling safety net makes itmodulefriendly (strange, but you cantmodule.hot.acceptin mjs)I've just tested your demo - one change to babelrc and it works!