Skip to content

Commit

Permalink
fix: opt-out for module safety net, fixes #1102, #1159
Browse files Browse the repository at this point in the history
  • Loading branch information
theKashey committed Jan 26, 2019
1 parent 24d0448 commit 93d0b1f
Show file tree
Hide file tree
Showing 3 changed files with 2,048 additions and 11 deletions.
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,28 @@ setConfig({

Mark a component as hot.

#### Babel plugin

Right now babel plugin has only one option, enabled by default.

* `safetyNet` - will help you properly setup ReactHotLoader.

You may disable it to get more control on the module execution order.

```js
//.babelrc
{
"plugins": [
[
"react-hot-loader/babel",
{
"safetyNet": false
}
]
]
}
```

#### Important

**!!** Use `hot` only for module `exports`, not for module `imports`. **!!**
Expand Down
36 changes: 25 additions & 11 deletions src/babel.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const shouldIgnoreFile = file =>
.match(/node_modules\/(react|react-hot-loader)([\/]|$)/)
/* eslint-enable */

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

const { safetyNet = true } = options

const buildRegistration = template(
'reactHotLoader.register(ID, NAME, FILENAME);',
templateOptions,
)
const headerTemplate = template(
`(function () {
var enterModule = require('react-hot-loader').enterModule;
var enterModule = (typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal : require('react-hot-loader')).enterModule;
enterModule && enterModule(module);
}())`,
templateOptions,
)
const footerTemplate = template(
`(function () {
var leaveModule = (typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal : require('react-hot-loader')).leaveModule;
leaveModule(module);
}())`,
templateOptions,
)
const evalTemplate = template('this[key]=eval(code);', templateOptions)

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

const buildTagger = template(
`
(function () {
var reactHotLoader = (typeof reactHotLoaderGlobal !== 'undefined' ?reactHotLoaderGlobal : require('react-hot-loader')).default;
if (!reactHotLoader) {
return;
}
REGISTRATIONS
leaveModule(module);
REGISTRATIONS
}());
`,
templateOptions,
Expand Down Expand Up @@ -151,12 +159,18 @@ module.exports = function plugin(args) {
registrations.length &&
!shouldIgnoreFile(file.opts.filename)
) {
node.body.unshift(headerTemplate())
if (safetyNet) {
node.body.unshift(headerTemplate())
}
// Inject the generated tagging code at the very end
// so that it is as minimally intrusive as possible.
node.body.push(t.emptyStatement())
node.body.push(buildTagger({ REGISTRATIONS: registrations }))
node.body.push(t.emptyStatement())

if (safetyNet) {
node.body.push(footerTemplate())
}
}
},
},
Expand Down
Loading

0 comments on commit 93d0b1f

Please sign in to comment.