Tuesday 16 June 2020

create an npm package with a simple node.js module on ubuntu

Today I want to create a npm package for a simple javascriptlibrary with modules and some tests. Src:https://egghead.io/lessons/javascript-how-to-write-a-javascript-library-configuring-npm-and-creating-a-package-json

At first we need a git repository on github.

Create a repository named "starwarsNames"

Login into your github account and create a new repository "starwarsNames"

echo "# starwarsNames" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/pboethig/starwarsNames.git
git push -u origin master

create an account on https://www.npmjs.com, if you dont have one
You will need an account there to publish your extension. 

Remember your <npm-username> you will need it.

Install nodejs
$ apt-get install nodejs
$ sudo ln -s /usr/bin/nodejs /usr/bin/node  

Install npm, if npm is not installed 
$ apt-get install npm 


If you are on windows you have to install it manualy, If you are on mac, you can use the packagemanager,

At next we inititialize the npm project. 
$ npm set init-author-name 'Your Name'
$ npm set init-author-email 'your email'
$ npm set init-author-license 'MIT'
$ npm set save-exact true

If you want to check that config, you can do it with
$ cat ~/.npmrc

Add your npm user to your project 
$ npm adduser
Username: <your npm-username>
Password: <your npm-password>
Email: (this IS public) <your npm-email>

Initilize your npm project
$ npm init

this will ask some data from you, and puts outs the package.json for you

name: (starwars-names-<your npm username>)
version: (1.0.0)
license: (MIT)
About to write to /var/www/html/starwarsNames/package.json:

{
  "name": "starwars-names",
  "version": "1.0.0",
  "description": "get random starwars names",
  "main": "src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://git@github.com/pboethig/starwarsNames.git"
  },
  "keywords": [
    "random",
    "starwars"
  ],
  "author": "pboethig",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/pboethig/starwarsNames/issues"
  },
  "homepage": "https://github.com/pboethig/starwarsNames#readme"
}

Okay. Lets create our first module:
- create a folder "src" in your projectroot to store our module sources.
- now , create a file "index.js" in the new src folder

Open this new file in your code editor. I am using vscode for it. That editor  has great node.js plugins.

Now we want to define our modulestructure. 
Type following code in index.js

var starWarsNames = require('./starwars-names.json');
module.exports =
{
    all,
    random
};
             


 
This tells node that you want to store the "starwars-names.json" list in a variable, that your module will use and it exports 2 properties ("all" and "random")

At next save the starwarsnames in a file "starwars-names.json" in your "src" folder:
 
 
[
  "4-LOM",
  "Ayla Secura",
  "Admiral Ackbar",
  "Ahsoka Tano",
  "Anakin Solo",
  "Asajj Ventress",
  "Aurra Sing",
  "Senator Bail Organa",
  "Barris Offee",
  "Bastila Shan",
  "Ben Skywalker",
  "Bib Fortuna",
  "Boba Fett",
  "Bossk",
  "Brakiss",
  "C-3PO",
  "Cad Bane",
  "Cade Skywalker",
  "Callista Ming",
  "Captain Rex",
  "Carnor Jax",
  "Chewbacca",
  "Clone Commander Cody",
  "Count Dooku",
  "Darth Bane",
  "Darth Krayt",
  "Darth Malgus",
  "Darth Maul",
  "Darth Nihilus",
  "Darth Vader",
  "Dash Rendar",
  "Dengar",
  "Durge",
  "Emperor Palpatine",
  "Exar Kun",
  "Galen Marek",
  "General Crix Madine",
  "General Dodonna",
  "General Grievous",
  "General Veers",
  "Gilad Pellaeon",
  "Grand Moff Tarkin",
  "Greedo",
  "Han Solo",
  "IG 88",
  "Jabba The Hutt",
  "Jacen Solo",
  "Jaina Solo",
  "Jango Fett",
  "Jarael",
  "Jerec",
  "Joruus CBaoth",
  "Kent C. Dodds",
  "Ki-Adi-Mundi",
  "Kir Kanos",
  "Kit Fisto",
  "Kueller",
  "Kyle Katarn",
  "Kyp Durron",
  "Lando Calrissian",
  "Luke Skywalker",
  "Luminara Unduli",
  "Lumiya",
  "Mace Windu",
  "Mara Jade",
  "Mission Vao",
  "Natasi Daala",
  "Nom Anor",
  "Obi-Wan Kenobi",
  "Padmé Admidala",
  "Plo Koon",
  "Pre Vizsla",
  "Prince Xizor",
  "Princess Leia",
  "Proxy",
  "Qui-Gon Jinn",
  "Quinlan Vos",
  "R2-D2",
  "Rahm Kota",
  "Satele Shan",
  "Savage Opress",
  "Sebulba",
  "Shaak Ti",
  "Shmi Skywalker",
  "Talon Karrde",
  "Ulic Qel-Droma",
  "Visas Marr",
  "Watto",
  "Wedge Antilles",
  "Yoda",
  "Zam Wesell",
  "Zayne Carrick",
  "Zuckuss"
]

At next we need a further npm library called unique-random-array.
Lets install it with:

$ npm install --save unique-random-array

This will save the new library to our dependency definition in package.json

Now lets use the new array library in our index.js
 
var uniqueRandomArray = require('unique-random-array');
var starWarsNames = require('./starwars-names.json');
module.exports =
{
    all,
    random
};


Our index.js now looks like that

var uniqueRandomArray = require('unique-random-array');
var starWarsNames = require('./starwars-names.json');
module.exports =
{
    all: starWarsNames,
    random:uniqueRandomArray(starWarsNames)
};
Now that we have the library included, lets use it in our module.

In the export function, we want to reference all starwars-names to the property "all" and a random startwars-name to the property "random".

To to that we only have to export the local variable "starwarsNames" to the global scope by referencing the  exportproperty "all" and the array-function uniqueRandomArray(starwarsNames) from our new library to the export-property "random". Here is the code of "index.js".
Now our index.js looks like that 

 var uniqueRandomArray = require('unique-random-array');
var starWarsNames = require('./starwars-names.json');
module.exports =
{
    all: starWarsNames,
    random:uniqueRandomArray(starWarsNames)
};

Yeah, we havehacked our first node module.

Lets test it!
- open a terminal and navigate to the root folder of your app 
$ node
$ var starwarsNames = require('./src/index.js');
$ starwarsNames.all
$ starwarsNames.random()  

The single commands will output the whole list of names and a random name from the list. Thats realy great!


Now we want to publish it in npm as an own package. 
For that, we have to commit it to our git repository.

open a terminal:
$ cmd to your projectroot
$ touch .gitignore
$ nano .gitignore

add "node_modules" to your .gitignore to prevent commiting the node_modules.

$ git add *
$ git commit -m "init"
$ git push origin master

Thats it.

Now we can publish it to npm.
Thats realy simple.

Just type:
$ npm publish

That it. Now you should directly see your new package on npm !

This is awesome!

Now we want to test, if our module is directly usable via npm.
- open a terminal to the desktop 
$ npm install starwars-names-<your npm_user> 

Super. Now you can use your library, from anywhere in the world.
switch to the desktop and create a file named "test.js" with following content:

var starwarsNames = require('starwars-names-mittax');
console.log(starwarsNames.all);
console.log(starwarsNames.random());

Now run a terminal and cd to the directory where you have stored test.js and run:
$ node test.js

You will now see the results from your library.

This is realy cool!


Thanky to Kent.C.Dotts for the great video!