In my last articles I have mainly talked about how to integrate Svelte, Tailwind, Jest and how to use NPM. Why all this? To get to understand how to create a Svelte component and how to publish it as an NPM package. Below, as is my habit now, I report the various steps I followed and the link to a template that should simplify everything.
Create components with SvelteKit
First of all the technology: SvelteKit. It may seem like a bizarre choice but I think it’s the simplest way. The SvelteKit documentation also has a section dedicated to packaging.
In short, you can take the contents of the src/lib
folder and save it as a package. It is also possible to publish it on NPM. In addition, the contents of the main folder can be exported in order to simplify the creation of documentation.
I omit the explanation of how to create a component with SvelteKit and the integration with Jest and TailwindCSS. I’ve written a couple of articles about it:
I go directly to what to change: the svelte.config.js
file. I add the package
entry and set the directory to export the compiled package to (by default it is the package
folder)
const config = {
// ...
kit: {
target: '#svelte',
package: {
dir: 'package',
emitTypes: true
}
}
// ...
};
Then I download and install svelte2tsx to generate TSX files from SVELTE files.
npm i svelte2tsx
So I add a new script to package.json
:
"scripts":{
"package": "svelte-kit package"
}
But if I try to run it (with the npm run package
command) I get nothing. Why? Because an index.js
file is missing. I need it how the entry point for the package. Since I am using TypeScript I have to create the src/lib/index.ts
file. I insert in this file the components that I want to make usable:
export { default as GridColors } from './GridColors.svelte';
export { default as Slider } from './Slider.svelte';
I know, I’m not explaining how to create the various Svelte files. For now it is not necessary to know the implementation of the individual components. The important thing is to remember to add a file to use as an entry point for the package and update the contents of package.json
with the essential information (name, github, and so on).
Then I run:
npm run package
and I get a new folder. Inside is the code to import to NPM.
I can publish using the command:
npm publish ./package --access public
As I have already explained in another article (this post) every time I change the code I can update the version number with the command:
npm version patch
and then republish with
npm publish
How to use an NPM package locally
All of this is very fast. But there may be things that don’t work after publication. I found some problems especially with TailwindCSS. In the test phase everything works fine but after exporting the package there were some bugs. I think it is a limitation of Tailwind: to avoid a plethora of CSS classes some commands are ignored or merged. In my case, in the repository I created as a template, Tailwind is not able to color only one border of a table cell. It works very well in testing but after exporting it doesn’t.
It is not the first time. To solve this problem I had to test the package created by SvelteKit several times. One option is to upload it online each time and then re-download it to test it. The alternative is to use npm-link
. Basically I can link a package saved on my computer and use it as a source for another project.
There are two commands to type. The first in the folder where the package code is (in my case in package
):
npm link
The second command must be used in the project where I intend to use my package. Instead of using npm install name-package
I use:
npm link name-package
In my example the command becomes:
npm link @el3um4s/svelte-component-package-starter
Now I can access the most recent compiled code without having to install the package from npm every time. To access the component just use the usual formula:
<script lang="ts">
import { Slider, GridColors } from "@el3um4s/svelte-component-package-starter";
let steps = 5;
</script>
<main>
<Slider label="hello" bind:steps />
<GridColors bind:steps --border-color="red" />
</main>
After I finished testing the component I can delete the link using the command:
npm uninstall --no-save name-package
npm install
I can also completely remove the global link from the package (so as to avoid future interference) with the command
npm uninstall name-package
However, I recommend reading these two posts to learn more about how to use npm-link
:
Use the newly created component
I have already mentioned this but I prefer to write it explicitly. After uploading the package to NPM I can download my component and use it in my other projects. To download it, the command is the classic npm install name-package
:
npm i @el3um4s/svelte-component-package-starter
After installing it I can access it from any Svelte file:
import { Foo } from 'your-library';
import Foo from 'your-library/Foo.svelte';
In my example it becomes:
<script lang="ts">
import { GridColors } from "@el3um4s/svelte-component-package-starter";
</script>
<GridColors />
How to use the template to create Svelte components
Obviously all this work is to create a template that simplifies the creation of reusable components in multiple projects. You can download the template using the command:
npx degit el3um4s/svelte-component-package-starter
Just empty the src/lib
and src/__tests__
directories to get a clean template.
Finally, you can see the repository code at el3um4s/svelte-component-package-starter.