Publishing a javascript module to NPM is fairly straightforward. There are a couple of extra steps though when you’re writing in TypeScript.
0. Output directory and entry point assumptions
Yep, it’s step 0. We need to do this with any js package anyway. Check your package.json
and make sure the main
key has the correct path to the entry point of your package.
"main": "dist/index.js",
Keep in mind that we’re gonna submit compiled JavaScript files to NPM, so "main"
should point to the .js
file.
It’s common for TypeScript projects to store compiled js files in a separate directory not tracked by VCS (.gitignore
and such). We usually call it dist
. Here and further down I’m gonna assume you have this line in your tsconfig.json
.
"outDir": "./dist",
1. Enable generating type declarations in tsconfig
"declaration": true, /* this goes to your tsconfig.json */
Normally tsc
simply compiles .ts
files to plain js. With this option switched on the compiler will also generate *.d.ts
files. They carry type declarations necessary for type checking and type hinting when someone imports your module in their TypeScript application.
You’ll find the *.d.ts
files in your outDir
along with compiled javascript.
2. Add type declarations to package.json
Now that you have the type declarations ready, add types
key to your package.json
.
"types": "dist/index.d.ts",
This will allow anyone who pulls your package to use the type declarations.
3. Specify what goes in the package
By default NPM ignores whatever you put in your .gitignore
which works fairly well for javascript libraries. When writing in TypeScript, however, this works against us. Mainly we don’t want to ignore our dist
dir — all the meat of our package is there! Here are two ways to do that.
3.1 .npmignore
$ touch .npmignore
.npmignore
overrides .gitignore
when publishing. Leave it empty, and everything will just be kept in. Well, not everything (here’s a detailed doc), but this is good enough for a proof of concept.
3.2 “files” key
I personally find whitelisting clearer. You don’t want your tests and dotfiles in the release so just specify what exactly goes in it. There’s files
key in package.json
for it.
"files": [
"dist/*"
],
README
, LICENCE
and package.json
are always included.
4. Build your package
Run your typescript compiler to make sure your generated js is up-to-date.
$ tsc
This is also a good time to verify that all is well before publishing.
- Run your tests.
- Create a tarball with
yarn pack
. Check out the contents of the package. - Link the package with
yarn link
and try importing it to make sure everything works.
5. Publish to NPM
$ yarn publish
Type in your password and the package version, and you’re done. Good job!