4

Developing and publishing a TypeScript NPM package

 3 years ago
source link: https://codeburst.io/developing-and-publishing-a-typescript-npm-package-d9fc643d4229
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Developing and publishing a TypeScript NPM package

We’ll also cover unit testing, test coverage, and code analysis

A picture of a dog sitting in front of boxes looking at the camera.
A picture of a dog sitting in front of boxes looking at the camera.
Image from Unsplash.

Introduction

Ever wondered how to publish your very own npm package to the npmjs.com registry? In this article, I’ll take you through the step-by-step process. We’ll start by developing a very simple npm package using TypeScript. Next, we’ll add unit tests to confirm the accuracy of the functionality we’re developing and while we’re at it, we’ll also produce a test coverage report. After that, we’ll use static code analyzers to help us improve our code quality. Finally, we’ll make use of some command-line magic to publish this package to npmjs.com. Doesn’t that sound exciting? Let’s begin.

Note: The steps below are mentioned in a linear fashion for brevity. In reality, you might find yourself doing things iteratively — and that’s okay.

Step 1: Develop

Initialize files and folders

In your project folder type in the command npm init -y. This will create an empty npm project with a sample package.json file. Let’s not worry about that for now — we’ll update it later.

You would also want to create a README.md file to write up an overview of your npm package, a LICENSE file which will contain the appropriate license text, and a .gitignore file which will tell Git what files and folders should not be source-controlled. We’ll also create a src folder which will contain all of our source code.

Image of source code directory.
Image of source code directory.

Adding some code

Let’s populate the src folder with some actual code. We’ll be using TypeScript for this demo which will then get compiled to JavaScript.

Create a file called add-demo-npm.ts in the src folder — this file will be the entry point for our package. You can name this file whatever you like, I just like naming it the same name as my npm package name. Write the following piece of code to include a simple add method.

Compiling code

Now, we want our TypeScript code to compile to JavaScript. To do so, let’s install the TypeScript module using the command npm i typescript -D. In your package.json file, replace “main”: “index.js”, with “main”: “./dist/add-demo-npm.js”, keeping the rest of the contents the same.

Next, let’s create a tsconfig.json file with the following contents. This tells the TypeScript compiler how to compile, where to place the output files and what folders to exclude from the compilation.

Now, update the scripts section of the package.json file to add a build script like the snippet below.

Tip: Where possible, I try to use a config file to supply the command-line tool additional options thereby keeping the actual command to a bare minimum. It looks a lot cleaner and is very readable.

To compile, execute the command npm run build. You should see a folder named dist being created with the compiled JavaScript file and a corresponding TypeScript definition file.

Image of the dist folder with compiled files in it.
Image of the dist folder with compiled files in it.

Step 2: Adding some tests

We want to ensure that the code we’re writing works well in all scenarios. The easiest way to do so is to write tests that cover different scenarios.

We’ll be using Mocha as the JavaScript testing framework and Chai as the assertion library. Since we’re testing source code written in TypeScript, we’ll be using ts-mocha which is a thin TypeScript wrapper to use Mocha.

Let’s install the npm packages ts-mocha, mocha, chai and their type definitions @types/mocha and @types/chai.

Tip: You can install multiple npm packages with a single command using the format npm i -D package1 package2 packageN.

Next, create a folder in your root directory called tests and create a file called add-demo-npm.test.ts. I like to name the test file the same as the file we’ll be unit testing. Copy the code snippet below into your file and feel free to add more tests if you like.

Then update the test script in the scripts section of the package.json file to execute the tests as shown below.

Run npm test to execute these tests and confirm all unit tests are passing.

Image of all unit tests passing.
Image of all unit tests passing.

Test coverage

We’ll be using nyc to add test coverage on top of our Mocha tests. Let’s run npm i nyc -D to install this npm package.

Next, let’s add a config file named .nycrc.json with the contents from the code snippet below. The config file tells nyc how to execute, what file types to include, what reporters (a.k.a. output formats) to use, and what is the benchmark (which can be updated to any number you like) to compare the results with. A full list of reporters can be found here.

Update the scripts section in the package.json file with the command to execute nyc as shown below.

Finally, we’ll run the command npm run coverage to see this in action.

Image of test coverage summary report.
Image of test coverage summary report.

Step 3: Code analysis

Linting using ESLint

ESLint analyzes code to find and report problems and enforces rules so you have a consistent style of coding.

To install, run the command npm i eslint -D. Next, add a config file named .eslintrc.json and paste the contents from the code snippet below into this config file. Since ESLint is completely configurable, you can customize this file as required. The official guide to configuring ESLint can be found here.

Since we’re using the @typescript-eslint/parser parser and @typescript-eslint/eslint-plugin plugin, we’ll need to install these npm packages as a dev dependency as well.

Add the required commands to lint the TypeScript files in the scripts section of the package.json file as shown in the code snippet below.

Execute npm run lint to perform the lint operation. To test, remove the whitespace between numbers and brackets and execute the command again — you should get an error.

Image of a function highlighting the whitespace to remove so ESLint can be tested.
Image of a function highlighting the whitespace to remove so ESLint can be tested.

You can add or remove rules as you see fit for your project. Full list of rules can be found here.

Code quality using SonarCloud

SonarCloud is a static code analyzer that scans your source code and assesses metrics like maintainability, reliability, duplication, and also identifies security issues. It’s more in-depth than just using ESLint.

I have my source code in GitHub, so I’ll quickly walk you through how you might connect SonarCloud with your GitHub repository.

Head over to sonarcloud.io and click on GitHub to hook your repository.

Screenshot of SonarCloud’s home page.
Screenshot of SonarCloud’s home page.

You may be asked to log in and authorize SonarCloud app in GitHub — grant the required permissions when asked. Once you head over to your SonarCloud projects dashboard page, click on the ‘+’ icon and then from the dropdown, select ”analyze new project”.

