No, I don’t mean resources to get help.
Have you ever opened a plugin or theme and seen a folder that says bower_components
or node_modules
? Yeah, I hate those. I don’t hate Bower or Node, I use them quite a lot. I hate how people use them in their plugins.
What Are Those Folders?
In order to make life easier, Bower is a package manager that lets you install libraries that your plugin needs. Making a plugin that needs AWS SDK?
bower install aws-sdk-js
Boom. And you can easily upgrade it too with bower update
– which I love. This is a great idea.
$ bower install aws-sdk --save bower aws-sdk#* cached git://github.com/aws/aws-sdk-js.git#2.2.28 bower aws-sdk#* validate 2.2.28 against git://github.com/aws/aws-sdk-js.git#* bower aws-sdk#~2.2.28 install aws-sdk#2.2.28 aws-sdk#2.2.28 bower_components/aws-sdk
But notice that last line? bower_components/aws-sdk
is where it saved my files. And if I go in there, the JS file I need is bower_components/aws-sdk/dist/aws-sdk.min.js
and that is surrounded by other files:
Now as a developer you have a couple choices here. You can leave the file where it is and just call it from there or you can move it. If you move it, you want to make a simple way of updating it. After all, the whole point of using Bower here is to make life easier. Personally I use Grunt for these things. I talked about it last year but my basic idea is to use Bower to download the latest and greatest versions, and then Grunt takes care of (a) updating the Bower packages and (b) copying the files to where I need them.
Okay, but what if I have something a little more complex?
What Resources Do I Need?
This seemingly innocuous question is surprisingly deep. It’s not just ‘what package/library am I trying to manage’, but how do I manage it and with what? What if, instead of the javascript, I wanted to use the PHP AWS SDK instead? Well, the AWS SDK for PHP is not available in Bower! Instead it uses Composer.
Here’s where things get weird. Composer is a package manger. Grunt is a package manager. Node and Bower are too. This means I have to stop and think hard. Which one do I need? Why do I need it? What am I going to be managing?
It’s time to ask this:
What Are My Packages For?
Within Node there are two kinds of packages:
- “dependencies”: these packages are required by your application in production
- “devDependencies”: these packages are only needed for development and testing
Take a moment to think what you need to dev and what you need to run. Your test code doesn’t need to be in your release, does it? No, of course not. It would make perfect sense to have in your Git or personal repository, but the WordPress SVN repository is not actually for your own code management. It’s a release management tool. That’s another post for another time. Just keep in mind that you should really only be pushing your code to SVN when it’s a version ready for use (be that beta testing or releases).
Back to what things are for. When talking about the AWS SDK javascript, I’m talking about front end packages. So that’s a dependancy. But Bower? It’s a devDependency. The users don’t need to know (or care) that I’m using Grunt and Bower to package things up. That means they shouldn’t be installed in my plugin!
In the case of my AWS SDK a ‘devDependency’ is Composer. I only need it to build my packages.
My dependencies are as follows:
"require": { "aws/aws-sdk-php": "2.*", "doctrine/orm": "*", "monolog/monolog": "*" }
Adding that to my composer.json
file is a simple thing and now I can just run composer update
to get everything I need!
Where Should My Packages Live?
This is generally pre-destined. If you use Node they go in node_modules
and Bower likes bower_components
and Composer uses vendor
and so on and so forth. You can, of course, customize these. I often make a folder called ‘assets’ or ‘assets-dev’ so I can easily ignore it in my version control. Frankly I don’t need them and neither do my users and it’ll help save space.
There’s a cool thing about composer. If you use composer init
then it asks, at the end “Would you like the vendor directory added to your .gitignore [yes]?
” This is great, because if you looked at the folder vendor
you would see a lot of folders and files you don’t really want. I actually only want one folder vendor/aws/aws-sdk-php/src/Aws/
and I want that folder to be located in aws/Aws
please and thank you. Composer adds this into .gitignore
for you.
You’ll still have to add that into your SVN ignore file, which is a little more annoying. To ignore all composer.*
files it’s this:
svn propset svn:ignore "composer.*" .
And if you want to ignore multiple files or folders use the following command to bring up the text editor:
svn propedit svn:ignore .
For SVN I would ignore composer.json
, composer.lock
, and the vendor
folder.
How Do I Move Folders?
Remember I want to move things to another folder? I use Composer’s scripts to do this. I admit this is ugly code. I have this in my composer.json
:
"scripts": { "post-update-cmd": [ "rm -rf aws/Aws", "cp -r vendor/aws/aws-sdk-php/src/Aws aws/", "rm -rf aws/Doctrine", "cp -r vendor/doctrine/common/lib/Doctrine aws/", "rm -rf aws/Guzzle", "cp -r vendor/guzzle/guzzle/src/Guzzle aws/", "rm -rf aws/Monolog", "cp -r vendor/monolog/monolog/src/Monolog aws/", "rm -rf aws/Psr", "cp -r vendor/psr/log/Psr aws/", "rm -rf aws/Symphony", "mkdir -p aws/Symphony/Component/EventDispatcher", "cp -r vendor/symfony/event-dispatcher/* aws/Symphony/Component/EventDispatcher/" ] }
This runs whenever I run composer update
in this folder and it copies everything where I need it to be. I did tell you it was ugly, right? But it does work.
The Result?
The result is my vendor
code is never uploaded to WordPress.org’s SVN, my users never see the stuff they don’t care about, and I have a faster way to update my plugins when I need to make sure all the packages are right.