$30 off During Our Annual Pro Sale. View Details »

node.js Module Development

Jay Harris
September 14, 2013

node.js Module Development

Node.js has given JavaScript a new resurgence as a server-side language. No longer just for image rollovers and AJAX, JS is now available as a platform for creating lightning-fast, lightweight, networked applications. In this session, we will move beyond Node’s base web servers and Twitter applications, and into module development: those small, reusable components that are the foundation for every business application on every platform. Learn how to create a module within Node.js, how to test your module and validate functionality, and how to get your creation distributed into the wild. With this knowledge, you can make the next great Node package and become famous.

Author:
Jay Harris
Problem Solver | Arana Software
[email protected] | www.aranasoft.com
www.twitter.com/jayharris

Jay Harris

September 14, 2013
Tweet

More Decks by Jay Harris

Other Decks in Technology

Transcript

  1. M O D U L E D E V E L O P M E N T

    View Slide

  2. Node.js is a platform built on
    Chrome's JavaScript runtime for
    easily building fast, scalable network
    applications.


    What is node.js?

    View Slide

  3. View Slide

  4. ./

    View Slide

  5. sourceControl
    git  init

    View Slide

  6. javascriptFiles
    mkdir  ./lib

    View Slide

  7. executableFiles
    mkdir  ./bin

    View Slide

  8. testFiles
    mkdir  ./test

    View Slide

  9. documentationFiles
    mkdir  ./doc
    mkdir  ./example
    mkdir  ./man

    View Slide

  10. informationalFiles
    touch  ./README
    touch  ./LICENSE
    touch  ./AUTHOR

    View Slide

  11. ./bin
    ./doc
    ./example
    ./lib
    ./man
    ./test
    singularNouns

    View Slide

  12. packageManagement

    View Slide

  13. Package Manager

    View Slide

  14. github:
    install:
    isaacs/npm
    comes with node

    View Slide

  15. npm install
    localInstallation

    View Slide

  16. npm install --global
    globalInstallation
    -g or --global

    View Slide

  17. npm install --link
    dualInstallation

    View Slide

  18. npm install --save[-dev]
    dependencyReferences
    --save or --save-dev

    View Slide

  19. npm install
    updateDependencies

    View Slide

  20. npm init
    packageInitialization

    View Slide

  21. $  npm  init
    name: (sample-node) Sample
    version: (0.0.0) 0.1.0
    description: This is a sample module
    entry point: (index.js) _

    View Slide

  22. author:  Jay  Harris
    license:  (BSD)  BSD
    About  to  write  to  /Projects/sample-­‐node/package.json:
    {
       "name":  "Sample",
       "version":  "0.1.0",
       "description":  "This  is  a  sample  module",
       "main":  "index.js",
       "scripts":  {
           "test":  "echo  \"Error:  no  test  specified\"  &&  exit  1"
       },
       "author":  "Jay  Harris",
       "license":  "BSD"
    }
    Is  this  ok?  (yes)  _

    View Slide

  23. ./package.json
    {
    "name": "Sample",
    "version": "0.1.0",
    "description": "This is a sample module",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no tests avail.\" && exit 1"
    },
    "author": "Jay Harris",
    "license": "BSD"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  24. npm init is additive not destructive

    View Slide

  25. moduleCreation

    View Slide

  26. module

    View Slide

  27. module.exports

    View Slide

  28. ./lib/sample.js
    module.exports.sayHello = function() {
    return "Hello World!";
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  29. var  sample  =  require("./lib/sample.js");
    //  Returns  'Hello  World!'
    sample.sayHello();

    View Slide

  30. ./lib/person.js
    function Person(first, last) {
    if (!(this instanceof Person)) {
    return new Person(first, last);
    }
    this.firstName = first;
    this.lastName = last;
    return this;
    }
    module.exports = Person;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  31. var person = require("./lib/person.js");
    // This will return undefined
    person.firstName;
    // This will return 'Jay'
    var jayHarris = new Person('Jay','Harris');
    jayHarris.firstName;

    View Slide

  32. function Person(first, last) {
    // ...
    }
    module.exports = Person;
    // This is a public method;
    Person.prototype.sayHello = function() {
    return _join.call(this, "Hello", this.firstName);
    }
    // This is a private method
    var _join(first, second) {
    return first + ' ' + second;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  33. var  person  =  require("./lib/person.js");
    //  This  will  throw  'Has  No  Method'  error
    person.sayHello();
    //  This  will  return  'Hello  Jay'
    var  jayHarris  =  new  Person('Jay','Harris');
    jayHarris.sayHello();

    View Slide

  34. function Person(first, last) {
    // ...
    }
    module.exports = Person;
    // This is a static method
    module.exports.sayHello = function() {
    return "Hello World!";
    }
    // This is a public instance method;
    Person.prototype.sayHello = function() {
    return _join.call(this, "Hello", this.firstName);
    }
    // This is a private method
    var _join(first, second) {
    return first + ' ' + second;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  35. var  person  =  require("./lib/person.js");
    //  This  will  return  'Hello  World!'
    person.sayHello();
    //  This  will  return  'Hello  Jay'
    var  jayHarris  =  new  Person('Jay','Harris');
    jayHarris.sayHello();

    View Slide

  36. eventEmitter

    View Slide

  37. var  EventEmitter  =  require('events').EventEmitter;

    View Slide

  38. EventEmitter.call(this);

    View Slide

  39. var  util  =  require('util');
    //  ...
    util.inherits(MyClass,  EventEmitter);

    View Slide

  40. var EventEmitter = require('events').EventEmitter
    , util = require('util');
    function Person(first, last) {
    // ...
    EventEmitter.call(this);
    // ...
    }
    util.inherits(Person, EventEmitter);
    Person.prototype.goToBed = function() {
    this.emit("sleep");
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  41. var  person  =  require("./person.js");
    //  This  will  return  'Hello  Jay'
    var  jayHarris  =  new  Person('Jay','Harris');
    jayHarris.on("sleep",  function()  {
           console.log("Goodnight,  Jay");
    }
    jayHarris.goToBed();
    //  Output  'Goodnight,  Jay'

    View Slide

  42. testingNode.js

    View Slide

  43. TDD is to coding style as yoga is
    to posture. Even when you're not
    actively practicing, having done so
    colors your whole life healthier.”
    j. kerr

    View Slide

  44. assertingCorrectness

    View Slide

  45. var  assert  =  require('assert');

    View Slide

  46. assert(value)
               .ok(value)
               .equal(actual,  expected)
               .notEqual(actual,  expected)
               .deepEqual(actual,  expected)
               .notDeepEqual(actual,  expected)
               .strictEqual(actual,  expected)
               .notStrictEqual(actual,  expected)
               .throws(block,  [error])
               .doesNotThrow(block,  [error])
               .ifError(value)

    View Slide

  47. var assert = require('assert');
    // Will pass
    assert.ok(true);
    // Will throw an exception
    assert.ok(false);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  48. var assert = require('assert');
    // Will throw 'false == true' error
    assert.ok(typeof 'hello' === 'number');
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  49. $  node  test.js
    assert.js:104
       throw  new  assert.AssertionError({
                   ^
    AssertionError:  false  ==  true
           at  Object.  (my-­‐test.js:7:8)
           at  Module._compile  (module.js:449:26)
           at  Object.Module._extensions..js  (module.js:467:10)
           at  Module.load  (module.js:356:32)
           at  Function.Module._load  (module.js:312:12)
           at  Module.runMain  (module.js:487:10)
           at  process.startup.processNextTick.process._tick...
    $  _

    View Slide

  50. Chai Assertion Library

    View Slide

  51. github:
    install:
    chaijs/chai
    npm install chai

    View Slide

  52. isTrue,                      isFalse,
    isNull,                      isNotNull,
    isUndefined,            isDefined,
    isFunction,              isNotFunction,
    isArray,                    isNotArray,
    isBoolean,                isNotBoolean,
    isNumber,                  isNotNumber,
    isString,                  isNotString,
                                       include,
                                       lengthOf,
                                       operator,
                                       closeTo  
    isObject,                  isNotObject,
    typeOf,                      notTypeOf,
    instanceOf,              notInstanceOf,
    match,                        notMatch,
    property,                  notProperty,
    deepProperty,          notDeepProperty,
    propertyVal,            propertyNotVal,
    deepPropertyVal,    deepPropertyNotVal,
    additional
    assertions

    View Slide

  53. var  assert  =  require('chai').assert;

    View Slide

  54. var assert = require('chai').assert;
    // Will throw 'expected 'hello' to be a number'
    assert.isNumber('hello');
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  55. $  node  test.js
    expected  'hello'  to  be  a  number
    $  _

    View Slide

  56. var chai = require('chai')
    , assert = chai.assert;
    chai.Assertion.includeStack = true;
    // Will throw and display stack
    assert.isNumber('hello');
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  57. expectAssertions

    View Slide

  58. expectSyntax
    expect(person).to.be.an('object');
           .with.property('age')
           .that.is.a('number')
           .that.equals(34);
    assert.isObject(person);
    assert.property(person,  "age");
    assert.isNumber(person.age);
    assert.equals(person.age,  34);
    assertSyntax

    View Slide

  59. var  expect  =  require('chai').expect;

    View Slide

  60. assertionChains
    for readability

    View Slide

  61. expect(person).to.exist
           .and.be.an('object')
           .with.property('age')
           .that.is.to.exist
           .and.is.a('number')
           .and.equals(34);

    View Slide

  62. .to
    .be
    .been
    .is
    .that
    .and
    .have
    .with
    syntaxSugar
    for readability

    View Slide

  63. expect(person).to.exist
           .and.be.an('object')
           .with.property('age')
           .that.is.to.exist
           .and.is.a('number')
           .and.equals(34);

    View Slide

  64. expect(person).to.exist
           .and.be.an('object')
           .with.property('age')
           .that.is.to.exist
           .and.is.a('number')
           .and.equals(34);

    View Slide

  65. .property
    subjectChange
    from original object

    View Slide

  66. expect(person)
       .that.is.an('object')
       .with.property('address')
           .that.is.an('object')
           .with.property('city')
               .that.is.a('string')
               .and.equals('Detroit')

    View Slide

  67. testingFramework

    View Slide

  68. mocha simple, flexible, fun

    View Slide

  69. mocha
    github:
    install:
    visionmedia/mocha
    npm install -g mocha

    View Slide

  70. $  npm  install  -­‐g  mocha
    $  mkdir  test
    $  mocha
       
       ✔  0  tests  complete  (1ms)
    $  

    View Slide

  71. var  mocha  =  require('mocha');

    View Slide

  72. describe('Testing  out  this  thing',  function()  {
           it('should  do  stuff',  function()  {
                   //  Assertion  tests
           });
    });
    bddSyntax

    View Slide

  73. ./test/my-test.js
    var assert = require('assert');
    describe('Assertions', function() {
    it('should pass on truthiness', function() {
    assert.ok(true);
    });
    it('should fail on falsiness', function() {
    assert.ok(false);
    });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  74. $  mocha  -­‐-­‐reporter  spec
       Assertions
           ✓  should  pass  on  truthiness  
           1)  should  fail  on  falsiness
       ✖  1  of  2  tests  failed:
       1)  Assertions  should  fail  on  falsiness:
             
       AssertionError:  false  ==  true
               at  (stack  trace  omitted  for  brevity)
    $  _

    View Slide

  75. groupedTests

    View Slide

  76. describe('Testing  out  this  thing',  function()  {
           describe('with  a  subset  of  this  other  thing',  function()  {
                   it('should  do  stuff',  function()  {
                           //  Assertion  tests
                   });
           });
    });
    groupSyntax

    View Slide

  77. var expect = require('chai').expect;
    describe('Assertions', function() {
    describe('on equality', function() {
    it('should pass on truthiness', function() {
    expect(true).is.true;
    });
    it('should pass on falsiness', function() {
    expect(false).is.false;
    });
    });
    describe('on type', function() {
    it('should pass on number', function() {
    expect(5).is.a('number');
    });
    });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  78. $  mocha  -­‐-­‐reporter  spec
       Assertions
           of  equality
               ✓  should  pass  on  truthiness  
               ✓  should  pass  on  falsiness  
           on  type
               ✓  should  pass  on  number  
       ✔  3  tests  complete  (6ms)
    $  _

    View Slide

  79. pendingTests

    View Slide

  80. describe('Testing  out  this  thing',  function()  {
           describe('with  a  subset  of  this  other  thing',  function()  {
                   it('should  do  stuff  someday');
           });
    });
    pendingSyntax

    View Slide

  81. var assert = require('chai').assert;
    describe('Assertions', function() {
    describe('of truthiness', function() {
    it('should pass on truthiness', function() {
    expect(true).is.true;
    });
    it('should pass on falsiness', function() {
    expect(false).is.false;
    });
    });
    describe('of type', function() {
    it('should pass on number', function() {
    expect(5).is.a('number');
    });
    it('should pass on object');
    });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  82. $  mocha  -­‐-­‐reporter  spec
       Assertions
           of  truthiness
               ✓  should  pass  on  truthiness
               ✓  should  pass  on  falsiness
           of  type
               ✓  should  pass  on  number  
               -­‐  should  pass  on  object
       ✔  4  tests  complete  (6ms)
       •  1  test  pending
    $  _

    View Slide

  83. skippedTests

    View Slide

  84. describe('Testing  out  this  thing',  function()  {
           it.skip('should  be  skipped',  function()  {
                   //  Assertion  tests
           });
    });
    describe.skip('This  entire  suite  will  be  skipped',  function()  {
           it('should  do  stuff',  function()  {
                   //  Assertion  tests
           });
    });
    skipSyntax

    View Slide

  85. describe('Assertions', function() {
    describe('of truthiness', function() {
    it('should pass on truthiness', function() {
    assert.isTrue(true);
    });
    it('should pass on falsiness', function() {
    assert.isFalse(false);
    });
    });
    describe('of type', function() {
    it.skip('should pass on number', function() {
    assert.isNumber(5);
    });
    it('should pass on object');
    });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  86. $  make  test
       Assertions
           of  truthiness
               ✓  should  pass  on  truthiness  
               ✓  should  pass  on  falsiness  
           of  type
               -­‐  should  pass  on  number  
               -­‐  should  pass  on  object
       ✔  4  tests  complete  (6ms)
       •  2  test  pending
    $  _

    View Slide

  87. setupTeardown

    View Slide

  88. before();
    beforeEach();
    after();
    afterEach();

    View Slide

  89. describe('Testing  out  this  thing',  function()  {
           before(function(){
                   //  ...
           };
           describe('with  a  subset  of  that  thing',  function()  {
                   it('should  do  stuff',  function()  {
                           //  Assertion  tests
                   });
                   afterEach(function(){
                           //  ...
                   };
           });
    });
    setupTeardown

    View Slide

  90. asynchronousTests

    View Slide

  91. it('should  not  error',  function(done)  {
           search.find("Apples",  done);
    });
    asynchronousSyntax

    View Slide

  92. it('should  not  error',  function(done)  {
           search.find("Apples",  done);
    });
    it('should  return  2  items',  function(done)  {
           search.find("Apples",  function(err,  res)  {
                   if  (err)  return  done(err);
                   res.should.have.length(2);
                   done();
           });
    });
    asynchronousSyntax

    View Slide

  93. All Mocha functions accept this callback

    View Slide

  94. describe('When searching for Apples', function(done) {
    before(function(done){
    items.save(['fiji apples',
    'empire apples'], done);
    });
    it('should not error', function(done) {
    search.find("Apples", done);
    });
    it('should return 2 items', function(done) {
    search.find("Apples", function(err, res) {
    if (err) return done(err);
    res.should.have.length(2);
    done();
    });
    });
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  95. simplifyExecution

    View Slide

  96. $  mocha  
    should be simplified to
    $  make  test and $  npm  test

    View Slide

  97. ./makefile
    # Makefile for sample module
    test:
    mocha --reporter spec --ui bdd
    .PHONY: test
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  98. ./makefile
    # Makefile for sample module
    test:
    mocha \
    --reporter spec \
    --ui bdd
    .PHONY: test
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  99. $  make  test
       Assertions
           ✓  should  pass  on  truthiness  
           1)  should  fail  on  falsiness
       ✖  1  of  2  tests  failed:
       1)  Assertions  should  fail  on  falsiness:
             
       AssertionError:  false  ==  true
               at  (stack  trace  omitted  for  brevity)
    $  _

    View Slide

  100. ./package.json
    {
    "name": "sample",
    "version": "0.1.0",
    "scripts": {
    "test": "make test"
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  101. $  npm  test
       Assertions
           ✓  should  pass  on  truthiness  
           1)  should  fail  on  falsiness
       ✖  1  of  2  tests  failed:
       1)  Assertions  should  fail  on  falsiness:
             
       AssertionError:  false  ==  true
               at  (stack  trace  omitted  for  brevity)
    $  _

    View Slide

  102. eliminate global dependency
    $  npm  install  mocha  -­‐-­‐link

    View Slide

  103. test:
    @./node_modules/.bin/mocha \
    --reporter spec \
    --ui bdd
    .PHONY: test
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  104. update dev dependencies
    $  npm  install  mocha  -­‐-­‐save-­‐dev
    $  npm  install  chai    -­‐-­‐save-­‐dev

    View Slide

  105. $  npm  install  mocha  -­‐-­‐save-­‐dev
    $  npm  install  chai    -­‐-­‐save-­‐dev
    $  git  diff  package.json  
    diff  -­‐-­‐git  a/package.json  b/package.json
    index  439cf44..3609bb9  100644
    -­‐-­‐-­‐  a/package.json
    +++  b/package.json
    @@  -­‐1,5  +1,7  @@
     {
         "name":  "sample",
    -­‐    "version":  "0.1.0"
    +    "version":  "0.1.0",
    +    "devDependencies":  {
    +        "mocha":  "~1.9.0",
    +        "chai":  "~1.6.0"
    +    }
     }

    View Slide

  106. notificationSystems

    View Slide

  107. mocha --watch
    continuousTesting
    -w or --watch

    View Slide

  108. $  mocha  -­‐-­‐watch
     ✔  5  tests  complete  (22ms)
     ^  watching

    View Slide

  109. Growl

    View Slide

  110. mac:
    win:
    also:
    apple app store
    growlForWindows.com
    growlNotify

    View Slide

  111. mocha --growl
    growlNotifications
    -G or --growl

    View Slide

  112. ⌘S

    View Slide

  113. test:
    @./node_modules/.bin/mocha \
    --reporter spec \
    --ui bdd
    watch:
    @./node_modules/.bin/mocha \
    --reporter min \
    --ui bdd \
    --growl \
    --watch
    .PHONY: test watch
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  114. mockingObjects

    View Slide

  115. JavaScript ships with a mocking framework
    ...it’s called JavaScript

    View Slide

  116. var me = {firstName: 'Jay'
    , lastName: 'Harris'
    , getFullName: function() {
    return this.firstName +
    ' ' +
    this.lastName; }};
    // Returns 'Jay Harris'
    me.getFullName();
    me.getFullName = function() { return 'John Doe'; };
    // Returns 'John Doe'
    me.getFullName();
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  117. nock HTTP Mocking Library

    View Slide

  118. nock github:
    install:
    flatiron/nock
    npm install nock

    View Slide

  119. var http = require('http');
    var reqOptions = {
    host: 'api.twitter.com',
    path: '/1/statuses/user_timeline.json?' +
    'screen_name=jayharris'
    };
    // ...
    http.request(reqOptions, resCallback).end();
    // Returns live Twitter data
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  120. var nock = require('nock');
    var twitter = nock('http://api.twitter.com')
    .get('/1/statuses/user_timeline.json?'+
    'screen_name=jayharris')
    .reply(200, "This worked");
    // Returns "This worked"
    http.request(reqOptions, resCallback).end();
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  121. // Returns live Twitter data
    http.request(reqOptions, resCallback).end();
    var nock = require('nock');
    var twitter = nock('http://api.twitter.com')
    .get('/1/statuses/user_timeline.json?'+
    'screen_name=jayharris')
    .reply(200, "This worked");
    // Returns "This worked"
    http.request(reqOptions, resCallback).end();
    // Returns live Twitter data
    http.request(reqOptions, resCallback).end();
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  122. nock nock.recorder.rec(  );
    nock.recorder.play(  );

    View Slide

  123. Spies, Stubs, & Mocks
    Sinon.js

    View Slide

  124. github:
    install:
    cjohansen/Sinon.JS
    npm install sinon
    Sinon.js

    View Slide

  125. versionTesting

    View Slide

  126. nvm Node Version Manager

    View Slide

  127. nvm github:
    github:
    creationix/nvm
    hakobera/nvmw

    View Slide

  128. $  nvm  list
           v0.4.0        v0.6.18        v0.8.21
           v0.4.7          v0.8.1        v0.10.0
           v0.6.0          v0.8.8
    current:    
    v0.8.1
    10  -­‐>  0.10.0  (-­‐>  v0.10.0)
    4  -­‐>  0.4.7  (-­‐>  v0.4.7)
    6  -­‐>  0.6.18  (-­‐>  v0.6.18)
    8  -­‐>  0.8.21  (-­‐>  v0.8.21)
    default  -­‐>  0.10.0  (-­‐>  v0.10.0)
    newest  -­‐>  0.10.0  (-­‐>  v0.10.0)
    $  _

    View Slide

  129. $  node  -­‐-­‐version
    v0.10.0
    $  nvm  install  v0.10.6
    Now  using  node  v0.10.6
    /Users/jayharris/.nvm/v0.10.6/bin/npm
    $  node  -­‐-­‐version
    v0.10.6
    $  _

    View Slide

  130. packageDistribution

    View Slide

  131. Package Manager

    View Slide

  132. ./.npmignore
    filePackaging

    View Slide

  133. npm adduser
    userSetup

    View Slide

  134. $  npm  adduser
    Username:  (jayharris)  jayharris
    Password:
    Email:  ([email protected])  _

    View Slide

  135. $  npm  whoami
    jayharris
    $  _

    View Slide

  136. npm publish
    packagePublish

    View Slide

  137. {  name:  'morale',
       description:  'Async  API  wrapper  for  Morale',
       'dist-­‐tags':  {  latest:  '0.2.0'  },
       versions:  
         [  '0.1.0',
             '0.1.2',
             '0.2.0'  ],
       maintainers:  'jayharris  ',
       time:  
         {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',
             '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',
             '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z'  },
       author:  'Arana  Software  ',
       repository:  
         {  type:  'git',
             url:  'git://github.com/aranasoft/morale-­‐node.git'  },
       users:  {  fgribreau:  true  },
       version:  '0.2.0',

    View Slide

  138. $  npm  publish
    npm  http  PUT  https://registry.npmjs.org/morale
    npm  http  409  https://registry.npmjs.org/morale
    npm  http  GET  https://registry.npmjs.org/morale
    npm  http  200  https://registry.npmjs.org/morale
    npm  http  PUT  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
    npm  http  201  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
    npm  http  GET  https://registry.npmjs.org/morale
    npm  http  200  https://registry.npmjs.org/morale
    npm  http  PUT  https://registry.npmjs.org/morale/-­‐/
    morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
    npm  http  201  https://registry.npmjs.org/morale/-­‐/
    morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
    +  [email protected]
    $  _

    View Slide

  139. {  name:  'morale',
       description:  'Async  API  wrapper  for  Morale',
       'dist-­‐tags':  {  latest:  '0.2.1'  },
       versions:  
         [  '0.1.0',
             '0.1.2',
             '0.2.0',
             '0.2.1'  ],
       maintainers:  'jayharris  ',
       time:  
         {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',
             '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',
             '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z',
             '0.2.1':  '2012-­‐08-­‐30T19:10:20.133Z'  },
       author:  'Arana  Software  ',
       repository:  
         {  type:  'git',
             url:  'git://github.com/aranasoft/morale-­‐node.git'  },

    View Slide

  140. { "private": "true" }
    privatePackages

    View Slide

  141. ./package.json
    {
    "name": "Sample",
    "version": "0.1.0",
    "description": "This is a sample module",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no tests avail.\" && exit 1"
    },
    "author": "Jay Harris",
    "license": "BSD",
    "private": "true"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    View Slide

  142. $  npm  publish
    npm  ERR!  Error:  This  package  has  been  marked  as  private
    npm  ERR!  Remove  the  'private'  field  from  the  package.json  to  
    publish  it.
    $  _

    View Slide

  143. npm shrinkwrap
    versionLockdown

    View Slide

  144. $  npm  shrinkwrap
    wrote  npm-­‐shrinkwrap.json
    $  _

    View Slide

  145. {
    "name": "morale",
    "version": "0.2.1",
    "dependencies": {
    "underscore": {
    "version": "1.3.3"
    },
    "mocha": {
    "version": "1.3.0",
    "dependencies": {
    "commander": {
    "version": "0.6.1"
    },
    "growl": {
    "version": "1.5.1"
    },
    "jade": {
    "version": "0.26.3",
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    View Slide

  146. $  rm  npm-­‐shrinkwrap.json
    $  npm  update
    $  npm  test
    $  npm  shrinkwrap

    View Slide

  147. tellEveryone

    View Slide

  148. Go make some Awesome

    View Slide

  149. jay harris
    P R E S I D E N T
    [email protected]
    #nodemoduledev
    @jayharris

    View Slide