Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building multiple bundles #40

Closed
gabegorelick opened this issue Apr 7, 2014 · 48 comments
Closed

Building multiple bundles #40

gabegorelick opened this issue Apr 7, 2014 · 48 comments
Assignees

Comments

@gabegorelick
Copy link

browserify-shim is giving me some trouble trying to build multiple bundles. I don't see any documentation on building multiple bundles, so it might be a usecase that hasn't been fleshed out yet.

I'm trying to build 2 bundles: a libs bundle containing 3rd-party libraries that need to be shimmed, and an app bundle containing my application code. I want to be able to, for example, require('angular') from app, even though angular is defined in libs. "exports": "global:angular" should solve this, but I think it's running into trouble since browserify-shim is running twice. When it runs on libs, it needs angular to "exports": "angular", but when it runs on app, it needs to use global.

It seems like global is designed for use with script tags, but not external bundles. But there doesn't seem to be another way to reference external bundles.

@thlorenz thlorenz self-assigned this Apr 7, 2014
@thlorenz
Copy link
Owner

thlorenz commented Apr 7, 2014

I'm sorry you are running into trouble, this is indeed a use case I haven't thought of.
So far (as you can also see from the tests) only single bundle cases were considered.

Since only a single config is supported right now it wouldn't know what part of it to apply to which bundle. Possibly we could allow a way to supply multiple configs? ala:

