The fast and easy way to create a TypeScript library
Become a prolific TypeScript open sourcerer with this guide
The secret to being prolific at something is to automate mundane tasks as much as possible. For software, this can translated as using CLIs, starters or boilerplates to get you up and running in no time. Let’s see how to quickly set up a Typescript library with unit testing, automatic release, continous integration, and documentation.
For didactic purposes, we’ll create a useless library that exposes a method to count the words in a sentence.
- We’ll use the typescript-starter CLI to get us up and running. Execute this in the terminal:
$ npx typescript-starter
It’ll make you run through a series of questions. Write the name of your library and choose whether you want this to be a browser or Node library. We’ll choose “Node.js application” for our example. Also, I normally prefer TravisCI over CircleCI.
- Remove the contents from
src/lib
and create a file for your library.
$ rm -rf src/lib/* && touch src/lib/tswordcount.ts
- Edit
src/index.ts
to configure your public API.
export * from './lib/tswordcount';
- Write your function in the file created in step 2. Our file is
src/lib/tswordcount.ts
.
export function countWords(sentence: string): number {
return sentence.split(/\s+/).length;
}
Note: Notice we’re not doing .split(' ')
as this would fail at inputs with long spaces in between the words. We use regex to separate words regardless of the spaces that divide them.
- Create a file to write your unit tests. Let’s name it
tswordcount.spec.ts
. It should live in the same folder where our source file is.
$ touch src/lib/tswordcount.spec.ts
- This starter uses AVA for unit tests. The syntax is similar to every other testing library out there. Let’s write a simple test for our function.
// tslint:disable:no-expression-statement
import test from 'ava';
import { countWords } from './tswordcount';
test('should count words', t => {
const testString = 'hello world';
t.is(countWords(testString), 3);
});
test('should count words with long spaces', t => {
const testString = 'hello world this is carlos ';
t.is(countWords(testString), 6);
});
- Test and build the library in one command.
$ npm run test
- If everything goes well you should have a
/build
folder with folders/main
and/module
. The former is configured for CommonJS and the latter for ES6 module system. Now you’re all set to publish your library.
$ npm publish
- Bonus: Documentation
Gotchas
You might face some problems right from the start because the project hasn’t been maintained for a few months now. Follow the next steps to fix them.
- Install the latest version of AVA
$ npm i ava@latest
- Remove the following lines from
package.json
to make AVA work properly
"ava": {
"failFast": true,
"files": [
"build/main/**/*.spec.js"
- ],
- "sources": [
- "build/main/**/*.js"
]
},
- Update
typedoc
dependencies:
$ npm un @bitjson/typedoc && npm i -D typedoc
- Optional. If using Travis CI, make sure you enforce coverage in your build. Change your
.travis.yml
with this:
sudo: false
language: node_js
node_js:
- '10'
cache:
directories:
- '$HOME/.npm'
script:
- npm run test
- npm run cov:send
- npm run cov:check
- It never hurts to do a clean install again
rm -rf node_modules && npm i
I'm Carlos Roso. I'm a Production Engineer at Meta. Former SDE at Amazon. Ex digital nomad at Toptal and Crossover. In love with open source and design.
More about me