Simple guide to creating and publishing npm modules.

When I was first looking into publishing npm modules I was a bit overwhelmed with where to start, and I had a few misconceptions. I always thought that “I had to write ES5 code” and that “everyone is watching you and laughing at your mistakes”. Turns out it’s really simple, and surprisingly quick to do! This post will be covering creating a React component, but if you want to create a plain old JavaScript module you can follow the exact same exact steps. We will be using Rollup for writing ES6 code, but letting us distribute ES5 code.

Creating a distributable module

Set up

Rollup have created a small starter project that I forked and added support for React and JSX, and can be found on Github (rollup-starter-project-react). We will clone this, delete any references to the git repo it was cloned to, and add our own git repo.

The lib folder. This is your source folder, you put your code here. The entry point, or in our case, the main exports of our application will go in the index.js. If we only have a single component or function that we need to export we can use export default ExampleComponent, or we can use export { Several, Components }.

We can have as many or as few files in the lib/ folder. The most important thing is that the index.js file is the entry point to the application.

This is the folder where the files generated by Rollup will end up. This will be the actual code that will be executed when people use our module. The entry point ("main") in package.json will point to the file here that Rollup creates.

package.json

Same old package.json as ever, have a quick look at scripts and make your self familiar with the commands.

rollup.config.js

The config file for the bundler we are using, Rollup. It’s not big, and it’s not advanced. The plugin section has two entries, postcss to let us inline our CSS style (only required if you use CSS in your component), and babel, to let us write modern and sleek ES6, while our output code is good old and well supported ES5.

The main configuration section has a entry-point, which is our lib/index.js file, our plugins, externals, globals. globals is where we need to define any external library that we use. This is because rollup doesn’t bundle your dependencies’ code, meaning that whoever use your module will have them installed on their system, and when they bundle their code your module will use that library. globals is defined as id: name pairs, meaning that react which is imported like this import React from 'react' will be defined here as react: 'React'.

The targets array is if you want to produce more than one kind of module. For simplicity we will create a single UMD. If you want to get down and dirty with creating several modules (for example letting your users use much more terse and efficient ES6 code if they want), have a look at Rollup’s documentation.

.babelrc

If you want to use even more modern JavaScript, this is where you add them.

.eslintrc

The starter project is set up to use eslint with the airbnb lint preset. This preset is very strict, but it helps you keep your code consistent. If you disagree with any of the rules you can disable them globally in the .eslintrc file.

yarn link v0.24.5 success
Registered "our-awesome-component".
You can now run `yarn link"our-awesome-component"`

In the project where you want to test your component, simply copy and paste the command shown by the output, e.g. yarn link "our-awesome-component". This will create a symbolic link in your test project at node_modules/our-awesome_component that points to your actual components code. Meaning that when you run yarn watch in your module project, the code will hot-load and will immediately be available in the test project, giving you a very quick feedback cycle.

When you are done, and your component successfully lints, all tests passes and it works well, you can move on to the next step, publishing it!

Publishing it to npm

Publishing is easy, too easy.

First things first, get your code ready. I like to delete the dist/ folder and re-run yarn build to make sure there aren’t any extraneous files in there.