{ 
  "browserify-shim": {
    "@bundle-foo": {
      "angular": "global:angular"
   },
   "@bundle-foo": {
      "./vendor/jquery": "$"
   }
}

It would be very helpful if you could create a sample project on github and note in the readme how you would like it to work and what it does instead.

@gabegorelick
Copy link
Author

What if I manually run the browserify-shim transform? Could you pass the config that way?

@thlorenz
Copy link
Owner

thlorenz commented Apr 7, 2014

That would be another option, but is not possible ATM.
We'd need to change the API and some other things accordingly.

That's why a sample project to play with in order to figure this out would be very helpful and much appreciated.

@gabegorelick
Copy link
Author

Not sure what to put in a sample project. It's pretty much just browserify with multiples bundles. That's described in a bunch of places, including here. Only difference is most examples use grunt-browserify with its shim option. I guess that provides a way to have multiple browserify-shim configs. I'm using a combination of browserify-middleware (in development, instead of a watcher) and calling browserify manually in a gulp build.

@gabegorelick
Copy link
Author

I should add that so far, browserify-shim has served me quite well (thanks for that 😄). It just can't split my source up into multiple browserify bundles, which seems to be standard operating procedure for browserify once your code grows to a certain size.

@thlorenz
Copy link
Owner

thlorenz commented Apr 7, 2014

Not sure what to put in a sample project

Just put the minimum of code that reproduces your problem.

It's pretty much just browserify with multiples bundles

yeah, but if you supply me with a working repro case it'll be much easier for me to get started trying to figure out how to solve your problem

@gabegorelick
Copy link
Author

Here you go. This is a sample project that uses browserify-shim to shim angular and angular-resource. For another potential monkey wrench, angular depends on jquery, which is already a CommonJS module.

Currently, all JS in this sample is bundled into /public/app.js by browserify-middleware, and that works fine. What we need is a way to exclude angular, angular-resource, and jquery from that bundle, and instead bundle them up into libs.js. browserify-middleware supports multiple bundles, so that's not an issue.

@thlorenz
Copy link
Owner

That is a good start, but I'm still waiting for you to add the actual build script you are using to the repo.
Please respect my time and if you really want something to get fixed help me as much as you can.

An empty gulp.js file is not gonna cut it.

Ideally everything is prepared and I can repro the problem with one simple command, i.e. npm test.
I honestly don't have the time to guess what you were doing and how you are building things.

Thanks.

@gabegorelick
Copy link
Author

I apologize if I'm wasting your time. That's not my intention and I appreciate your taking the time to implement this.

I skipped the gulpfile because it's not needed to run browserify, that's handled by browserify-middleware at runtime. You could of course, do it in the build instead, but I just copied my current setup.

If you want a test case, well I'm not sure what the API for this feature should be, since it's apparently not implemented. For example, should global be used to resolve dependencies from outside modules, or should a new keyword be introduced? Or do you want to tackle passing options directly to the transform function?

@thlorenz
Copy link
Owner

All I need actually is the build script you are running so I can see why it fails.
I didn't mean for you to implement or guess an API.

Just allow me to do something similar to the below to see the problem:

git clone your/reprocase && cd reprocase
npm install
npm test

Thanks.

@gabegorelick
Copy link
Author

Gotcha. So you don't need like a full-on Karma test? Just enough to open a browser and get an error?

@thlorenz
Copy link
Owner

Exactly!
Sorry if we misunderstood each other. I just wanna help you with your problem, but was unable until now since I didn't have enough info to repro it.

@gabegorelick
Copy link
Author

No worries. I just updated the repo. The original commit is with everything working using a single bundle. The second commit tries to move the libs into a separate bundle. The weird thing is, it looks like it's working now. Using external seems to be good enough.

I'll have to do some digging to see why it doesn't work on my other project. Maybe something about the specific deps it's using.

@gabegorelick
Copy link
Author

OK. It looks like it's currently complaining about d3 not being defined. I added a few more deps to the sample project to showcase this. You can run it with npm run test. Note that I just tested it, and everything works if it's in one bundle (i.e. you comment out external and don't load libs.js).

@thlorenz
Copy link
Owner

Thanks will have a look in conjunction with the other issue I linked above.
Seems like the issues are related.

@humidair1999
Copy link

Hey @gabegorelick, not to hijack this thread and steer it away from browserify-shim, but I was actually after the same end goal as you, separate bundles for libs versus app code, and ended up being able to achieve it via a combination of a prebundle process, alias, and the external options.

Here's an example of my tasks (it's from a gruntfile using grunt-browserify, but the logic is identical to gulp functionally):

grunt.initConfig({
    browserify: {
        libs: {
            src: './blank.js',
            dest: './public/js/built/libs.js',
            options: {
                preBundleCB: function(bundle) {
                    bundle.require('./bower_components/angular/angular.js');
                    bundle.require('./bower_components/angular-route/angular-route.js');
                }
            }
        },
        app: {
            src: './public/js/app.js',
            dest: './public/js/built/app.js',
            options: {
                alias: [
                    './bower_components/angular/angular.js:angular',
                    './bower_components/angular-route/angular-route.js:angular-route'
                ],
                external: [
                    './bower_components/angular/angular.js',
                    './bower_components/angular-route/angular-route.js'
                ]
            }
        }
    }
});

The two outputted files can then be included in your HTML page:

<script src="js/built/libs.js"></script>
<script src="js/built/app.js"></script>

Note that this doesn't use the shim at all; instead, it functions by synchronously requiring your modules into the bundle (sourced from an empty seed), providing external values to your app bundle to assure the libs don't get duplicated, and utilizing alias so you can use clean requires in your app code, such as:

require('angular');
require('angular-route');

If you actually NEED the shim for one reason or another, this might not be an option, but for most client-side libs without many dependencies, it works great, and might at least give you a starting place.

@gabegorelick
Copy link
Author

@jkymarsh Thanks for that. I considered doing something similar. The only problem, which you alluded to, is that it doesn't integrate browserify-shim. I could live with

require('angular');
var angular = window.angular;

although it's obviously not as nice as what browserify-shim gives you with exports. But I'd really miss shimming depends, e.g. that angular depends on jquery and angular-resource depends on angular. Without it, you have to order your require statements manually, which gives me flashbacks of the dark days of ordering script tags.

As an aside, I don't think you need prebundle (although if it works, go for it). You can use the require option instead. Also, see the official guide on multiple bundles.

@humidair1999
Copy link

Yeah, you're absolutely right about it requiring manual ordering of the require statements, which is a bummer.

It's a real shame; the shim situation with Browserify has frustrated me to the point where I might have to drop back to my old requirejs setup. I'm sure we all appreciate your work on the shim, @thlorenz, but it just doesn't seem like it's quite there yet, especially considering the grunt and gulp integrations, as well as the shim, keep updating and altering the way they integrate, making it difficult to use the newest versions.

Noted on the use of require also, @gabegorelick. Thanks!

@thlorenz
Copy link
Owner

doesn't seem like it's quite there yet

Depends on what there means for you @jkymarsh, but this is the first time that multi bundle shimming came up, so therefore also the first chance to get it fixed.
I don't think it's too far out, so bare with us we are doing our best to improve things ;)

