Closed bkniffler closed 9 years ago
I just discovered the bootstrap you provided https://github.com/gaearon/react-transform-boilerplate and it seems to work. I'll check whats different on my end.
Seems like my https://github.com/reactjs/express-react-views templates are causing these errors with react-transform-hmr.
Please provide a project reproducing the problem.
Otherwise it's hard to guess why module.hot
isn't available.
One thing to look out for is that you shouldn't transform node_modules
with babel-loader
.
Transform just your code with include
option on the loader.
I'm having this too.
"react-transform-webpack-hmr"
doesn't have it though.
Its because of the recent changes in version 1.0.0. And for me it seems like the problem appears since, as @gaearon supposed, I got files in custom modules that are transformed by babel-loader
.
@gaeron i have same error but completed your recommendations.
Repo:
https://github.com/MrEfrem/react-redux-starter-kit
Execute app:
npm run compile && npm run server:start
Out in console:
...
[2] /home/user/react-redux-starter-kit/dist/server/index.js:1269
[2] k like React.');}if(!hot || typeof hot.accept !== 'function'){throw new Error(
[2] ^
[2] Error: locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr
[2] at proxyReactComponents (/home/user/react-redux-starter-kit/dist/server/index.js:4574:12)
[2] at Object.<anonymous> (/home/user/react-redux-starter-kit/dist/server/index.js:14774:65)
[2] at Object.module.exports.Object.defineProperty.value (/home/user/react-redux-starter-kit/dist/server/index.js:14827:31)
[2] at __webpack_require__ (/home/user/react-redux-starter-kit/dist/server/index.js:21:30)
[2] at Object.module.exports.Object.defineProperty.value (/home/user/react-redux-starter-kit/dist/server/index.js:14918:27)
[2] at __webpack_require__ (/home/user/react-redux-starter-kit/dist/server/index.js:21:30)
[2] at Object.<anonymous> (/home/user/react-redux-starter-kit/dist/server/index.js:14685:16)
[2] at __webpack_require__ (/home/user/react-redux-starter-kit/dist/server/index.js:21:30)
[2] at Object.<anonymous> (/home/user/react-redux-starter-kit/dist/server/index.js:71:19)
[2] at __webpack_require__ (/home/user/react-redux-starter-kit/dist/server/index.js:21:30)
[2] npm
[2]
[2] ERR! Linux 3.16.7-24-desktop
[2] npm
[2] ERR!
[2] argv "/usr/bin/node" "/usr/bin/npm" "run" "server:start" "--" "--nw"
[2] npm ERR!
[2] node v0.12.7
[2] npm ERR! npm v2.11.3
[2] npm ERR! code ELIFECYCLE
[2] npm ERR!
[2] bankdocs-js@0.13.0 server:start: `node --harmony bin/server "--nw"`
[2] npm
[2] ERR! Exit status 1
[2] npm ERR!
...
Don't enable the transform in the Node server build. Most other React Transforms don't expect to be invoked on server either so it's good to fail early.
@gaearon Why can't one use babel in webpack configuration? Is it prohibited somewhere?
I'm not sure I understand the question.
You can configure Babel plugin either in .babelrc with env option (corresponds to BABEL_ENV or NODE_ENV, whichever is set), or in your build tool setup (for example babel-loader for Webpack lets you pass configuration as an object to "query" field).
my locals
array looks like this:
@@@@@@@@@@@@ [ { id: 'G:\\work\\cinema\\code\\client\\html.js',
exports: { __esModule: true },
parent:
{ id: 'G:\\work\\cinema\\code\\server\\webpage rendering.js',
exports: [Object],
parent: [Object],
filename: 'G:\\work\\cinema\\code\\server\\webpage rendering.js',
loaded: false,
children: [Object],
paths: [Object] },
filename: 'G:\\work\\cinema\\code\\client\\html.js',
loaded: false,
children: [ [Object], [Object], [Object], [Object] ],
paths:
[ 'G:\\work\\cinema\\code\\client\\node_modules',
'G:\\work\\cinema\\code\\node_modules',
'G:\\work\\cinema\\node_modules',
'G:\\work\\node_modules',
'G:\\node_modules' ] } ]
Is it good?
It's the error i get when running the server.
I guess hot module replacement is not intended for use on the server.
But .babelrc
should be uniform therefore it's a single file.
You should fix this plugin to not run on the server while there is NODE_ENV = development
My solution is as follows:
{
"stage" : 0,
"optional" : "runtime",
"loose" : "all",
"plugins":
[
"typecheck"
],
"env":
{
"development/client":
{
"plugins":
[
"typecheck",
"react-transform"
],
"extra":
{
"react-transform":
[{
"target" : "react-transform-hmr",
"imports" : ["react"],
"locals" : ["module"]
}]
}
}
}
}
configuration.plugins = configuration.plugins.concat
(
// environment variables
new webpack.DefinePlugin
({
'process.env':
{
NODE_ENV: JSON.stringify('development'),
BABEL_ENV: JSON.stringify('development/client')
},
...
With this configuration it works, but they've made a mistake by using JSON instead of Javascript in their .babelrc
file.
With this configuration it works, but they've made a mistake by using JSON instead of Javascript in their .babelrc file.
Maybe, but that would be up to Babel. Maybe you can file an issue there (unless one already exists).
@gaearon Nah, they obviously won't listen to a stranger with no history of commits. The thing is Babel requires Node.js so why not make the configuration non-declarative like they did in Webpack.
By the way, I didn't find a way to stop Babel from loading the default .babelrc, so my approach with custom .babelrc.server didn't work. The custom BABEL_ENV is the only one that worked.
If you use Webpack on client, you can put React Transform configuration there. For example see this React Native example using babel-loader
's configuration query
field. This way you can share .babelrc
between client and server.
@gaearon hmmm, actually, that would be a better solution. I'll use it.
That's really strange.
After running some test cases it looks like this error appears wherever I use any babel-related stuff on the server, like require('babel/register')
. I didn't even start nor webpack-dev-server
nor webpack-dev-middleware + webpack-hot-middleware
, just bare express
instance that is intended to run React
on the server-side.
It's really confusing that example at Readme recommends not-the-best(bulletproof?) way.
Anyway, @halt-hammerzeit, @gaearon, thanks for discussion, I have everything up and running now.
I suggest to add some clarification about how to use this plugin with projects that heavily rely on server-side (I mean universal apps here too).
@aulizko yes, that's a new feature of babel so I recommend removing .babelrc
way from the README
http://babeljs.io/blog/2015/03/31/5.0.0/#babelrc
It's really confusing that example at Readme recommends not-the-best(bulletproof?) way.
You can always make a PR to recommend the right way. :wink: Open source projects need help, especially in documentation.
@gaearon but there's always the project owner factor where the project owner should say "yes, do it" otherwise noone's gonna merge your PR. so I woudn't submit such a PR blindly. if the project owner says "aaah, that's actually a good idea, username!" only then a stranger should start thinking about contributing.
@gaearon by the way you've got a bunch of cool projects here. not Holowaychuk level of course but still a lot of development efforts. so that you know we appreciate your contribution to the progression of society.
@gaearon I think you are awesome. Whatever level that is.
I believe the change itself is for the better so that's why I released it. However configuring Babel is something you know better than me: you have real apps with different requirements and you are a better judge of how to make this change work in your project and what best practices are. That's what I'm trying to say: I can't document the best approach because I don't know it. If you know a better approach than the docs say, submit a PR and let's discuss it.
okay, I propose some kind of this textual addition to the readme:
## React
If you're rendering React both on client and server then you should add `react-transform` plugin to your `babel-loader` configuration
...
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
stage: 0,
plugins: []
}
},
...]
},
...
// enable React Hot loader
if (process.env.HOT) {
config.module.loaders[0].query.plugins.push('react-transform');
config.module.loaders[0].query.extra = {
'react-transform': [{
target: 'react-transform-hmr',
imports: ['react'],
locals: ['module']
}]
};
}
Otherwise, if you're not using React on server side, you can just edit your .babelrc to include extra.babel-plugin-react-transform.
...
That's my idea of updating the Readme but most likely you'll want to change this somehow.
that's not working for me, I have a webpack config especial for HMR
{
devtool: 'eval',
entry: [
'webpack-hot-middleware/client',
'./client.js'
],
output: {
path: path.join(__dirname, 'public/js/'),
filename: 'bundle.js',
publicPath: '/js/'
},
module: {
loaders: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel',
query: {
stage: 0,
plugins: [
'react-transform'
],
extra: {
'react-transform': [{
target: 'react-transform-hmr',
imports: ['react'],
locals: ['module']
}]
}
}
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
progress: true,
resolve: {
extensions: ['', '.js', '.jsx']
}
}
and my .babelrc
{
"stage": 0,
"loose": [
"es6.modules",
"es6.classes",
"es7.classProperties"
],
"optional": [ "es7.classProperties", "es7.exportExtensions" ],
"env": {
"development": {
"plugins": ["react-transform"],
"extra": {
"react-transform": [{
"target": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"target": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}
}
still getting
/Users/erik/towbook/isomorphic-app-hmr/node_modules/react-transform-hmr/lib/index.js:51
throw new Error('locals[0] does not appear to be a `module` object with Hot Module ' + 'replacement API enabled. You should disable react-transform-hmr in ' + 'production by using `env` section in Babel configuration. See the ' + 'example in README: https://github.com/gaearon/react-transform-hmr');
^
Error: locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr
at Object.proxyReactComponents [as default] (/Users/erik/towbook/isomorphic-app-hmr/node_modules/react-transform-hmr/lib/index.js:51:11)
at Object.<anonymous> (/Users/erik/towbook/isomorphic-app-hmr/components/Nav.jsx:4:36)
at Module._compile (module.js:434:26)
at normalLoader (/Users/erik/towbook/isomorphic-app-hmr/node_modules/babel/node_modules/babel-core/lib/api/register/node.js:199:5)
at Object.require.extensions.(anonymous function) [as .jsx] (/Users/erik/towbook/isomorphic-app-hmr/node_modules/babel/node_modules/babel-core/lib/api/register/node.js:216:7)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/Users/erik/towbook/isomorphic-app-hmr/components/Application.jsx:23:1
@eriknyk so you don't have .babelrc
file in your project?
I have it, that why it is confusing me, I need setup both or just one?
my .babelrc
{
"stage": 0,
"loose": [
"es6.modules",
"es6.classes",
"es7.classProperties"
],
"optional": [ "es7.classProperties", "es7.exportExtensions" ],
"env": {
"development": {
"plugins": ["react-transform"],
"extra": {
"react-transform": [{
"target": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"target": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}
}
@eriknyk yep what? do you have .babelrc
in your project or you don't?
I have a .babelrc file on my project
@eriknyk delete it and try to run your project again. then tell me that it works now.
this is my example proj.
@eriknyk see my comment above ^^^
@halt-hammerzeit it worked, thanks you!
delete it and try to run your project again. then tell me that it works now.
but it means that now we can't use .babelrc? ... I was using it and everything was working fine before,.. after I updated the reference when react-transform-webpack-hmr was renamed to react-transform-hmr, it stops working.
Best regards.
@eriknyk you can still use .babelrc
as long as you don't enable react-transform-hmr
plugin there.
the root cause is that when you do require('babel/register')
in your server-side code it loads .babelrc
and if react-transform-hmr
is enabled there then it enables react-transform-hmr
on the server where there's no "hot reload" hence the error.
ok, thank you for your answers @halt-hammerzeit
@eriknyk, @halt-hammerzeit, @gaearon
I spent a day thinking about this problem with .babelrc
and now I think that it's actually good that we can't store hmr
plugin config inside of .babelrc
.
Think yourself: it actually make sence to store your configuration inside your webpack/browserify config so that it explicitely tells you what is going on with your development/production build in one place.
And it was by far not so good when we have to store half of the configuration inside of webpack.config.js
and other half inside the different file like .babelrc
. I mean it should be really confusing for a new member of the team when he would try to grok project structure. Like webpack.config.js
contains webpack-hot-middleware/client
, but other half of the hot-reload contains in the .babelrc
. Not-intuitive, error-prone solution, I think.
But now it is good.
You should store everything about your development configuration inside of webpack.config.js
. And .babelrc
would keep only all-project-related configuration for babel. Like, I dunno, stage: 0
.
It is always good to have one and only one file that contains all configuration details for one domain-specific problem. IMO.
what he said ^^^^^
Great input, thanks for the suggestion concerning the webpack.config.js and deleting .babelrc, it works perfectly for my dev environment.
module: {
loaders: [
{
test: /\.js$|\.jsx$|\.es6$|\.babel$/,
loader: 'babel',
query: {
stage: 0,
plugins: ['react-transform'],
extra: {
"react-transform": [{
"target": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"target": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}]
}
Confirming that killing the .babelrc
file in favor of configuring in the webpack babel loader fixes the issue. The config format changed a little bit since @bkniffler posted above, so here's what a working setup currently looks like:
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel',
include: path.join(process.cwd(), config.root.src, config.tasks.js.src), // wherever your source js lives
exclude: /node_modules/,
query: {
"stage": 0,
"plugins": ["react-transform:after"],
"extra": {
"react-transform": {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}
}
]
}
UPDATE: Added :after
to "plugins": ["react-transform:after"]
See https://github.com/gaearon/babel-plugin-react-transform/issues/19#issuecomment-147755452 for details.
thanks @greypants
Sorry @greypants your webconfig did not work for me, but @bkniffler's did work fine.
Why was your config using react-transform:after
instead of react-transform
?
My example of using react-transform based on @gaearon's example. This works well in prod and dev, with different webconfig
and a different express server for dev and prod.
Thanks for your help @halt-hammerzeit, I also agree that this better alternative version of running react-transform-hmr should be updated in the README, I am happy to add a PR.
@StevenIseki without :after
, class names are lost in the debug output, and instead you'll see ProxyClass
everywhere (detailed in the issue I referenced in my comment). The config I posted is for the latest versions. Syntax changed a bit. Also be sure to replace include
and exclude
with your own paths (or remove them altogether—they're optional). The ones in that config are specific to my setup.
Thanks for the tip on the classes @greypants that makes sense now. It was more likely the include, exclude which caused the error.
Things changed with babel6
. I still have this problem with babel@6.4
, babel-plugin-react-transform@2.0
and react-transform-hmr@1.0.1
.
Things changed with babel6. I still have this problem with babel@6.4, babel-plugin-react-transform@2.0 and react-transform-hmr@1.0.1.
What exactly changed? The problem is that you're either enabling the transform in environments other than development, or you are compiling for production with a dev/empty environment. This was the cause of the problem before, and it is the cause of the problem now. How did this change?
@gaearon wow, I have this problem because I comment // new webpack.HotModuleReplacementPlugin()
:joy: So it's all right besides query: {stage:0, xxx}
is not valid setting with babel6
.
However, I found my app wont update even there is log:
[WDS] Hot Module Replacement enabled.
[WDS] App updated. Recompiling...
[WDS] App hot update...
[WDS] App updated. Recompiling...
[WDS] App hot update...
Hi, try this: webpack.config.js: devServer: { historyApiFallback: true, inline: true, hot: true, progress: true } and package.json: "scripts": { "dev": "webpack-dev-server --progress --hot --profile --colors" }
hot is the key.
None of this should matter in React Hot Loader 3. I know React Transform has been a configuration hell; hopefully, this should be solved. See https://github.com/gaearon/react-hot-boilerplate/pull/61 if you’d like to try it!
Hi, I've installed 1.0.0, I've copy&pasted .babelrc from the examples and I'm using babel-loader with webpack as adviced, all in my dev environment, but I'm getting said error as soon as I'm running the whole thing. Whereas, the previous version worked.
Is there anything not yet documented I'm missing?