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 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!
$ mkdir svelte-star-rating
$ cd svelte-star-rating
Now, we can actually initialize our project.
$ 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:
{
"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"
}
}
Component creation
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:
// 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!
<!-- 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.
// ...
"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 anmjs
extension file so that Node can differentiate it among the modules created withCommonJS
andES6
. - In
svelte
, we are defining the path of our main file, theindex.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:
{
"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.
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.
$ npx degit sveltejs/template svelte-playground
Then we access the cloned project and install two initial dependencies.
$ 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.
$ npm link
With it we will get a response similar to this:
# 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.
$ 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
.
$ 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.
<!-- 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.
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.
After being logged in, and sure you want to publish the first version of your package, just run the following command:
$ 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,
$ 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 that I used to store the package mentioned here in the post and the link to it already published on npm!
I hope you enjoyed this post and that it helped you, in some way, to find what you were looking for! 💙
Top comments (4)
I like this because it explains how to do it from scratch. However, I must ask: What do you think about using SvelteKit to create a component library? It is the current recommended way of doing it, officially.
Glad you liked it! I tried to be as clear as possible and do everything from scratch for those who never did!
But yeah, it really is better to do it with SvelteKit as that's the current recommended way. The only reason I did without SvelteKit is because I had already written it by the time I developed the Star-ratting project and this post was in my notes just waiting to be published. But, in the future, I intend to update it or write a new version for a new component using SvelteKit.
Thanks for your comment!
+1 to a new version (as opposed to editing this one). If you remember, please make the comparison and whether or not you find issues. Personally, I found the issue that
main
in package.json seems to be required, although SvelteKit doesn't add it. If I remember correctly, some ES standard/convention says it shouldn't be required, but it ends up being anyway.Someone with your expertise can probably unveil this mystery for us mortals. 😄
Thank you for your enthusiasm for the new version! I'll try to make sure to compare it to the previous one and see if there are any issues. Regarding the "main" entry in the package.json file, you are right that according to some ES standards/conventions this should not be mandatory. However, in certain cases, it may still end up being necessary. Possibly I will delve into this mystery and share my findings here when possible. It's always exciting to explore these details and demystify them! 🔥