Skip to content

Commit 93d0b1f

Browse files
committed
fix: opt-out for module safety net, fixes #1102, #1159
1 parent 24d0448 commit 93d0b1f

File tree

3 files changed

+2048
-11
lines changed

3 files changed

+2048
-11
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,28 @@ setConfig({
451451

452452
Mark a component as hot.
453453

454+
#### Babel plugin
455+
456+
Right now babel plugin has only one option, enabled by default.
457+
458+
* `safetyNet` - will help you properly setup ReactHotLoader.
459+
460+
You may disable it to get more control on the module execution order.
461+
462+
```js
463+
//.babelrc
464+
{
465+
"plugins": [
466+
[
467+
"react-hot-loader/babel",
468+
{
469+
"safetyNet": false
470+
}
471+
]
472+
]
473+
}
474+
```
475+
454476
#### Important
455477

456478
**!!** Use `hot` only for module `exports`, not for module `imports`. **!!**

src/babel.dev.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const shouldIgnoreFile = file =>
1212
.match(/node_modules\/(react|react-hot-loader)([\/]|$)/)
1313
/* eslint-enable */
1414

15-
module.exports = function plugin(args) {
15+
module.exports = function plugin(args, options = {}) {
1616
// This is a Babel plugin, but the user put it in the Webpack config.
1717
if (this && this.callback) {
1818
throw new Error(
@@ -27,34 +27,42 @@ module.exports = function plugin(args) {
2727
}
2828
const { types: t, template } = args
2929

30+
const { safetyNet = true } = options
31+
3032
const buildRegistration = template(
3133
'reactHotLoader.register(ID, NAME, FILENAME);',
3234
templateOptions,
3335
)
3436
const headerTemplate = template(
3537
`(function () {
36-
var enterModule = require('react-hot-loader').enterModule;
38+
var enterModule = (typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal : require('react-hot-loader')).enterModule;
3739
enterModule && enterModule(module);
3840
}())`,
3941
templateOptions,
4042
)
43+
const footerTemplate = template(
44+
`(function () {
45+
var leaveModule = (typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal : require('react-hot-loader')).leaveModule;
46+
leaveModule(module);
47+
}())`,
48+
templateOptions,
49+
)
4150
const evalTemplate = template('this[key]=eval(code);', templateOptions)
4251

4352
// We're making the IIFE we insert at the end of the file an unused variable
4453
// because it otherwise breaks the output of the babel-node REPL (#359).
45-
const buildTagger = template(
46-
`
47-
(function () {
48-
var reactHotLoader = require('react-hot-loader').default;
49-
var leaveModule = require('react-hot-loader').leaveModule;
5054

55+
const buildTagger = template(
56+
`
57+
(function () {
58+
59+
var reactHotLoader = (typeof reactHotLoaderGlobal !== 'undefined' ?reactHotLoaderGlobal : require('react-hot-loader')).default;
60+
5161
if (!reactHotLoader) {
5262
return;
5363
}
5464
55-
REGISTRATIONS
56-
57-
leaveModule(module);
65+
REGISTRATIONS
5866
}());
5967
`,
6068
templateOptions,
@@ -151,12 +159,18 @@ module.exports = function plugin(args) {
151159
registrations.length &&
152160
!shouldIgnoreFile(file.opts.filename)
153161
) {
154-
node.body.unshift(headerTemplate())
162+
if (safetyNet) {
163+
node.body.unshift(headerTemplate())
164+
}
155165
// Inject the generated tagging code at the very end
156166
// so that it is as minimally intrusive as possible.
157167
node.body.push(t.emptyStatement())
158168
node.body.push(buildTagger({ REGISTRATIONS: registrations }))
159169
node.body.push(t.emptyStatement())
170+
171+
if (safetyNet) {
172+
node.body.push(footerTemplate())
173+
}
160174
}
161175
},
162176
},

0 commit comments

Comments
 (0)