However the fact that it didn't come up before makes me think that not too many users create multiple bundles when using browserify-shim (at least until now).
So this is just another feature that now seems to become important - previous ones were bower support, illegal require fixing, etc. which were all addressed ;)

I might have to drop back to my old requirejs setup

New use cases will come up all the time, so in that sense it will never be quite there since I cannot anticipate all of them. If that is a problem you should probably not use browserify-shim, otherwise you are welcome to help in moving things along and cover more use cases.

especially considering the grunt and gulp integrations

afaik grunt-browserify still uses browserify-shim v2 not sure about gulp, but in my experience whenever people wrap browserify and browserify-shim (both of which are perfectly configurable in package.json) inside a task runner, they are making their life a bit harder.

On another note, you could also consider pulling these large libs in from a CDN via a script tag and using the shim global feature as that should work already in either situation.

@gabegorelick
Copy link
Author

this is the first time that multi bundle shimming came up

Combining all libraries into a single bundle is what yeoman does with usemin last I checked (although they don't use browserify), so this kind of build is becoming more popular. It can make sense for big SPAs that use a lot of libs.

afaik grunt-browserify still uses browserify-shim v2 not sure about gulp

FWIW, gulp usually frowns on wrapping JS tools as plugins. The usual setup is just to call browserify() directly in your gulpfile. But that's a whole different issue.

@thlorenz
Copy link
Owner

@gabegorelick you need to read my comments more carefully

this is the first time that multi bundle shimming came up

was of course referring to multi bundles in the context of browserify-shim and not some other library that exists in the world.

At any rate please lets get back to the main reason for this thread and try to figure out how to make browserify-shim better instead of turning this into an argument about why it's not supported yet.

@gabegorelick
Copy link
Author

@thlorenz No disrespect, but maybe you should read my comments more carefully 😉 I was illustrating how this is actually a common thing, even if it's the first time shimming multiple bundles has been brought to your attention (see for another example all the blog posts illustrating multiple bundles with grunt-browserify).

At any rate please lets get back to the main reason for this thread and try to figure out how to make browserify-shim better instead of turning this into an argument about why it's not supported yet.

Agreed, let's stay focused. I opened #42 to track manually passing options to the transform function, as mentioned in my earlier comment.

@humidair1999
Copy link

Sorry, don't mean to keep the conversation off-track, but for the sake of posterity and anyone that stumbles across this going forward:

afaik grunt-browserify still uses browserify-shim v2

grunt-browserify actually completely removed the shim as of version 2.0.2, and doesn't provide any information on how to actually integrate it.

Didn't at all mean to be needlessly critical; it would have been more accurate for me to simply say "integration between all these tools seems to be a major pain point, especially across differing versions."

Thanks for the other tips, and again, thanks for your work on the shim!

@humidair1999
Copy link

Hey @gabegorelick, maybe I'm misunderstanding your exact issue, but I threw up a repo demonstrating the use of separate bundles with the shim:

https://github.com/jkymarsh/grunt-browserify-angular-boilerplate

It includes d3 and nvd3 as well, and it all works as expected.

Note that I did drop grunt-browserify and opt for running command-line commands via grunt-run instead; I suspect that grunt-browserify is adding complexity, especially with the shim, that's making it difficult to troubleshoot.

Let me know if that helps you at all, or if I'm totally misunderstanding your issue.

@gabegorelick
Copy link
Author

Cool. The only difference I can see is in the depends. You use, for
example, angular instead of angular:angular. @thlorenz should that make a
difference? My understanding is that it shouldn't.

On Sunday, April 13, 2014, J. Ky Marsh notifications@github.com wrote:

Hey @gabegorelick https://github.com/gabegorelick, maybe I'm
misunderstanding your exact issue, but I threw up a repo demonstrating the
use of separate bundles with the shim:

https://github.com/jkymarsh/grunt-browserify-angular-boilerplate

It includes d3 and nvd3 as well, and it all works as expected.

Note that I did drop grunt-browserify and opt for running command-line
commands via grunt-run instead; I suspect that grunt-browserify is adding
complexity, especially with the shim, that's making it difficult to
troubleshoot.

Let me know if that helps you at all, or if I'm totally misunderstanding
your issue.

Reply to this email directly or view it on GitHubhttps://github.com//issues/40#issuecomment-40326187
.

@thlorenz
Copy link
Owner

@jkymarsh thanks a lot for figuring this out, so it seems like browserify-shim is working as expected already and no changes are necessary?
Possibly however we should add some example/instructions to the readme and/or wiki.

@gabegorelick of course the way you set up depends matters. As you can see from here, if you have depends: 'x:y', that means that it depends on x and needs it to be exposed on the window as window.y.

@gabegorelick would you please confirm that this work and your issue is resolved? Otherwise please let me know what else is missing to fix your problem.

Thanks.

@gabegorelick
Copy link
Author

of course the way you set up depends matters. As you can see from here, if you have depends: 'x:y', that means that it depends on x and needs it to be exposed on the window as window.y.

Right, so angular:angular means we depend on angular being exposed on window.angular, which is what you want. I meant that in this case, the two are the same, since, and correct me if I'm wrong, depends: "angular" is shorthand for depends: "angular:angular". If they're not the same, than how could @jkymarsh's example possibly work?

@thlorenz
Copy link
Owner

@gabegorelick it could be that when requiring angular it already attaches itself to the window as angular. So the overall result would be the same.

You can see from here how the two cases get handled (first line depends: 'x:y', the other depends: 'x').

However I noted that @jkymarsh's example uses angular-route, while yours uses angular-resource, that could make a difference.

Another way to figure out why one works is to crack open the generated bundle and look at how angular-route vs. angular-resource get initialized and if that is what each lib expects.

However we are making progress here since it seems like the only real difference is that your example uses angular-resource. From looking at it, things should work though, since it expects window.angular as does angular-route.

@gabegorelick
Copy link
Author

Another difference is my use of browserify-middleware. I tried to follow their example of using multiple bundles, but there might be something lurking there. I bet if I use browserify directly, as @jkymarsh does, that will fix it. I'll let you know how that goes.

@thlorenz
Copy link
Owner

Cool, thanks.

@humidair1999
Copy link

@jkymarsh thanks a lot for figuring this out, so it seems like browserify-shim is working as expected already and no changes are necessary?

I haven't come across anything to indicate that browserify-shim is working incorrectly. Seems to work perfectly for every lib I've tried it with.

Make sure you guys check out my reply on the nvd3 thread too; nvd3 is working as intended as well, and I see no reason to think otherwise.

Honestly, my opinion is that people have difficulty grasping the concept of exports/global/window, both in the context of browserify and other module loaders. I don't blame them; these properties are often poorly-explained and difficult to grasp. As you suggest, we probably just need a little more documentation!

@ruimarinho
Copy link

I've also began building multiple bundles and, after getting everything working, with the vanilla browserify version, I hit some problems with browserify-shim which I use extensively (it has worked for every single use case I've dealt with, thank you @thlorenz!).

