How To Deploy An NPM Package

Raymundo Martinez
Level Up Coding
Published in
4 min readMay 27, 2020

--

Using Typescript and Rollup.js

Photo by jesse ramirez on Unsplash

Step 1: Create a Project

If you already have a project feel free to skip to Step 2.

Let’s start with a simple project structure: an /src directory where we’ll export index.ts and a package.json.

/src
-index.ts
package.json

We will be exporting a simple function called addTwo. Add the following to the index.ts file.

export default function addTwo(num:string) {
return num + 2
}

Now, we will begin to install our dependencies.

Step 2: Install Typescript

npm i -D typescript

Because this is a typescript project, we should include a tsconfig.json file to specify the root level and any compiler options. We will use the following simple-case example.

//these options specify where we want our types to be build to 
//aswell as specifying what not to include in the compilation
//we do not want to include our built files in dist(we will configure this in a later step) or our node_modules
{
"compilerOptions": {
"declaration": true,
"declarationDir": "dist/types",
},
"exclude": ["dist", "node_modules"]
}

try running

tsc

If everything went well you should have a new index.js file in your /src dir.

Now run

tsc --emitDeclarationOnly

You should now have a new /dist directory with an index.d.ts file. These are your types.

Now, let’s install rollup.js

Step 3: Install Rollup.js and Plugins

Rollup compiles your modern modular code back down to other supported formats like CommonJS, AMD, and IIFE-style scripts. We will need the node-resolve plugin so that rollup can locate our modules.

npm i -D rollup @rollup/plugin-node-resolve

Your package.json should now look something like this:

{
"name": "rollup-typescript-starter",
"version": "1.0.0",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"dependencies": {},
"devDependencies": {
"@rollup/plugin-node-resolve": "^7.0.0",
"rollup": "^1.29.0",
"typescript": "^3.9.3"
},
"scripts": {
"build": "rollup -c"
},
"files": [
"dist"
]
}

Now let’s add a rollup.config.js file to the root directory.

import pkg from './package.json';const extensions = ['.js', '.ts']export default [// CommonJS (for Node) and ES module (for bundlers) build.{
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs'
},
{
file: pkg.module,
format: 'es'
}
],
plugins: [
resolve({
extensions //specifies the extensions of files that the plugin will operate on
}),
]
}

Now let’s add try to build our code.

npm run build

What happened?

Because we are building using rollup and not through the typescript compiler (tsc) we must configure a way to remove types through rollup. In comes babel!

Step 4: Install Babel

First, we install babel.

npm i -D @babel/core

Now let’s install the typescript preset. This will remove the types from the typescripts files.

npm i -D @babel/preset-typescript

Next, add a .babelrc file to your root directory.

{"presets": ["@babel/preset-typescript"]}

Finally, install the rollup babel plugin. This will allow rollup to use babel to transpile our typescript files and remove the types.

npm i -D @rollup/plugin-babel

Update your rollup.config.js file

import resolve from '@rollup/plugin-node-resolve';
import pkg from './package.json';
import babel from 'rollup-plugin-babel'
const extensions = ['.js', '.ts']export default [// CommonJS (for Node) and ES module (for bundlers) build.{
input: 'src/index.ts',
output: [
{
file: pkg.main,
format: 'cjs'
},
{
file: pkg.module,
format: 'es'
}
],
plugins: [
resolve({
extensions
}),
babel({
exclude: 'node_modules/**',
extensions
}),
],
},

Now let’s try building again

npm run build

Nice!

Step 5: Publish

Ok before we publish we want to make sure we build our types as well so they can be available to people who install the package.

Remember this command.

tsc --emitDeclarationOnly

Let’s add it to our build script in package.json, and while we’re at it let’s clean our /dist directory before every build to ensure that we have the latest build every time.

{
"name": "rollup-typescript-starter",
"version": "1.0.0",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"dependencies": {},
"devDependencies": {
"@rollup/plugin-node-resolve": "^7.0.0",
"rollup": "^1.29.0",
"typescript": "^3.9.3"
},
"scripts": {
"build": "rm -rf dist && rollup -c && tsc --emitDeclarationOnly"
},
"files": [
"dist"
]
}

Now let’s add our publish script.

{
"name": "rollup-typescript-starter",
"version": "1.0.0",
"main": "dist/index.cjs.js",
"module": "dist/index.esm.js",
"dependencies": {},
"devDependencies": {
"@rollup/plugin-node-resolve": "^7.0.0",
"rollup": "^1.29.0",
"typescript": "^3.9.3"
},
"scripts": {
"build": "rm -rf dist && rollup -c && tsc --emitDeclarationOnly",
"prepublish:public": "npm run build && npm run bump-version",
"publish:public": "npm publish --access public",
},
"files": [
"dist"
]
}

The ‘pre’ prefix in front of ‘prepublish:public’ means that this script will run before the ‘publish:public’ script.

Now to publish to the npm repository run:

npm run publish:public

Congratulations! Now your package is available in the npm registry.

--

--