How To Create Custom NPM Modules

In the previous article How To Use Node Package Manager, we have learned what NPM is and how to use it to install, uninstall, update and search third-party NPM modules. This article will tell you how to create your own NPM modules.

1. NPM Module Directory Structure.

  1. If you install a third-party node module like Async locally, you can see a directory which name is async is created in your project node_modules folder. In that folder, there are a lot of JS files and particularly a package.json file.
  2. Each node module must contain a package.json file. It is a JSON format text file that describes the node module-related information such as author, homepage, license, main file, version, name, keywords, dependencies, repository, etc.
  3. Below is the async module package.json file content.
    {
     "_from": "async",
     "_id": "[email protected]",
     "_inBundle": false,
     "_integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
     "_location": "/async",
     "_phantomChildren": {},
     "_requested": {
     "type": "tag",
     "registry": true,
     "raw": "async",
     "name": "async",
     "escapedName": "async",
     "rawSpec": "",
     "saveSpec": null,
     "fetchSpec": "latest"
     },
     "_requiredBy": [
     "#USER"
     ],
     "_resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
     "_shasum": "61a29abb6fcc026fea77e56d1c6ec53a795951f4",
     "_spec": "async",
     "_where": "/Users/zhaosong/Documents/WorkSpace/dev2qa.com-example-code/JavaScriptExampleWorkspace/NodeJSWorkspace/AsyncExecute",
     "author": {
     "name": "Caolan McMahon"
     },
     "bugs": {
     "url": "https://github.com/caolan/async/issues"
     },
     "bundleDependencies": false,
     "dependencies": {
     "lodash": "^4.14.0"
     },
     "deprecated": false,
     "description": "Higher-order functions and common patterns for asynchronous code",
     "devDependencies": {
     "babel-cli": "^6.24.0",
     "babel-core": "^6.24.0",
     "babel-plugin-add-module-exports": "^0.2.1",
     "babel-plugin-istanbul": "^2.0.1",
     "babel-plugin-transform-es2015-modules-commonjs": "^6.3.16",
     "babel-preset-es2015": "^6.3.13",
     "babel-preset-es2017": "^6.22.0",
     "babelify": "^7.2.0",
     "benchmark": "^2.1.1",
     "bluebird": "^3.4.6",
     "chai": "^3.1.0",
     "cheerio": "^0.22.0",
     "coveralls": "^2.11.2",
     "es6-promise": "^2.3.0",
     "eslint": "^2.13.1",
     "fs-extra": "^0.26.7",
     "gh-pages-deploy": "^0.4.2",
     "jsdoc": "^3.4.0",
     "karma": "^1.3.0",
     "karma-browserify": "^5.1.0",
     "karma-firefox-launcher": "^1.0.0",
     "karma-mocha": "^1.2.0",
     "karma-mocha-reporter": "^2.2.0",
     "mocha": "^3.1.2",
     "native-promise-only": "^0.8.0-a",
     "nyc": "^7.0.0",
     "recursive-readdir": "^1.3.0",
     "rimraf": "^2.5.0",
     "rollup": "^0.36.3",
     "rollup-plugin-node-resolve": "^2.0.0",
     "rollup-plugin-npm": "^2.0.0",
     "rsvp": "^3.0.18",
     "semver": "^4.3.6",
     "uglify-js": "~2.7.3",
     "vinyl-buffer": "^1.0.0",
     "vinyl-source-stream": "^1.1.0",
     "watchify": "^3.7.0",
     "yargs": "~3.9.1"
     },
     "gh-pages-deploy": {
     "staticpath": "docs"
     },
     "homepage": "https://caolan.github.io/async/",
     "keywords": [
     "async",
     "callback",
     "module",
     "utility"
     ],
     "license": "MIT",
     "main": "dist/async.js",
     "name": "async",
     "nyc": {
     "exclude": [
     "mocha_test"
     ]
     },
     "repository": {
     "type": "git",
     "url": "git+https://github.com/caolan/async.git"
     },
     "scripts": {
     "coverage": "nyc npm run mocha-node-test -- --grep @nycinvalid --invert",
     "coveralls": "npm run coverage && nyc report --reporter=text-lcov | coveralls",
     "jsdoc": "jsdoc -c ./support/jsdoc/jsdoc.json && node support/jsdoc/jsdoc-fix-html.js",
     "lint": "eslint lib/ mocha_test/ perf/memory.js perf/suites.js perf/benchmark.js support/build/ support/*.js karma.conf.js",
     "mocha-browser-test": "karma start",
     "mocha-node-test": "mocha mocha_test/ --compilers js:babel-core/register",
     "mocha-test": "npm run mocha-node-test && npm run mocha-browser-test",
     "test": "npm run lint && npm run mocha-node-test"
     },
     "version": "2.6.0"
    }