Like most of the people using browserify for large projects, I've also decided to split the vendor files into a separate bundle, keeping a more reasonably sized application file. I'm using gulp, browserify, watchify (for cached incrimental builds) and browserify-shim to achieve this, but I came across nearly every situation that @gabegorelick described in this thread (I also use angular and angular-route, wanted to be able to pass options to transform, etc). Looks like we're onto the same thing here!

It's actually very late here (took me some time to figure it all out...), so let me know if you still need any help. I plan on documenting this.

Lastly, I've noticed that the vendors file includes a reference to a local path (e.g. {"/Users/username/Projects/project/vendor/jquery/dist/jquery.js":"qLqOE9"}. Is there any chance of hiding this information? I'm not sure if this is related to browserify-shim or not. fullPaths already defaults to false.

@thlorenz
Copy link
Owner

@ruimarinho did you solve your problem in the end or did you also find an issue with browserify-shim?

I'm trying to figure out what needs to be done here. I get mixed feedback.

@jkymarsh seems to have figured out how to properly set things up (at least in one case).

@gabegorelick seems no longer sure if the problems he is encountering are actually browserify-shim issues or possibly related to browserify-middleware he's using.

@jkymarsh @gabegorelick please correct me if I'm wrong here.

How to proceed

If things work

If things work already (i.e. no changes to b-shim needed), but are hard to figure out, I'd like to add documentation that helps people to figure this out faster.