Screenshot of SonarCloud projects home page and arrows pointing the buttons to click.
Screenshot of SonarCloud projects home page and arrows pointing the buttons to click.

Search for your repository, check the box beside it, and then click on the Set Up.

Image showing the steps to add a GitHub repository to SonarCloud.
Image showing the steps to add a GitHub repository to SonarCloud.

SonarCloud will start analyzing your project and show you the first analysis report.

Screenshot of SonarCloud analyzing the source code for the first time.
Screenshot of SonarCloud analyzing the source code for the first time.

Before wrapping things up with SonarCloud, there’s one additional thing you’d require to do before you can get a quality gate from SonarCloud. Click on Administration and from the dropdown, select New Code. Then, select the Previous version from the list of options. This means that the quality gate will be computed every time new code is checked in and all the metrics will focus on what has just changed.

Image showing the steps to set new code definition in SonarCloud.
Image showing the steps to set new code definition in SonarCloud.

What’s awesome about SonarCloud is that it triggers an analysis on every new pull request and adds a comment on your GitHub pull request with a summary about the analysis.

Screenshot of a SonarCloud quality gate comment in a GitHub pull request.
Screenshot of a SonarCloud quality gate comment in a GitHub pull request.

If you head over to the Overview tab in SonarCloud, you can see various metrics, and should one of those tiles need your attention, you can click on it to find out more and make the required code changes.

Screenshot of SonarCloud’s overview tab.
Screenshot of SonarCloud’s overview tab.

Step 4: Housekeeping

Updating the package.json file

Before we go ahead and publish the npm package, we’ll need to update the package.json file. See this commit diff to see what has been updated and the code snippet below to see what the final version of the package.json file looks like.

A full explanation on each item of the package.json file can be found here. However, here are a couple of special mentions:

  • The name of the npm package is the most important item in the package.json file as that value uniquely identifies your package. Apart from the rules outlined here, I would recommend researching an apt name for your npm package and then not changing this value ever.
  • The value entered in the description doesn’t actually show up on the npm package page but shows up in the search results when you search for one.
  • The version number has to be of a valid semver format.
  • The license identifier should be one from the SPDX license list and ideally should also be OSI approved.
  • Only add npm packages to the dependencies section if your npm package requires them once installed on users' machines. All the other npm packages that you require during development goes into the devDependencies section.
  • You can add any number of custom scripts into the scripts section. Think of this like adding aliases to running your actual command instead of actually typing it out.

Readme file

Update the contents of the readme file to be as detailed as possible, thereby, making it very clear for other developers to consume your npm package easily. This file is written in Markdown format and the npm package page converts Markdown contents to HTML.

Step 5: Publish

Publishing via the command-line interface (CLI)

We’ll be publishing our npm package to npmjs.com using a command-line interface (CLI). A full list of available commands can be found here.

Login

Head over to npmjs.com and sign up for a new account if you don’t have one already. Next, open up a terminal in Visual Studio Code, and type in the command npm adduser. Then, enter the username, password, and email address associated with your account.

Screenshot showing npm adduser command in action.
Screenshot showing npm adduser command in action.

Getting help

At any given time, should you require help with any of the commands, just type the command followed by -help.

Screenshot showing how to get help for a command in npm.
Screenshot showing how to get help for a command in npm.

Confirm log in

To confirm that you are logged in to npm using CLI, type in the command npm whoami which should return the logged-in username.

What am I distributing?

To check what files will be packaged into your npm package, we can use the command npm publish --dry-run. Running this will not publish your npm package.

Screenshot showing npm dry-run command in action.
Screenshot showing npm dry-run command in action.

Publish!

Finally, when you’re ready to publish your npm package, type in the command npm publish. This will publish your npm package and within minutes, you should also get a confirmation email.

Screenshot showing npm publish command in action.
Screenshot showing npm publish command in action.

Package page on npmjs.com

Once published, you should be able to view your npm package page. Here are a couple of points highlighted.

Screenshot of the demo npm package’s public page.
Screenshot of the demo npm package’s public page.
  1. Readme: The contents of the readme file will appear on your npm package page. Markdown is supported, so get creative!
  2. Keywords: The keywords/tags you enter in your package.json file will also appear on your npm package page.
  3. Version, license, homepage, and repository: These will be picked up from your package.json file.
  4. Dependencies: This tab will show you what your npm package is dependent upon. Dev dependencies don’t add up to the count.
  5. TypeScript logo: Hovering your mouse over this icon gives you the following message: “This package contains built-in TypeScript declarations.” This is referring to the type definition file add-demo-npm.d.ts created in the dist folder.
  6. Collaborators: By default, this would be your username. If you’d like to add more owners/contributors to this list, check out the npm-owner CLI command.

Logout

After everything's done, use the command npm logout to logout from the CLI.

Demo material

If you’d like to check out this demo in action, you can download the npm package from here and have a look at the source code on GitHub.

Summary

Alright, time for a quick recap —

  • We developed the package using TypeScript and used tsc to compile TypeScript files to JavaScript.
  • We used ts-mocha to unit test our TypeScript code with Mocha as the testing framework and Chai as the assertion library. We followed that up with nyc to add a test coverage report.
  • Next, we installed ESLint to ensure that we’re writing code in a consistent. We complemented that with SonarCloud which analyzes the source code for various metrics like maintainability, reliability duplication and also identifies security issues.
  • Before publishing, we did some housekeeping where we updated the package.json and README.md files.
  • Finally, we used npm’s command-line interface to log in to npmjs.com and publish the npm package.

See, it wasn’t that daunting, was it? Give it a try and let me know in the comments how did you find this, okay? That’s it. Thanks for reading!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK