Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Browserifying react with addons to a standalone component, usable by plugins

I am experementing a bit with react and browserify and have these wishes:

  • I want to bundle all code written by me into a single file
  • I want to bundle all 3rd party dependencies (react, react-router, lodash etc) into separate files, one for each lib, to maximize caching possibilities

I have managed to do the things described above but I ran into this specific situation:

In some places of my code I want to use react with addons and as such require it like this: var React = require('react/addons). I don't do this in all parts of my code and it is not done in 3rd party dependencies such as react-router. This seems to create a conflict. Either the browserified bundle will only be available through var React = require('react/addons) which breaks 3rd party dependencies, or I will have to bundle react both with or without addons which menas that react is bundled and downloaded twice.

I tried to use aliasify and make react an alias for react/addons but I couldn't make it work. Should this be possible?

Another acceptable solution would be to bundle just the addons in a separate bundle and through that make both react and react/addons available through calls to require. Is any of this possible?

Addition As a comment to the first comment by BrandonTilley, this is not just applicable to React and addons. Lodash also comes with a number of different distributions and I would like to be able to choose the version to use in my webapp in this case as well.

like image 890
Ludwig Magnusson Avatar asked Sep 09 '14 17:09

Ludwig Magnusson


1 Answers

Notice that what you want to achieve is documented here: Browserify partitionning

I'm packaging my app in 2 parts: appLibs.js and app.js. I've done this for caching too but I choose to put all the code that does not change often in a single bundle instead of splitting it like you want, but you can use the same trick.

Here's the code that might interest you:

var libs = [
    "react",
    "react/addons", // See why: https://github.com/substack/node-browserify/issues/1161
    ... other libs
];

gulp.task('browserify-libs', function () {
    var b = browserify(...);
    libs.forEach(function(lib) {
        b.require(lib);
    });
    return b.bundle().......
});
gulp.task('browserify',['browserify-libs'],function () {
    var b = browserify(...);
    libs.forEach(function(lib) {
        b.external(lib);
    });
    return b.bundle().......
});

This way, React is only bundled once in appLibs.js and can be required inside app.js using both react and react/addons

If you really want to bundle your libs in separate files, bundle then with b.require("myLib"), but in this case be sure to check that the libraries do not have direct dependencies. If a lib to bundle has a dependency in React, this means that lib will be packaged in the bundle, potentially leading to multiple bundles having React inside them (and making weird failures at runtime). The library should rather use peerDependencies so that b.require does not try to package these dependencies

like image 113
Sebastien Lorber Avatar answered Oct 28 '22 02:10

Sebastien Lorber