2. Create Custom NPM Module.

  1. Run the below command in a terminal, it will create a module custom_module_1‘s package.json file in the current project node_modules folder.
    $ mkdir node_modules
    
    $ cd node_modules
    
    $ mkdir custom_module_1
    
    $ cd custom_module_1
    
    $ npm init
    
    This utility will walk you through creating a package.json file.
    
    It only covers the most common items, and tries to guess sensible defaults.
    
    See `npm help json` for definitive documentation on these fields
    
    and exactly what they do.
    
    Use `npm install <pkg>` afterwards to install a package and
    
    save it as a dependency in the package.json file.
    
    Press ^C at any time to quit.
    
    package name: (node_modules) custom_module_1
    
    version: (1.0.0) 
    
    description: This is a custom node module just for example
    
    entry point: (index.js) 
    
    test command: make test.js
    
    git repository: 
    
    keywords: test example
    
    author: jerry zhao
    
    license: (ISC) Apache
    
    Sorry, license should be a valid SPDX license expression (without "LicenseRef"), "UNLICENSED", or "SEE LICENSE IN <filename>" and license is similar to the valid expression "Apache-2.0".
    
    license: (ISC) ISC
    
    About to write to /Users/zhaosong/Documents/WorkSpace/dev2qa.com-example-code/JavaScriptExampleWorkspace/NodeJSWorkspace/AsyncExecute/node_modules/package.json:
    
    {
    
      "name": "custom_module_1",
    
      "version": "1.0.0",
    
      "description": "This is a custom node module just for example",
    
      "main": "index.js",
    
      "scripts": {
    
        "test": "make test.js"
    
      },
    
      "keywords": [
    
        "test",
    
        "example"
    
      ],
    
      "author": "jerry zhao",
    
      "license": "ISC"
    
    }
    
    Is this OK? (yes)
  2. After running the above code, you can see the custom module’s package.json file is created in node_modules/custom_module_1 directory with the below content.
  3. package.json file content example.
    {
     "name": "custom_module_1",
     "version": "1.0.0",
     "description": "This is a custom node module just for example",
     "main": "index.js",
     "scripts": {
     "test": "make test.js"
     },
     "keywords": [
     "test",
     "example"
     ],
     "author": "jerry zhao",
     "license": "ISC"
    }

3. Publish Custom NPM Module To NPM Repository.

  1. If you want to publish the created custom node module to the npmjs.com repository. You can execute the command $ npm adduser to achieve it.
    $ npm adduser
    Username: jerry-zhao
    Password: 
    Email: (this IS public) [email protected]
    Logged in as jerry-zhao on https://registry.npmjs.org/.
  2. This command will add a user in the npmjs.com repository, just follow the prompt and input related user info.
  3. Please note npmjs.com will send a verification email to your email box to verify that you are a real valid user.
  4. Remember the user name and password carefully, you will use them later.
  5. Then execute command $ npm publish in node_modules/custom_module_1 directory to publish the node module to npmjs.com repository.
  6. After that login to www.npmjs.com with the just-created user name and password and then you can see your NPM module in it.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.