This can be added to the wiki either here or if lots of other tooling like gulp is involved here.

We could then link to these from the readme.

If things don't work

If on the other hand there are features that are missing from browserify-shim and/or are buggy, I'd like to create test cases that reproduce these if possible.

You could help me with this by either creating a PR that includes a failing test (please leave tools like gulp out of it since a test needs to be more focused), or by creating small repro cases which I could use to create these tests from.
Some of you have done so already.

I'm going to have a look at @jfsiii's repro right now in order to either find a bug with b-shim or explain what's wrong with his setup.

Finally

I want to get this issue resolved one way or the other.
browserify-shim is supposed to solve and clearly document all use/edge cases you'd encounter and I'd like to keep it that way.

@ruimarinho
Copy link

@thlorenz I did not find an issue with browserify-shim. I had some difficulty getting the whole process running together, especially because browserify-shim is so unobtrusive and operates very smoothly in the normal use-case. Documentation would certainly help here - a description of the multiple bundle use-case and possible solutions (with or without gulp or other automation utils). I can share my experience with gulp, maybe @jkymarsh can add his input from a grunt perspective.

I'll be offline during the weekend so expect an update from me during the next week. Thanks for your support!

@humidair1999
Copy link

My only actual issue with the shim, so far, has been the problem where it attempts to shim built-in node modules (that have browserified abstractions) and fails, as I documented in #44. Hoping to submit a PR for that myself, if I have sufficient time this weekend.

Aside from that, 100% of the issues I've had have related to integrating the shim with other build tools, including grunt and gulp. For instance, I opened an issue on grunt-browserify that explains the difficulty using transforms such as the shim, and the response from the author of grunt-browserify himself was that he wasn't sure on how to integrate a tool/transform such as the shim.

Unfortunately, issues like that fall within that middle gray area where the real problem is integration between tools, so it's not immediately clear who should be documenting things, resolving Issues, and making decision designs.

I'll take another look at the README this weekend and see about adding a little more detail as well, but aside from more thorough documentation (and it really depends on how detailed we care to be; do we really want to upkeep documentation for integration with tools like grunt-browserify and gulp-browserify?), I don't see a compelling reason to think the shim has any significant bugs.

I'm quite confident stating that @jfsiii's issue stems from improper configuration and usage. Hopefully my newest comment in that other thread will help him a bit.

