In October last year, I piqued my curiosity into 3 package system managements. Their names are known by developers: popular ones are NPM, Bower, Packagist, gem, Maven... Each platform aims a context or a specific language. This helps your project dependencies and compatibilities between libraries. It also gives more visibility than a custom hosting, thank to a unique platform. This concept is very similar to package managers on OS like Debian (apt), Fedora (rpm).

Pack 'all the things'

So I definitely packed PHP Push Websocket, Pulse.js and blgn, respectively into Packagist, Bower and NPM. The main reason is to share these librairies across the community. On one hand, it gives more visibility for people to use them. On the other hand, developers could help to contribute and to give feedback for improvements - in therory :).

In this post, I am talking about how I have packed my librairies into theses 3 package managers: NPM, Bower and Packagist. I am also writing about the difficulties and issues that I have met, my opinions about the task and consequences of publishing librairies that I have experienced.

  1. Build a package
    1. NPM
    2. Bower
    3. Packagist
  2. Pack 'all the things' - Thoughts

Build a package

The following sections are roughly tutorials for building a package for package managers: NPM, Bower and Packagist. Of course, all need to be adapted to the current context, I only use examples. One important thing is to know what the commands are used for.

How to build a package for NPM

Every NPM has a main file described in package.json. This is pretty easy if the code already follows that specifications (module.export).

npm init

For blgn, here is the main information:

{
  "name": "blgn",
  "version": "0.1.3",
  "main": "src/blgn.js",
  "description": "Generation of a light-weight blog in Node.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/srchea/blgn.git"
  },
  "keywords": [
    "blog",
    "generator",
    "light weight",
    "cms"
  ],
  "author": "Sann-Remy Chea",
  "license": "GPLv2",
  "bugs": {
    "url": "https://github.com/srchea/blgn/issues"
  },
  "homepage": "https://github.com/srchea/blgn",
  "dependencies": {
    "html-minifier": "^0.7.2",
    "pretty-data": "^0.40.0",
    "uglify-js": "^2.4.23",
    "ycssmin": "^1.0.1",
    "marked": "^0.3.3"
  }
}

If you already have an account on NPM, please go to the step after. Otherwise, type npm adduser then follow the instructions.

To make a new tag:

npm version v0.1.0

This creates the v0.1.0 tag. Then, push it into the repository:

git push origin v0.1.0

Now we need to publish the library in NPM.

npm publish

I found it very easy and accessible without constraints. I mean every developer could publish their librairies easily and quickly.

For updating the code, create a new tag then publish it.

npm version v0.2.0
git push origin v0.2.0
npm publish

To bump a major/minor or patch version, instead of specifying a version, we can use this following command:

npm version minor -m"Created tag %s"

This will automatically upgrade the minor version of the package and it will also commit the new tag. After few minutes, you will find your package in the public NPM repository.

How to build a package for Bower

Pre-requirements: Bower requires NPM, and a public git repository.

First, create the bower.json, this file contains information about the package.

bower init

Bower does not need a specific architecture. It is better to have a single main file, compressed and minified, for developers to handle. However, the description of the package should be written in bower.json. Here is the bower.json of Pulse.js:

{
  "name": "pulsejs",
  "version": "0.1.0",
  "homepage": "https://github.com/srchea/pulse.js",
  "authors": [
    "Sann-Remy Chea"
  ],
  "description": "Beats per minute (BPM) automatic detection with Web Audio API.",
  "main": "bin/pulse.min.js",
  "keywords": [
    "music",
    "beats",
    "detection",
    "rhythm",
    "bpm",
    "web",
    "audio"
  ],
  "license": "MIT",
  "ignore": []
}

Then, we need to register our package.

bower register pulsejs git://github.com/srchea/pulse.js.git

This will prompt for GitHub account information. After this process, you will be able to see your package in Bower.

How to build a package for Packagist

First of all, we need to know if the architecture fits for Packagist. In fact, it has to follow a specification:

  • PSR-0
  • PSR-1
  • PSR-2
  • PSR-3
  • PSR-4

At this time, the latest is PSR-4. I chose PSR-4 deliberately because I wanted to keep an up-to-date structure. That specification describes the autoloading classes.

Pre-requirements: composer, an account on Packagist.org, an library that matches PSR-4 specs and a public git repository.

For PSR-4, PHP Classes have to be inside a folder, here it is src/PushWebSocket. Moreover, each class has to belong to the same namespace. For example:

namespace PushWebSocket;

class Server {
  public function __construct() {
    // ...
  }
}

Once it is PSR-4 compliance, we generate a composer.json which contains crutial information for our package.

composer init

This will prompt information on the package. The following output is the composer.json for PHP-Push-WebSocket.

{
  "name": "srchea/php-push-web-socket",
  "description": "Lightweight PHP WebSocket server handling several clients.",
  "type": "library",
  "license": "GPLv3",
  "keywords": [
    "websocket",
    "push",
    "server",
    "rfc",
    "6455"
  ],
  "authors": [
      {
        "name": "Sann-Remy Chea",
        "email": "src@srchea.com"
      }
  ],
  "minimum-stability": "dev",
  "require": {
    "php": ">=5.3.0"
  },
  "autoload": {
    "psr-4": {
        "PushWebSocket\\": "src/PushWebSocket/"
    }
  }
}

We can try to install the package with the following command:

composer install

If everything is fine, we can keep going to the next step: commit, create a tag and register our package.

To commit on GitHub:

git commit -m"Packed my first package for Packagist"

Then, we create a tag:

git tag -a v1.0.0 -m"Stable version 1.0.0 of my package"
git push origin v1.0.0

Here we are, now we are going to register the package online. For that, we need to go to the submission page of Packagist.

We are done, in few minutes you will be able to see the package on Packagist.org. The package is now shared across PHP developers!

Pack 'all the things' - Thoughts

I think that every developer who pushed a package into a public repository should be proud of it (yes, I am). Packages are shared across Node.js developers, JavaScript developers, PHP developers... and they can easily installed by a one-line command. Keep in mind that a library that is useful for you could be useful for others.

During this experience, I met very few people that contribute by pushing codes, bugfixes. A bunch of people who asked for new features and created bug reports, which is good. And others ask help without reading the documentation :). In addition, there are people who needed help for their projects that use one of my libraries. By committing to public platforms, especially on GitHub, my profile gains more visibility: I received a couple of mails from recruiters.

Technically speaking, I become more rigorous when I commit a new code because I know that it can impact people who has used your library. Documentations are the main entry point for contributions. These guildelines are the how-to for commits and pull requests.

Feel free to comment, share your thoughts and your experiences.

Share & Comments
comments powered by Disqus