Publishing My First NPM Package
Tags: opensource, node, javascript, npm
Published: 2021-11-27 03:25:05

## Intro

I published my first package, [jellybean](https://www.npmjs.com/package/jellybean), to [npm](https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages)! I actually published the package back when I first created the repository in September, just to experiment. However, it didn't work back then and I kind of forgot about it after that. This week, I fixed up the issues I was having and now it works. 😊 In this post, I'll be explaining the process of how I published the package and fixed the issues I previously encountered. 

## Preparing a Project to be Published

I decided to publish my program to [npm](https://docs.npmjs.com/creating-and-publishing-unscoped-public-packages) since it's the most common package manager for JavaScript programs. There are a few steps I followed in order to prepare the program to be published. First, in the package.json file, I added main and bin parameters. In addition, you need to have name and version parameters as well. For example, here is a snippet from my package.json file:

```json
{
  "name": "jellybean",
  "version": "1.0.10",
  "description": "From one small program, you can create an entire website. Jellybean is a static site generator created in Node.js that lets you easily convert your text/markdown files into HTML.",
  "main": "src/index.js",
  "bin": {
    "jellybean": "src/index.js"
  }
}
```

Name and version are pretty self-explanatory, but main specifies the main entry point into the program and bin specifies the command to run the associated executable file. In this case, when a user runs the command "jellybean" after installing the package, the file "src/index.js" will be executed. In addition, each time I published to npm, I incremented the [version](https://docs.npmjs.com/about-semantic-versioning#incrementing-semantic-versions-in-published-packages) and if you forget to do so, you will receive an error message.

In addition, I added the line:

```text
#!/usr/bin/env node
```

To the top of the file to be executed ("src/index.js" in this case), which specifies that the program should be run in a node environment.

## Testing the Project

Before publishing to npm, I tested the program by running:

```
npm link
```

From within the same directory as the repository. Then I ran the program as if it had already been published (eg. running `jellybean --version` would print the version number, etc.). You can read more about how to use npm link [here](https://docs.npmjs.com/cli/v8/commands/npm-link). 

## Publishing the Project

Next, I published the program by running the commands:

```
npm adduser
npm publish
```

`npm adduser` creates or links to your npm account. `npm publish` publishes your package, which you should run each time you want to update your package. 

## Problems I Encountered

Although the steps described above are quite simple, I encountered some problems along the way. Because I originally published the package in September and installed it, I had an older version of the jellybean files in my C:\Users\\...\AppData\Roaming\npm folder. Therefore, every time I tried to run the jellybean command, I got the following error:

```
& : The term '/user/bin/env.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check
the spelling of the name, or if a path was included, verify that the path is correct and try again.
```

I fixed this issue by deleting the old files from the npm folder and once I published my package to npm, I reinstalled it globally and was able to successfully run the program. 

## Testing

I partnered with another student from my class, [Suhhee](https://github.com/suhhee1011), in order to test each other's programs. When Suhhee tested my program, she received the following error:

```
Error: ENOENT: no such file or directory, open 'src/layout.html'
    at Object.openSync (fs.js:498:3)
    at Object.readFileSync (fs.js:394:35)
    at getHtmlLayout 
```

Because of this, I changed my file paths from relative to absolute paths using path.resolve() so that the program can be run from any directory. For example instead of:

```js
return fs.readFileSync(
        'src/index.html',
        'utf8'
    );
```

I updated the code to: 

```js
return fs.readFileSync(
        path.resolve(__dirname, '../src/layout.html'),
        'utf8'
    );
```

## Conclusion

In conclusion, the process of setting up an npm package was pretty straightforward, other than a few problems that I was able to resolve. Over the past almost three months, I've been working on this project every week and getting to publish it was a great end to this journey. If you're interested in trying out the program, you can read more about it [here](https://www.npmjs.com/package/jellybean) or run:

```
npm install -g jellybean
jellybean --help
```

To get started. Thanks so much for reading!