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

Dependencies of installed packages? #45

Open
LeonB opened this issue Sep 15, 2014 · 17 comments
Open

Dependencies of installed packages? #45

LeonB opened this issue Sep 15, 2014 · 17 comments

Comments

@LeonB
Copy link

LeonB commented Sep 15, 2014

Hi,

I've got a question about how debowerify works with dependencies. I'm struggling with that issue and maybe I'm just misunderstanding it.

I have a application.js which contains one thing: require('magnific-popup'). I've installed magnific-popup via bower and it has one dependency: jQuery.

When I browserify the file (browserify -t debowerify app/assets/javascripts/application.js > public/js/application.js) the resulting file doesn't contain the jQuery dependency. Am I doing something wrong or is this how debowerify is supposed to work?

@pllee
Copy link

pllee commented Jan 9, 2015

I have the same problem/question. Does this have to be enabled ? Is there a way to ignore dependencies by name? For example a jquery plugin that requires another plugin but ignores jquery if passed in as an argument or whatever.

@bobthecow
Copy link
Collaborator

Browserify and Debowerify aren't magic... if a jQuery plugin isn't written to require jQuery properly — and most of them aren't — it won't be bundled automatically. I usually end up with a file in my project that looks something like this:

var $ = require('jquery');

// most jQuery plugins don't work unless jQuery is on the window as well :-/
window.$ = window.jQuery = $;

require('some-jquery-plugin');
require('another-jquery-plugin');
// ...

@pllee
Copy link

pllee commented Jan 9, 2015

magic ... It doesn't load the dependencies defined in the plugins bower.json file. What is the point of using a bower component if it doesn't define its dependencies properly. Also no offense to the writer of this but what is the point of Debowerify if it doesn't follow the dependency tree?

@sukima
Copy link
Collaborator

sukima commented Jan 9, 2015

@pllee And you hit the bower nail on the head. That has always been the problem with bower and why many browserify fans prefer npm modules over bower components. Until the front end community moves on we will always have to deal with these issues.

I found many times with bower components that I would use debowerify or browserify-shim or some combination together.

@pllee
Copy link

pllee commented Jan 9, 2015

@sukima I prefer broswserify but there are cases where the bower way makes sense. Such as excluding a jquery file that the whole page uses but the component also relies on or including a component that only works with bower. My current "problem" now is that I have a "main.js" for each page that just requires whatever components it needs and they all get built into one file with browserify. Unfortunately a jquery plugin that I am extending manages its dependencies with bower (which I think is pretty common) but in order for me to make my component requireable/work I need to require 2 js files and some css. Instead of cherry picking the dependencies I thought a tool could be used to automate the process by using bower's api. I found this tool that I thought would fit my needs but it looks as if it doesn't manage dependencies or give a way to get required css info, also I would prefer to have the ability for non minified source.

@sukima
Copy link
Collaborator

sukima commented Jan 9, 2015

@pllee When this happened to me I use bower to install the dependencies and then used browserify-shim instead of debowerify and manually declared the components dependencies.

@pllee
Copy link

pllee commented Jan 9, 2015

@sukima Thanks for all the help, that looks like a useful tool. Just to confirm debowerify isn't meant for dependency/css management right ? How tedious it to maintain your suggested way with browserify-shim? One of the great strengths of browserify is that there is no external logic for dependency management and very simple build process.

Would you use a tool that took a bower component and made it into requirable/browerifiable js code ?

@bobthecow
Copy link
Collaborator

debowerify is only meant to expose bower packages to browserify. but bower packages are all over the map. if the packages are commonjs-friendly, they'll build properly with browserify+debowerify. if they're not, you'll need to use a shim. if you don't want to use a shim, take it up with the bower package maintainer :)

@pllee
Copy link

pllee commented Jan 10, 2015

@bobthecow Thanks for the input, I wasn't clear on the if the packages are commonjs friendly part. That might be helpful to note that in the readme, if it is already there I must have missed it. Since most bower components are not commonjs friendly I might write a tool that can try to package them to be requirable and built with browserifiy.

@sukima
Copy link
Collaborator

sukima commented Jan 10, 2015

@pllee Why write a tool that's exactly what browserify-shim is designed to do.

@bobthecow
Copy link
Collaborator

Why write a tool that's exactly what browserify-shim is designed to do.

👍

@pllee
Copy link

pllee commented Jan 10, 2015

@sukima @bobthecow

I figured I would be sick of writing browserifiy-shim config files that just mimic that the dependencies defined by bower file. It seems like the great tool but doesn't really automate the process. I still don't know if it is worth the effort for my use case because there are tools out there and it really isn't a big problem for me. Having info about css meta would be nice to I was thinking about doing something like :

bowerifiy jquery.businessHours -jquery > businessHours.js

That file would include it's deps without jquery so basically be:

require(./'bower_components/jt.timepicker')
require('./bower_components/jquery.businessHours')
module.exports = {
    css: .. css info;
}

I would be able to use that file in my code that will be browserifed

var businessHours = require('./businessHours')
loadCss(businessHours.css);

https://github.com/gEndelf/jquery.businessHours

@sukima
Copy link
Collaborator

sukima commented Jan 12, 2015

In my cases where I also wanted CSS and stuff I used the CSS processor lib to pull it in. Like Less or Sass include statements and left the JS separate. Sounds like you have more unique requirements.

Maybe your setup could glean some light on how to import CSS from JS and a way to parse the bower.json file better. If so please contribute back; sounds like it would be a valuable feature for debowerify.

@maxnordlund
Copy link
Collaborator

This seams a lot like cssify, perhaps this could be solved using a combination of debowerify and cssify? Just throwing ideas out there.

@pllee
Copy link

pllee commented Jan 12, 2015

@maxnordlund @sukima cssify looks nice but I am weary about including css strings in js. I am not really sure how relative images would work and the processing of js strings to css is much more overhead than natively parsed and cached css. But my weariness is irrelevant.

Besides that all I what was looking to do would be to add some "meta" to the bundle which adds css info that could be used by external tools such as cssify or loaded with a css loader etc. It would just basically parse the bower.json's main for css files and add them to the meta. It might look something like:

{
 filePaths: ['./bower_components/dep1/file.css', './bower_components/dep2/file.css'],
 relativeUrls: ['bower_components/dep2/file.css', 'bower_components/dep2/file.css']
}

@eggyal
Copy link

eggyal commented May 26, 2015

I've just started using browserify and must admit to being rather surprised (and confused) by this discussion. I had assumed (just as @LeonB and @pllee appear to have done) that, upon encountering a commonjs-unfriendly component, debowerify would automatically require the dependencies listed in its .bower.json—it appears, from what @bobthecow @sukima and @maxnordlund are saying, that it does not?

If I've understood correctly, then browserify-shim will not do this automatically either?

Presumably these tools do not adopt such an approach because it wouldn't work? Would someone be able to elaborate on that for me? I'm rather puzzled at present.

FWIW: I'm reluctant to switch to npm for front-end package management because of its nested approach to dependency management, which (again, if I've understood correctly) could result in libraries being included multiple times... at least with bower I can manage version conflicts in such a way as to end up including only a single copy of each. I don't want to be serving up three versions of jQuery with every page!

@fza
Copy link

fza commented May 26, 2015

This is a bit offtopic, I'm sorry. ;)

@eggyal

I'm reluctant to switch to npm for front-end package management because of its nested approach to dependency management, which (again, if I've understood correctly) could result in libraries being included multiple times...

That's only true when the same package is referenced multiple times with a non-combinable version constraint. For example, when a package is referenced by 1.1.x and another time by ~1.1.0 (patch level constraint in this example), a fresh npm install will place only one copy of that package at the top level of the node_modules directory (or as top most as necessary, I'm not sure about the exact placement behavior). At least the package will only be present once. Thus, browserify will only find this one copy and will therefore not include the package twice in the bundle.

But you are right in terms that e.g. the combination of 1.2.x and ~1.1.0 should cause the "same" package being included twice, but in different versions. That's on purpose as e.g. the API could have changed. That's what all this semantic versioning is all about and it's actually a good thing—in a perfect world at least, where all packages have well defined (dependency) versions. (see also semver)

You can test it with a package.json like this:

{
  "name": "test",
  "version": "0.1.0",
  "dependencies": {
    "httppp": "~0.2.1", // references readable-stream 1.0.2
    "readable-stream": "~1.0.0" // yields only one ~1.0.0 in the node_modules directory
                                // try with "1.1.0" and you get two copies
  }
}

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

7 participants