@humidair1999
Copy link

I also do feel that, from a design standpoint, the use of the shim with vanilla browserify, and the use of the shim with grunt-browserify or gulp-browserify, are two very different integration points, and centralizing the configuration in the package.json unfortunately makes it just a little bit painful to integrate with said build tools. This is both because the configuration is located in what may be considered a "strange" location, and because it seems to often result in redundancy, requiring duplicated configuration both in the package.json and within the grunt/gulp tasks.

My personal stance is that it's both easier and safer to stick with using browserify directly, primarily via the command line, without an abstraction like grunt or gulp complicating things. As a result, I understand your decision to use the package.json, @thlorenz, and have had no problems using it as such. The instant the build tools come into play, things get messy.

Unless a conscious decision is made to say, "hey, we're going to actively ensure the tool is kept up-to-date with build tools like grunt and gulp," I'd say it might be wise to toss a little disclaimer in the README, stating that the shim's intended purpose is to be used with vanilla browserify, and that by integrating it with a build tool, the onus is on you to figure out how the hell it works.

@thlorenz
Copy link
Owner

@jkymarsh Thank you, these are very good points and I appreciate the feedback about the cause of the issues that are encountered.

I'll take another look at the README this weekend and see about adding a little more detail

I created a wiki, so please add information there. I have a page for general recipes and one for integration with tools like gulp.
We can link to the pages from the readme, but want to allow others to add info there without a PR needed.

centralizing the configuration in the package.json unfortunately makes it just a little bit painful to integrate with said build tools

That's the part I don't fully understand, since if you put all browserify and browserify-shim related configuration in the package.json it gets picked up no matter how browserify is invoked, i.e. via a tool or directly.

So even if using one of these tools as long as you stick to the spirit of browserify tools and config things there (and it's not a strange place IMO since all other main node tools, i.e. npm look for config there as well), things just work either way.

However if you try to config things via gulp/grunt directly then you are in trouble.

So possibly we should add something to the readme and/or wiki that explains things as such:

Although using browserify and browserify-shim works much better, if you have to, you may use them with other tools like gulp or grunt, but should keep the configuration of both in the package.json.
Not doing so i.e. trying to configure them in some Gruntfile is most likely going to make it much harder to integrate and may not even work at all.

@humidair1999
Copy link

However if you try to config things via gulp/grunt directly then you are in trouble.

Right, exactly, and that's the thing: the typical convention for 95% of grunt and gulp task modules out there is to configure them directly within the task in the gruntfile/gulpfile. That's why my Issue regarding grunt-browserify was so painful; you have to utilize not only the package.json to config, you ALSO have to duplicate that config within the gruntfile, because that's where the configuration is expected.

It's more an issue of browserify and the shim being very different, conceptually, from build tools like grunt and gulp. There's nothing wrong with that, per se, but it definitely makes them tougher to integrate.

Again, I actually prefer your and browserify's approach of using the package.json; I think it's a more logical place for configuration. However, it definitely differs from where build tools generally expect configuration to exist.

@thlorenz
Copy link
Owner

Ok, so we'll just document this in the way (or similar) that I suggested.
I think we need to communicate that b-shim solves problems related to non-commonjs packages and/or packages not installed with npm, but downloaded with bower for instance.

However it doesn't solve certain tools not integrating very well with the way things are commonly done in nodejs/browserify.

@humidair1999
Copy link

Totally concur. I'll definitely spend some time working on wiki docs this weekend, and elaborate on the things we've discussed. Maybe add in examples of using the shim with build tools, as well, for posterity's sake.

The bottom line, for me, is that grunt and gulp are kind of deviating from where node is headed as far as configuration and build tasks, and it's sort of annoying. I wish they'd move to align themselves more closely with the conventions that browserify (and the shim) uses.

@thlorenz
Copy link
Owner

Cool, feel free to go crazy with the wiki pages :) i.e. rearrange, rename, create new, etc.

