How to publish common module with reusable functions to npm registry
Tags: npm, typescript, tutorial
Published: 2023-03-21 17:06:06

In [previous post](https://dev.to/bellabe/automate-ethereum-based-smart-contract-abi-load-with-typescript-5737) post we have created a common module of reusable functions with the intention to publish it to npm registry. Here is a quick guide on how to do it.

#### STEP 1: Create an Organisation within your npm account

There are 3 popular options to publish a package into npm registry: 
- public - package available to everybody at no cost;
- public or private within an Organisation - package available to  members of an Organisation, at a cost if private, at no cost if public;
- private - package with granted access.

We are not storing any sensitive information, so we will create a public package within an Organisation. Follow the [link](https://www.npmjs.com/org/create) to do so. Once it is ready, we should update `name` field in `package.json` file, I have named mine `crypto-project`. 

```javascript
{
  "name": "@crypto-project/common",
  "version": "1.0.0",
  "description": "Module contains helper functions to be used in crypto project",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^5.0.2"
  },
  "dependencies": {
    "axios": "^1.3.4"
  }
}
```

#### STEP 2: Create git repository and commit

In order to publish our package to npm registry, we should init git repository and do the commit. Before proceeding add `.gitignore` file to exclude `node_modules`

```javascript
touch .gitignore && echo "node_modules" > .gitignore
```

Run git init and do commit

```javascript
git init
git add .
git commit -m "initial commit"
```

#### STEP 3: Compile typescript to javascript

We will publish our package as javascript one. Update `tsconfig.json` file: uncomment `"declaration": true` and  `"outDir": "./build"` fields. 

```javascript
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./build",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

```

Update `.gitignore` file to exclude `build` directory from commit

```javascript
echo "build" > .gitignore
```

Add `build` command to `package.json` file, adjust project entry point, add `types` field to indicate types definition entry point, add `files` field to indicate which files to include from our build directory

```javascript
{
  "name": "@crypto-project/common",
  "version": "1.0.0",
  "description": "Module contains helper functions to be used in crypto project",
  "main": "./build/index.js",
  "types": "./build/index.d.ts",
  "files": [
    "build/**/*"
  ],
  "scripts": {
    "build": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "typescript": "^5.0.2"
  },
  "dependencies": {
    "axios": "^1.3.4"
  }
}

``` 

`Build` command should be run every time we update our package, previous build should be removed. Let's use helper package `del-cli` to automate the process

```javascript
npm install -D del-cli
```

Once it is installed, update `package.json` file

```javascript
{
  "name": "@crypto-project/common",
  "version": "1.0.0",
  "description": "Module contains helper functions to be used in crypto project",
  "main": "./build/index.js",
  "types": "./build/index.d.ts",
  "files": ["build/**/*"],
  "scripts": {
    "clean": "del ./build/*",
    "build": "npm run clean && tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "del-cli": "^5.0.0",
    "typescript": "^5.0.2"
  },
  "dependencies": {
    "axios": "^1.3.4"
  }
}
```

#### STEP 4.A: First publish

we are ready to publish our package, type the following command in your terminal (root of the package)

```javascript
npm publish --access public
```

You should see the following output

```javascript
npm notice 
npm notice 📦  @crypto-project/common@1.0.0
npm notice === Tarball Contents === 
npm notice 338B  package.json                         
npm notice 91B   src/index.ts                         
npm notice 468B  src/smart-contract-utils/abi.ts      
npm notice 134B  src/smart-contract-utils/types/abi.ts
npm notice 5.9kB tsconfig.json                        
npm notice === Tarball Details === 
npm notice name:          @crypto-project/common                  
npm notice version:       1.0.0                                   
npm notice filename:      @crypto-project/common-1.0.0.tgz        
npm notice package size:  2.6 kB                                  
npm notice unpacked size: 6.9 kB                                  
npm notice shasum:        5c9084c410eaf3855e6b568206f2a3a9bad6f528
npm notice integrity:     sha512-al7DDvmUOhVeI[...]7rJzedBAjfSgw==
npm notice total files:   5                                       
npm notice 
npm notice Publishing to https://registry.npmjs.org/
+ @crypto-project/common@1.0.0
```

If the output is an error instead, make sure you are logged in by typing `npm login` and entering the same username and password you use to login `npmjs.com`.


#### STEP 4.B: Publish after a change

To publish after a change we should follow a slightly different flow and it consists of following steps:
- update git repository
- increment version (most popular are `patch`, `minor`, `mahor`)
- build
- publish

Last 3 steps could be wrapped into one script, let's add it to our `package.json` file

```javascript
{
  "name": "@crypto-project/common",
  "version": "1.0.0",
  "description": "Module contains helper functions to be used in crypto project",
  "main": "./build/index.js",
  "types": "./build/index.d.ts",
  "files": [
    "build/**/*"
  ],
  "scripts": {
    "clean": "del ./build/*",
    "build": "npm run clean && tsc",
    "pub": "npm version patch && npm run build && npm publish"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "del-cli": "^5.0.0",
    "typescript": "^5.0.2"
  },
  "dependencies": {
    "axios": "^1.3.4"
  }
}
```

That's it. We have our base package and we are able to publish/re-publish it to npm registry. Link to github repo is [here](https://github.com/BellaBe/common).