Closed romseguy closed 7 years ago
Yeah, I can see the split can be problematic. Perhaps we need to go through loaders instead? In this case you would resolve against React at the test and use imports-loader to inject react-dom
. You can likely set up an alias for react-dom
too in order to use the minified version for that as well.
I haven't tried this approach yet but it would be the first thing for me to try. If you get it work this way, let me know. :+1:
im also hitting this problem. is there a definite solution yet?
@NickStefan I might try setting up some separate task to generate a minified version based on the bits you need (minify in development mode to retain type checks!). The minified bundle would then contain React core and react-dom. Of course this implies extra work but it might be a direction worth investigating.
@bebraw thanks for the quick answer! I set up a separate task, and added aliases for react and reactDom
var pathToReactMin = path.resolve(node_modules, 'react/dist/react.min.js');
var pathToReactDomMin = path.resolve(node_modules, 'react/lib/ReactDOM');
works. thanks.
:+1:
React has a 'release' version for react-dom as well:
var pathToReactMin = path.resolve(node_modules, 'react/dist/react.min.js');
var pathToReactDomMin = path.resolve(node_modules, 'react-dom/dist/react-dom.min.js');
@NickStefan, I wound up using resources already included with the React NPM distribution:
// ...
var reactPath = path.join(modulesPath, 'react', 'react.js')
, reactDOMPath = path.join(modulesPath, 'react', 'lib', 'ReactDOM.js')
, reactCSSTransitionGroupPath = path.join(modulesPath, 'react', 'lib', 'ReactCSSTransitionGroup.js');
// ...
module.exports = {
// ...
entry: {
// ...
vendors: [
'react'
, 'react-dom'
, 'react-addons-css-transition-group'
]
},
resolve: {
alias: {
'react': reactPath,
'react-dom': reactDOMPath,
'react-addons-css-transition-group': reactCSSTransitionGroupPath
}
}
// ...
}
Open to criticism.
@michaelahlers I have the same problem and was solved by your approach of 'react/lib/ReactDOM' but why official React page says to install: "npm install --save react react-dom" when later we provide ReactDOM through /react/lib/ReactDOM ? In that case I can just remove the node_modules/react-dom
@TrkiSF2, because that documentation makes assumptions that don't hold true in these webpack configurations.
Look inside those NPM modules. Specifically, for this scenario, see index.js
in react-dom
and react-addons-css-transition-group
respectively:
module.exports = require('react/lib/ReactDOM');
module.exports = require('react/lib/ReactCSSTransitionGroup');
These modules aren't providing resources—they're essentially references back to the react
package contents, which I've effectively duplicated in my webpack alias
configuration.
It's obviously a hack, and can't possibly be best practice.
I know, was looking there. At the beginning I wanted to try something like:
join(
'node_modules',
'react-dom',
'index.js',
which would be cleaner imo but didn't work. Well for now I am keeping it the way you proposed.
They're referencing react-dom back to the original react repro to get you used to the package separation, until they can actually separate them out. The API changed before the underneath did. Deprecation vs outright dropping APIs. Once the packages are actually more separate, I imagine it will be less weird with the aliasing in webpack.
I have this webpack.config.js but I still get a Undefined: require is not defined error in react-dom.js
when running npm run dev
.
Is there something wrong with my setup?
var path = require('path');
var webpack = require('webpack');
var node_modules = path.resolve(__dirname, 'node_modules');
var react_path = path.resolve(node_modules, 'react/dist/react');
var react_dom_path = path.resolve(node_modules, 'react/lib/ReactDOM');
module.exports = {
entry: [...],
resolve: {
alias: { 'react': react_path, 'react-dom': react_dom_path }
},
output: {...},
module: {
loaders: [...],
noParse: [react_path, react_dom_path]
}
};
@aabanaag I got that too. Seems like different things are in conflict. Once you alias 'react' to 'react.min.js', the underlying require('react/lib/ReactDOM') in 'react-dom' becomes relative to 'react.min.js', which breaks when building. But if you alias 'react-dom' to 'react-dom.min.js' and noParse it as usual, the require('react') in 'react-dom.min.js' won't be converted to a webpack_require call, so that breaks in the browser. @michaelahlers doesn't include noParse in his code snippet, so maybe he didn't hit that.
It seems to work if you alias 'react' and 'react-dom' to their 'dist/[name].min.js' copies, but only noParse 'react', so that the require('react') in 'react-dom.min.js' gets processed by Webpack and turned into a webpack_require call to get React.
It's fairly verbose, but something like:
var alias = {
'react': 'react/dist/react.min.js',
'react-dom': 'react-dom/dist/react-dom.min.js'
};
Object.keys(alias).forEach(function(name) {
alias[name] = path.resolve(path.join(__dirname, 'node_modules', alias[name]));
});
var noParse = ['react'].map(name => alias[name]);
All 'react-dom.min.js' does it require React and return its __SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED property, which is a reference to ReactDOM. It's a really small file, so taking it out of noParse shouldn't really matter.
@chrispesto But how about using production version and not the minified one. Does it apply too?
@aabanaag You mean 'react-dom.js' instead of 'react-dom.min.js'? Yes, you'd still need to remove it from the noParse, because it has require('react').
You can expose React as a global variable using expose-loader (npm i expose-loader --save-dev)
module = {
loaders: [{
test: path_to_your_react_min_location,
loader: "expose?React"
}]
}
Then based on @chrispesto approach then noParse variable would be like this
var noParse = Object.keys(alias).map(name => alias[name]);
same issue here, Undefined: require is not defined error in react-dom.js
@chrispesto thank you! Works great for me, no extra build time really.
I'm going to close this as the book has drifted too much apart from the initial issue. It's possible I'll add something similar there. Thanks.
https://christianalfoni.github.io/react-webpack-cookbook/Optimizing-rebundling.html
Is there a way to prevent using the alias over the node_modules directory?