What's currently there is just a quick repost from the readme to get things started and one contribution related to gulp integration.

Thanks.

@gabegorelick
Copy link
Author

@gabegorelick seems no longer sure if the problems he is encountering are actually browserify-shim issues or possibly related to browserify-middleware he's using.

Finally had time to investigate this more. Just wanted to confirm that this is indeed what's going on. Everything works perfectly fine with browserify directly, it's browerisfy-middleware that causes the issue. Also, the depends thing ("depends": ["d3:"d3"] vs "depends":["d3"]) doesn't make a difference in my case.

I'll play around with browserify-middleware more to see if I can make it work. Otherwise I'll file a bug with them.

@thlorenz
Copy link
Owner

@gabegorelick thanks a lot for the feedback, I will keep this issue open in order to coordinate efforts to improve documentation/wiki pages, but consider the issue you had originally as solved.

@ryan-kimber
Copy link

I've been experiencing the exact same troubles.

I'm using gulp with browserify and browserify-shim (directly, no gulp-browserify).

I've created a bare-bones repository (https://github.com/ryan-kimber/multi-browserify) to demonstrate the issue. The README.md explains the expected output, the output I'm getting and how to run the build.

The build process works, producing the correct files, but I don't know enough about browserify/browserify-shim to be able to tell if the shim/browserify code wrapping my own should look like.

If anyone can help me get this simple example working, I'll be happy to contribute documentation back to the project (and to gulp) to detail this use case. Thanks for any guidance you can offer. =)

@thlorenz
Copy link
Owner

@ryan-kimber you could use browserify-shim didagnostics to see if shimming is applied.

Also search for the string 'browserify_shim' in the resulting bundle. If modules were shimmed it should be present.

@mattdesl
Copy link

I'm running into similar issues with a gulp project. I find that it's almost always preferable to use a separate bundle for large packages (like jQuery, ThreeJS, TweenMax, etc) to keep my build times speedy. I also don't want to manually edit bunch of vendor paths in <script> tags or in package.json, since it's a maintainability nightmare (especially if there is duplication in Gulp/Grunt files).

My current solution is to concat (with source maps) the vendor libs into a single "libs.js" bundle, then add global:THREE, global:$, etc to the shims in package.json.

This is working pretty well -- it leads to very fast builds and I at a later point I can easily change to using CDNs for ThreeJS etc. But I'd be interested in exploring other options.

I think there is also room for more tooling. If things like browserify and b-shim are moving config into package.json, I think we should start thinking about how some configurations can be automated in the same was as npm init or npm install --save.

The instant the build tools come into play, things get messy.

Agreed, but sadly, build tools are not going anywhere, and are pretty much a staple of any large project. And whenever live-reload or watch tasks are needed, I tend to steer away from npm run.

EDIT: Now using wiredep to hook up to my bower JS files. It's pretty clean:

var bower = require('wiredep')({
    //... optional config ....
});

gulp.task('libs', function() {
    gulp.src(bower.js)
        .pipe(concat('libs.js'))
        .pipe(gulp.dest('app/js'));
});

Now I just need to a tool to automate the browserify-shim field, but that might be too much to ask for. :)

EDIT2: I ended up making a little tool to help automate the process. It will go through your bower dependencies and prompt you for the export value of each module. So far it works well for common bower packages, although given the poor state of standards across bower, I'm sure there are many edge cases that won't work perfectly well.

https://www.npmjs.org/package/shimbro

@thlorenz
Copy link
Owner

@mattdesl nice tool - I'll star it as soon as it has tests ;)

@thlorenz
Copy link
Owner

Closing this issue for now.

@ryan-kimber we are discussing your issue in another thread and it doesn't seem related to multi-bundles.

Please contribute to the wiki whenever you figured something out that was tricky, so whoever comes after you has an easier time :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants