How to develop a svelte component and publish it as a package in NPM
Tags: npm, svelte, tutorial
Published: 2023-05-21 02:24:14

> Publish your favorite svelte component as a package on npm and make it available for use anytime.

When we like a certain component that we develop, we end up using and reusing it countless times, in different ways, that is; replicating your files and logic in many different places in the project, or in several other projects, or simply redeploying the same component over and over again. This will work, of course. However, it is not the best way to act in this situation.

Imagine that you will have to carry out maintenance, or simply change, say, the color of this component. Imagine that there are 10, 100, 200... Well, you will have to make this change in each component present in your project, correct? What if it is already applied to other projects? well, the change should be made too. The problem I think we already understood. But how to solve it?

When it comes to a project that uses the same technology, in the case that we will see in this post [Svelte](https://svelte.dev/) for example, you can create a component and publish it as a package in NPM and reuse it whenever you need it. That's what we'll see here! for cases where the projects do not share the same technology, this is a matter for another time. But if you like spoilers you can read about WebComponents.

## What will we develop?

I recently made a simple svelte component - hence the idea of the post - to perform evaluations. It is simply a nest of stars and in it the user will be able to show his satisfaction with such content that the component will return the selected information in its configuration prop. He will be the one we will develop!

For this, you need to have an account on NPM, have NodeJs and NPM installed on your machine and be patient to venture out!

## Initializing the project

The first step, like any project, is to create a directory for it. let's go!

```bash
$ mkdir svelte-star-rating
$ cd svelte-star-rating
```

Now, we can actually initialize our project.

```bash
$ npm init -y
```

This command will create a `package.json` file and will automatically fill in some information about the package we are developing like name, author, description, etc... the `-y` flag will perform a short auto-fill. If you want to do it manually run without it. But don't worry, you can always change package.json when needed.

## Installing required dependencies 

The next step is to install the necessary development dependencies of our package. That way, notice that package.json will add the dev dependencies section. In addition, I will take the opportunity to make some changes, such as name, author, keywords, etc. Feel free to fill in as you see fit.

Finally, the `package.json` should look like this:

```json
{
  "name": "@ernane/svelte-star-rating",
  "version": "1.0.0",
  "description": "Simple component to assign scores based on stars.",
  "homepage": "https://github.com/ErnaneJ/svelte-star-rating",
  "bugs": {
    "url": "https://github.com/ErnaneJ/svelte-star-rating/issues"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ErnaneJ/svelte-star-rating.git"
  },
  "keywords": [
    "svelte",
    "star",
    "ratting",
    "component",
    "sapper"
  ],
  "author": "ernane <ernane.junior25@gmail.com>",
  "license": "MIT",
  "devDependencies": {
    "rollup": "^2.39.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-svelte": "^7.1.0",
    "svelte": "^3.32.3"
  }
}
```

## Criação do componente

As usual, I create my logic files usually in a subdirectory named `src`, I'll follow that pattern here. In this way, we will create an `index.js` file, it will be the starting point of our component.

Basically we will import the main component of our package and export it as default in index. It will be something like this:

```js
// src/index.js
import SvelteStarRating from './SvelteStarRating.svelte';
export default SvelteStarRating;
```

As a consequence we will now have to create the file, which will be our svelte component itself, `SvelteStarRating.svelte`. To test it, let's just put a test message at the moment!

```html
<!-- src/SvelteStarRating.svelte -->
<p>Hello World! It's my first package svelte component! ✨ SvelteStarRating ✨</p>
```

In this file we will have all the logic and implementation of our package. In it we will add styles, necessary imports, among other things.. Let's go ahead, we'll be back in it!

## Formalizing structure

Now that we have the main structure of our component, we need to formalize it in our package.json. For this, we will need to make some more changes to it.

```json
// ...
"main": "dist/index.js",
"module": "dist/index.mjs",
"svelte": "src/index.js",
"scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
},    
// ...
```

Since this part is a bit tricky, let's see what it's actually doing:

- In `main` we define what will be the output after the execution of the compilation script,
- In `module` we define the same, but as output an `mjs` extension file so that Node can differentiate it among the modules created with `CommonJS` and `ES6`.
- In `svelte`, we are defining the path of our main file, the `index.js` that we created earlier.
- And, finally, `scripts` will be the commands used for execution and compilation in development.

Note that the dist subdirectory, which we specified in the first two commands, does not exist as it will be automagically generated ✨.

After these small changes our `package.json` will look like this:

```json
{
  "name": "@ernane/svelte-star-rating",
 "version": "1.0.0",
  "description": "Simple component to assign scores based on stars.",
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "svelte": "src/index.js",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w"
  },
  "homepage": "https://github.com/ErnaneJ/svelte-star-rating",
  "bugs": {
    "url": "https://github.com/ErnaneJ/svelte-star-rating/issues"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/ErnaneJ/svelte-star-rating.git"
  },
  "keywords": [
    "svelte",
    "star",
    "ratting",
    "component",
    "sapper"
  ],
  "author": "ernane <ernane.junior25@gmail.com>",
  "license": "MIT",
  "devDependencies": {
    "rollup": "^2.39.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-svelte": "^7.1.0",
    "svelte": "^3.32.3"
  }
}
```

## Creating the rollup.config.js file

You are probably already familiar with this file because it is Svelte. But basically we perform the basic build configuration of our simple project.

```js
import svelte from "rollup-plugin-svelte";
import resolve from "rollup-plugin-node-resolve";
const pkg = require("./package.json");
export default {
    input: "src/AtButton.svelte",
    output: [
        { file: pkg.module, format: "es" },
        { file: pkg.main, format: "umd", name: "Name" },
    ],
    plugins: [svelte(), resolve()],
};
```

Wow! Package successfully configured for use. 🥳

## Testing component locally

Before we publish our new component on `NPM`, it's always good to test it to see how it really is and if its result is satisfactory. For this, we can use it on our machine even before we send it for publication. For this, let's create, in parallel, a simple project in Svelte. For this case, I'll use `svelte-playground` itself.

```bash
$ npx degit sveltejs/template svelte-playground
```

Then we access the cloned project and install two initial dependencies.

```bash
$ cd svelte-playground
$ npm install
```

Now, in order to use our component as an npm package and apply it to this project, we can run the following command in the directory of our `svelte-star-rating` package.

```bash
$ npm link
```

With it we will get a response similar to this:

```bash
# npm WARN svelte-star-rating@1.0.0 No repository field.

# audited 17 packages in 0.711s

# 3 packages are looking for funding
#   run npm fund for details

# found 0 vulnerabilities
```

After that, now in the `svelte-playground` test project we can run the same command, but now, going to the directory of our new package on our machine.

```bash
$ npm link /path/svelte-star-rating
```

That way we can use our component as a package locally, and best of all, in realtime!

## Using component locally

Access the test project we created, `svelte-playground`, and run the project under development using the command present in your `package.json`.

```bash
$ npm run dev
```

EThen access the browser at the suggested port and see the application running. After that, we can now apply our component to this project and thus visualize its changes at runtime.

for that, we go to the `src/app.svelte` file, to make some changes.

```html
<!-- src/app.svelte -->
<script>
  ...
  import StarRating from "@ernane/svelte-star-rating";
  ...
</script>

...
<StarRating/>
...
```

And then we'll have our component running locally. Fantastic, isn't it!?

Now we just have to develop our new component the way we want and check if the changes made match what we want. Here is the current development status of my [svelte-star-rating](https://github.com/ErnaneJ/svelte-star-rating).

## Publishing package in NPM

Great, we already have our component working we would like. And now? well, now we publish it! Publishing is as simple as a push, check it out...

First, you must be logged into your `NPM` account, if you are not or don't know, just follow the steps described [here](https://docs.npmjs.com/creating-a-new-npm-user- account).

After being logged in, and sure you want to publish the first version of your package, just run the following command:

```bash
$ npm publish --access public
```

Ready! you can access your profile on the NPM page and you will see a new package added! 🎉 Simple no?!

## Testing new NPM package

You've undoubtedly done this here hundreds of times, or maybe less 😅.. Access your package information that will tell you how to install it. But following the standards you can do it with the simple npm install passing the name, defined in the package.json, of your project!

i.e,

```bash
$ npm i @ernane/svelte-star-rating
```

Usage will be the same as before, import and use. Well, that you already know!

If you have any questions, here is the [repository](https://github.com/ErnaneJ/svelte-star-rating) that I used to store the package mentioned here in the post and the link to it already [published on npm]( https://www.npmjs.com/package/@ernane/svelte-star-rating)!

I hope you enjoyed this post and that it helped you, in some way, to find what you were looking for! 💙

- [Official NPM documentation](https://docs.npmjs.com/);
- [Rollup Documentation](https://rollupjs.org/guide/en/);
- [Svelte Documentation](https://svelte.dev/docs);