Material-ui: Using Material UI externalizing React with Webpack

Created on 4 Feb 2016  路  9Comments  路  Source: mui-org/material-ui

I'm working in a React component library. I already use React as external library, linking directly production version of React.

Now I'm using Material UI components, but I'm having problems because, for some reason, my final bundle already includes react, what makes my app doesn't work properly.

I realized that this error only happens if I use a Material UI component that imports a react add-on (like react-addons-pure-render-mixin).

In order to make easier reproduce this undesirable behavior I have created a project:

using-material-ui-webpack-externalizing-react

Maybe I鈥檓 losing something in my configuration files, but I think it could be a bug.

There is a similar issue about this subject (#262) but it's not the same. It's a request of a standalone version. I prefer to have MaterialUI as node package and make my own bundle, like in your examples.

Most helpful comment

Thanks @billyvg, it worked for me!

I checked in dependencies of package.json of Material UI and my webpack externals finally looks like:

module.exports = {
    externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
        'react-addons-transition-group': 'React.addons.TransitionGroup',
        'react-addons-pure-render-mixin': 'React.addons.PureRenderMixin',
        'react-addons-create-fragment': 'React.addons.createFragment',
        'react-addons-update': 'React.addons.update'
    }
}

I also don't know if it's the best solution, but at least there's a workaround.

What I don't like too much of this solution is that I need to take care updating future versions of Material UI that may depend on other React addons (maybe a new one), to put it in external libraries of webpack.

Perhaps other libraries like Material UI are facing same problem. I think it's very usual to externalize this kind of libraries and also it's very usual that a library depends on others (like Material UI and React and ReactAddons)

Does anyone know a better solution?

EDIT:

Previous config file was not working well because I have React Addons loaded directly on window, I load it before any module loader.

React and ReactDOM were working well because they are simple paths that webpack resolve like root['React'] where root is window. Obviously when it tries to resolve root['React.addons.update'] it returns undefined.

Looking webpack docs I found a solution. Correct config JSON in this case is:

module.exports = {
    externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
        'react-addons-transition-group': 'var React.addons.TransitionGroup',
        'react-addons-pure-render-mixin': 'var React.addons.PureRenderMixin',
        'react-addons-create-fragment': 'var React.addons.createFragment',
        'react-addons-update': 'var React.addons.update'
    }
}

All 9 comments

I'm also having this problem, I'm not sure if this is the best solution but I added react-addons-transition-group and react-addons-pure-render-mixin to externals in webpack config.

module.exports = {
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
    'react-addons-transition-group': 'React.addons.TransitionGroup',
    'react-addons-pure-render-mixin': 'React.addons.PureRenderMixin',
  },
};

Thanks @billyvg, it worked for me!

I checked in dependencies of package.json of Material UI and my webpack externals finally looks like:

module.exports = {
    externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
        'react-addons-transition-group': 'React.addons.TransitionGroup',
        'react-addons-pure-render-mixin': 'React.addons.PureRenderMixin',
        'react-addons-create-fragment': 'React.addons.createFragment',
        'react-addons-update': 'React.addons.update'
    }
}

I also don't know if it's the best solution, but at least there's a workaround.

What I don't like too much of this solution is that I need to take care updating future versions of Material UI that may depend on other React addons (maybe a new one), to put it in external libraries of webpack.

Perhaps other libraries like Material UI are facing same problem. I think it's very usual to externalize this kind of libraries and also it's very usual that a library depends on others (like Material UI and React and ReactAddons)

Does anyone know a better solution?

EDIT:

Previous config file was not working well because I have React Addons loaded directly on window, I load it before any module loader.

React and ReactDOM were working well because they are simple paths that webpack resolve like root['React'] where root is window. Obviously when it tries to resolve root['React.addons.update'] it returns undefined.

Looking webpack docs I found a solution. Correct config JSON in this case is:

module.exports = {
    externals: {
        'react': 'React',
        'react-dom': 'ReactDOM',
        'react-addons-transition-group': 'var React.addons.TransitionGroup',
        'react-addons-pure-render-mixin': 'var React.addons.PureRenderMixin',
        'react-addons-create-fragment': 'var React.addons.createFragment',
        'react-addons-update': 'var React.addons.update'
    }
}

@vasconita It works, thank you !

@vasconita After some hours , finally works . thanks :+1:

@vasconita This is great but the last problem I'm running into is dealing with Material UI's react-tap-event-plugin dependency. It patches the react libs directly, which is blocking me from fully externalizing. Did you find a way around that?

@sanjayp that means, if you externalize with the current code some things will be broken because react-tap-event-plugin is not included?

@ricardopolo It's slightly more complicated than that. In order to work in the first place, react-tap-event-plugin directly patches the react lib in a way that is not reproducible with the react CDN dependency (because it's bundled and only exposes the public API). This effectively prevents someone from using material-ui while also externalizing the react dependency.

I have since refactored material ui out of my codebase so I can't speak to whatever the most recent version may be, but I doubt it's changed.

@vasconita do you have any comments about what @sanjayp says? Should we re open the issue?

Anyone knows specifically which components use that plugin to know what we should not use?

Thanks!

@sanjayp have you been able to solve that? because I just ran into that issue.

Was this page helpful?
0 / 5 - 0 ratings