layout: true
@basicallydan
--- class:topic-header .important.pushdown[ # I'm a Node Module Maintainer
(And so can you!) ## Dan Hough ] --- .important[ **Note:** This is the way *I* do things. It'll probably work for you, but maybe not. I don't know. Heckle me later. Or maybe give me more useful tips about the subject. .smaller.central[ (by the way, you can follow the slides at http://basicallydan.github.io/node-maintainer-talk/) ] ] --- # Scenario Let's say you're a developing a module which will create an LNUG talk for you and make it really interesting and a huge success. --- class:topic-header .important.pushdown[ # Target *everybody* ] --- # Target *everybody* A lot of the time there's no need to restrict your target audience to just NodeJS developers. You may be writing browser-friendly code without even realising it. Think about the ways that your module might be used in browsers. ```bash browserify index.js > lnugTalkGenerator.js uglify lnugTalkGenerator.js > lnugTalkGenerator.min.js ``` -- **HOWEVER:** Make sure you dependencies are browser-safe! .smaller[ See [browserify.org](http://browserify.org) and [github.com/mishoo/UglifyJS](http://github.com/mishoo/UglifyJS). ] --- class:topic-header .important.pushdown[ # The art of a good **README** ] --- # The art of a good **README** They're called READMEs for a reason: someone looking at your project for the first time should be given all the information they need to get started with it. More broadly, what's the purpose of the README? It tells prospective users the following: 1. That it's *legit* 2. How to use it 3. Whether it's going to be maintained and kept up-to-date 4. Whether it's reliable enough to use in production --- # The art of a good **README** You need: * API Documentation * Examples... --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs * `18e6513 Fixed fuck ups` is not a change log entry --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs * `18e6513 Fixed fuck ups` is not a change log entry * How to test - ideally it should be as simple as `npm test` --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs * `18e6513 Fixed fuck ups` is not a change log entry * How to test - ideally it should be as simple as `npm test` * How to compile --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs * `18e6513 Fixed fuck ups` is not a change log entry * How to test - ideally it should be as simple as `npm test` * How to compile * **VERY IMPORTANT:** How to contribute --- # The art of a good **README** You need: * API Documentation * Examples... in JavaScript, **not** CoffeeScript. * A proper changelog - don't rely on git commit logs * `18e6513 Fixed fuck ups` is not a change log entry * How to test - ideally it should be as simple as `npm test` * How to compile * **VERY IMPORTANT:** How to contribute * **Write it in Markdown** --- class:topic-header .important.pushdown[ # The Importance of Good Dependency Management ] --- # The Importance of Good Dependency Management You know how sometimes you install a module and it *just won't work* even though the Travis build is fine and the developer's documentation is really good and there aren't any issues and you've SLAMMED YOUR FIST ON THE TABLE LIKE FIVE HUNDRED TIMES?! -- That's because the developer didn't use `npm shrinkwrap`. --- # Good Dependency Management `npm shrinkwrap` creates a file recording the module's dependencies at the exact point they are at in the current directory. White `package.json` may have a requirement for `"request": "^2.42.0"`, `npm-shrinkwrap.json` will contain *specifically* version 2.42.0 if that's what you have installed. 1. You `shrinkwrap` your module with version `2.42.0` 2. `request` gets upgraded to `2.42.1`, `2.42.2`, etc. which are all theoretically compatible with 2.42.0 3. Without `shrinkwrap`, `npm install`ing your module would cause the latest in `2.42.x` to be installed, but since you have `shrinkwrap`'d, `2.42.0` specifically will be installed. --- # Good Dependency Management **Note:** By default, `npm shrinkwrap` will not include `devDependencies`. To include these you've gotta run `npm shrinkwrap --dev`. This means people cloning from the source will get the `shrinkwrap`ped development dependencies *and* the regular, non-dev ones. --- # Good Dependency Management `npm prune` is a command which will remove any modules you have installed in the `node_modules` folder but not currently in the `dependencies` or `devDependencies` sections of `package.json`. Run this *before* `npm shrinkwrap`. If you run `npm shrinkwrap` and get an `extraneous` error, it's because you have unsaved dependencies. Either: save them, or `npm prune` them out of your project. --- # Good Dependency Management On the other hand, if your module has dependencies that you've `npm install`ed but forgot to `--save`, you might want to fix that. You can use the package `require-analyzer` to analyse your codebase to find un-saved modules. Get it on npm, of course: ```bash npm install -g require-analyzer # Go to your project folder, run: require-analyzer # It will update package.json for you ``` --- class:topic-header .important.pushdown[ # Versioning ] --- # Versioning Semantic Versioning, aka SemVer, is the way we version modules on npm. If you aren't doing it, you're ruining the ecosystem for everyone else. **No excuses!** How does Semantic Versioning work? Here's a primer on the basics: `major.minor.patch`, e.g. `1.2.3` * `major` - This number is incremented when changes to the module include *incompatibilities* with previous versions, e.g. `generateLNUGTalk()` gets changed to `writeBrilliantLNUGTalk()`. * `minor` - This number is incremented when new functionality is added which is backwards-compatible, such as a new function called `saveLNUGTalkToPDF()`. * `patch` - This number is incremented when you make backwards-compatible bugfixes or refactoring. --- # Versioning You might just go into `package.json` and 1. Change the `version` string... then, 2. Create a `git commit` specifically for this change 3. Create a `git tag` so that GitHub users can find snapshots of the module at specific points in time. This sounds like three different actions, right? WRONG! -- `npm version` to the rescue! --- # Versioning `npm version [major|minor|patch]` is a command which not only increments the appropriate number in `package.json`, but creates a `git commit` and `git tag`. Example: ```bash # Let's say our module is currently at version 3.1.5 npm version minor -m "v3.2.0 Added insertRelevantGIFsIntoSlides function" ``` This will automatically increment the `1` to `2` and reset the `5` to `0`, then create a `git commit` with the message `"v3.2.0 Added insertRelevantGIFsIntoSlides function"`, and then create `git tag` called `v3.2.0` pointing at this new commit. -- This is a hugely satisfying command. --- class:topic-header .important.pushdown[ # A pre-publish checklist ## What to do after you've finished your change, and before you publish the module ] --- # A pre-publish checklist 1. Determine next version. E.g. For `0.23.3`, a bugfix/patch means `0.23.4` is next. 2. Update changelog (e.g. in `README.md` or `CHANGELOG.md`) with new entry, e.g.
`v3.3.0 (2015-02-25) Added wakeAudienceUp function.` 3. Make sure dependencies are locked down. Run `npm prune`, then `require-analyzer`, then `npm shrinkwrap --dev`. 4. If you're targeting browsers, compile using `browserify` and maybe `uglify` 5. Commit these changes, don't mention the version code yet... 6. Run `npm version [major|minor|patch]` with a message (`-m`) e.g.
`npm version -m "v3.3.0 wakeAudienceUp() function added"` 7. Do a quick `git push` 8. You're done! `npm publish` will push changes to npm. Well done! --- class:topic-header .important.pushdown[ # Interacting with your community ] --- .important.pushdown[ # Your community of contributors is made up of **real** people with **real** feelings, who put **real** time into making your project a little bit better! ] --- # How can your community feel included? ## Publicly recognise contributions * Try a `contributors.md` file, or a little list in `readme.md`, with links to the GitHub profiles of people who've made successful pull requests. * Thank them in the `changelog`, too? This will not only will you encourage more contributors, but you'll get a warm, fuzzy feeling inside, and so will your new open-source-co-workers. --- # How can your community feel listened-to? ## Respond as quickly as possible * Responding quickly to issues and pull requests shows care and respect * This doesn't mean reading huge comments and replying with huge comments immediately * Simply, "Hey, thanks for your PR - I've seen it and I'll give it a proper read as soon as I can! Thanks!" will do. --- # How to improve community contributions ## Enforce style * Write a style guide * This can be in `CONTRIBUTING.md` or the `README`, but it helps. * Put a `.jshintrc` file in the root of your project * If they use it in their IDE, they'll be told off when they don't match your style --- # How to improve community contributions ## Respond honestly * Don't want to include a feature request? * Tell them - no need to beat about the bush * Spotted some stylistic no-nos? * Point them out, make suggestions * Don't forget to be polite, grateful, and prepared for debate --- # How to prevent your project from dying ## Take on extra help, and/or quit! Losing interest? Too many issues piling up? Try: * Get in touch with contributors to find co-maintainers, or someone to take over * Ask around on Hacker News, Reddit or the LNUG Gitter Channel for help -- > It's better that the project is properly maintained with the help of others than floundering under your sole ownership. --- class: full-image-background-slide be-excellent .gradient-cover[ # Finally: Be excellent to each other Even if people are dicks to you in your issues and pull requests section, they are probably either frustrated, tired, or unaware that they are talking to a real person. Turn the other cheek and be nice: they might just be nice back. ] --- class: topic-header # Thanks ## Good luck with your modules! ## I also sometimes blog about Node and JavaScript on my website, [danhough.com](http://danhough.com), and tweet about it too [@basicallydan](https://twitter.com/basicallydan).
.central[ Many thanks to [@admataz](https://github.com/admataz), [@jkbits1](https://github.com/jkbits1) and [@rosskukulinski](https://github.com/rosskukulinski) for their feedback. ]