How to create and publish a typescript module on npmjs.com
Raphael MANSUY
Posted on September 6, 2020
This tutorial explains
- How to configure a typescript package from zero
- How to add the support of Jest for the unit tests
- How to generate the tests coverage
- How to publish the library in npmjs.com
Let's create a simple library to validate emails and IPv4 addresses. The name of this library will be xanthe.
️Xanthe means “golden” or “yellow” in Greek. Xanthe is an exotic epithet of Demeter, goddess of the harvest and agriculture 🇬🇷🧚♀
Create a package.json file
{
"name": "xanthe",
"version": "0.0.1",
"author": {
"email": "contact@elitizon.com",
"name": "elitizon"
},
"license": "MIT",
"description": "A library to validate common formats such as emails, numbers, phone numbers, and IP addresses",
"contributors": [
"raphaelmansuy"
],
"keywords": [
"format",
"validator",
"email validation",
"IP address validation"
],
"dependencies": {},
"devDependencies": {}
}
Install typescript as a development dependencies
yarn add -D typescript @types/node
@types/node contains type definitions for Node.js
typescript contains the typescript compiler
Create the src and test directory
mkdir src
mkdir tests
Install a testing environment
Install Jest as a development dependency
Jest is a testing library developed by Facebook.
yarn add -D jest ts-jest
Create a jest.config.js file to configure Jest
module.exports = {
transform: {'^.+\\.ts?$': 'ts-jest'},
testEnvironment: 'node',
testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
}
- All the files ending by .ts will be handled by ts-jest.
- The test environment is nodejs
- The test files are contained in the ./tests directory and must have .test. or .spec. in the filename and must end by .ts or .tsx
Create a script section in the package.json file
"scripts": {
"build": "tsc",
"test": "yarn build && jest",
"coverage": "jest --coverage"
},
- build: invoke the typescript transpiler
- test: build and invoke the tests
- coverage: generate the tests coverage in the coverage directory
Create a tsconfig.json file to configure typescript
{
"compilerOptions": {
"target": "es5" ,
"module": "commonjs",
"outDir": "./build",
"strict": true,
"esModuleInterop": true ,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true
},
"exclude": ["node_modules", "build", "tests"]
}
The build command will generate the CommonJS files in the ./build/ directory
Creation of validations functions
Create a file email.ts in ./src/validators/ directory
/**
* @param email to validate. No spaces or tab are allowed at the start or at the end of the string
* @returns true of false if the email is valid or not
*/
function isEmail(email: string) : boolean {
// An email address is a word followed by an unique @ followed by a word then a . followed by a word with a length of 2 to 3 characters
const regEx = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/
const result = regEx.test(email)
return result
}
export {
isEmail
}
Create a file ipV4.js in ./src/validators/ directory
/**
* @param ip to validate. (No spaces or tab are allowed at the start or at the end of the string)
* @returns true of false if the IP is valid or not
*/
function isIPv4(ip: string) : boolean {
// An ip V4 address has the form of X.X.X.X
// Where X is a number between 0 to 255
const regEx = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
const result = regEx.test(ip)
return result
}
export {
isIPv4
}
Create a file index.ts in ./src/
import { isEmail } from "./validators/email"
import { isIPv4 } from "./validators/ipv4"
export { isEmail, isIPv4 }
Our module is now nearly ready. Let's create the unit tests.
Creation of unit tests
Create an email.test.ts in ./src/tests directory
import { isEmail } from "../src/index"
test("email luc@perdu.com valid", () => {
expect(isEmail("luc@perdu.com")).toBe(true)
})
test("Empty string not valid", () => {
expect(isEmail("")).toBe(false)
})
test("No double @ in an email", () => {
expect(isEmail("martin@toto@titi.com")).toBe(false)
})
test("not trimmed email to be false", () => {
expect(isEmail(" luc@perdu.com ")).toBe(false)
})
Create the ipV4.test.ts in ./src/tests/ directory
import { isIPv4 } from "../src"
test("192.168.0.1 is valid", () => {
expect(isIPv4("192.168.0.1")).toBe(true)
})
test("1920.168.0.1 is not valid", () => {
expect(isIPv4("1920.168.0.1")).toBe(false)
})
test("192.1682.0.1 is not valid", () => {
expect(isIPv4("192.1682.0.1")).toBe(false)
})
test("192.168.256.1 is not valid", () => {
expect(isIPv4("192.168.256.1")).toBe(false)
})
test("192.168.255.500 is not valid", () => {
expect(isIPv4("192.168.255.500")).toBe(false)
})
test("192.168.255.255 is valid", () => {
expect(isIPv4("192.168.255.255")).toBe(true)
})
test("192.168.X.255 is valid", () => {
expect(isIPv4("192.168.X.255")).toBe(false)
})
Let's compile and tests
yarn build
yarn test
Execute the tests coverage
yarn coverage
A coverage has been generated with all the information about the tests coverage
Creation of git repository
Create of a .gitignore file
node_modules
build
coverage
run git init
git init
add the files
git *
commit the files
git commit -m "First commit"
Publish the file to a Github repository
An empty Github project must be created before publishing.
The file package.json need to be updated as follow:
"repository": {
"url": "https://github.com/myorganisation/xanthe.git",
"type": ""
},
myorganisation represents your Github account
We can now set up the Github project as a remote representation of the local project and push the local master branch to the remote server (origin).
git remote add origin`https://github.com/myorganisation/xanthe.git
git branch -M master
git push -u origin master
Publish to npmjs.org
An account must be created before publishing a package in the npm registry.
- Once the account is created you need to log into
npm login
Enter your username, password, and email address registered on npmjs.org
Add a new file .npmignore to exclude some files from the publication
README.md
TUTORIAL.md
jest.config.json
tests/
- We can now publish it to the library at npmjs.org
yarn publish
A few questions will be asked such as the new version number 0.0.1
And "voilà". Our components are published and visible 🥳
Posted on September 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.