Reputation: 2244
Yeoman's quickstart and package manager guides suggest using Bower to manage dependencies.
They get installed into
app/bower_components/[component_name]
The guide just suggests inserting a
<script src="app/bower_components/[component_name]/[relevant_file.js]"></script>
line into your html file.
That's fine. Except if that component has dependencies. Bower helpfully fetches those components, but, as far as I can see, doesn't give you a list of them and the order they need to be inserted into your code. (I know you get a list of what got installed when you do the install, and one could dig it out of a json file somewhere, but that's still just bower's name for the component, not the path to the actual file that needs to be referenced). Which means that, for a popular component like jquery-maonsonry I have to manually insert
<script src="bower_components/get-size/get-size.js"></script>
<script src="bower_components/doc-ready/doc-ready.js"></script>
<script src="bower_components/eventEmitter/EventEmitter.js"></script>
<script src="bower_components/eventie/eventies.js"></script>
<script src="bower_components/get-style-property/get-style-property.js"></script>
<script src="bower_components/jquery-bridget/jquery-bridget.js"></script>
<script src="bower_components/matches-selector/matches-selector.js"></script>
<script src="bower_components/outlayer/outlayer.js"></script>
<script src="bower_components/jquery-masonry/masonry.js"></script>
All of which I had to go into and find the relevant js file name. Given that all these files are defined already in json dependencies files, and bower knows about them, is there a way the above code can be autogenerated. Either for me to put into my html manually, or a symLink that points to the output of a watch command. I'm aware require.js might manage this on my behalf, but is there a way to get around needing require?
Upvotes: 17
Views: 3786
Reputation: 21546
I've just put some code on npm which puts your dependencies in an ordered array. https://www.npmjs.org/package/dependency-orderer
If you're not using grunt bower-install, or don't want to use script tags (if you're bundling your javascript, which you should be), hopefully this will work for you.
Keen to hear feedback, as this is the first module I've published.
Upvotes: 1
Reputation: 5770
I wrote a tool that helps with this, grunt-bower-install
. It's a grunt plug-in that works well with the Yeoman workflow. You manually run grunt bower-install
after any change-up of your bower components. (After you install a new one, remove one, whatever).
I tried it out with jquery-masonry
...
$ bower install jquery-masonry --save
$ grunt bower-install
...and ended up with...
<!-- bower:js -->
<script src="bower_components/outlayer/item.js"></script>
<script src="bower_components/get-size/get-size.js"></script>
<script src="bower_components/jquery-masonry/masonry.js"></script>
<!-- endbower -->
The reason this plug-in can't be more helpful is due to each package's bower.json
file not specifying a main
property. Without that knowledge, a script (like mine) can't reliably detect the actual package's core file.
These tools are all young. Given the free nature of Bower, anyone can register a package. The author has the choice of not mentioning dependencies, leaving out the main
property, choose to include needless files, and we end up with a bit of chaos. Bower offers the dream workflow for end-users if package authors would just avoid these patterns. Hopefully they will pick up on these practices sooner than later.
However, that chaos aside, this is still so much better than it was just a couple years ago. You actually had to dig these plug-ins up for yourself, extract their .zip file to a folder, and find the real file you wanted yourself, anyway.
So, long story short, a tool like grunt-bower-install
can help, but in the end, what you did originally is the safest approach.
Yeoman's generator-webapp
now includes this Grunt task, grunt-bower-install
, out of the box. So, the result I described above is out-of-date.
grunt-bower-install
with jquery-masonry
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/get-style-property/get-style-property.js"></script>
<script src="bower_components/get-size/get-size.js"></script>
<script src="bower_components/eventie/eventie.js"></script>
<script src="bower_components/doc-ready/doc-ready.js"></script>
<script src="bower_components/eventEmitter/EventEmitter.js"></script>
<script src="bower_components/jquery-bridget/jquery.bridget.js"></script>
<script src="bower_components/matches-selector/matches-selector.js"></script>
<script src="bower_components/outlayer/item.js"></script>
<script src="bower_components/outlayer/outlayer.js"></script>
<script src="bower_components/jquery-masonry/masonry.js"></script>
<!-- endbower -->
Upvotes: 16