Today, I wanted to test the library: SolidJS. It features JSX support and is known for its great performance.
Install the lib
The first step I did was to follow the Getting Started guide and start from a given template:
> npx degit solidjs/templates/ts my-app
> cd my-app
> npm i
Remove the unnecessary files
I removed all content from src/
folder and created an empty index.ts
.
This file will serve as an entry point for the lib.
Update Vite's configuration
In vite.config.ts
, I added the lib
configuration:
export default defineConfig({
plugins: [solidPlugin()],
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
name: 'my-component',
fileName: (format) => `my-component.${format}.js`
},
// ...
},
});
With the lib
property, Vite provides a way to bundle a library from the given entry point.
This library mode still gives you access to the demo page with npm run start
.
Creating the component
I then created a file for my component.
// src/MyComponent.tsx
const MyComponent: Component<Props> = (props) => {
return <> {/*...*/} </>;
}
And I did not export the component like I am used to with react, but I rather registered it with the customElement
helper from the solid-element
module.
The
solid-element
is a separate module that needs to be installed.
// src/MyComponent.tsx
import { customElement } from "solid-element";
/* ... */
customElement("my-component", { someProp: "defaultValue" }, MyComponent)
The custom customElement
helper works by giving the module a tag name (e.g. "my-component"
) and binding it to your component (e.g. MyComponent
).
You need to pass as a second argument the default props values. Omitting this object prevents the props from receiving data from their corresponding attribute (e.g.
some-prop
attribute should bridge data tosomeProp
prop).
A note about styles
Vite allows writing css-modules files (e.g. MyComponent.module.css
) in order to scope the style to a specific component. Because of the Shadow DOM, styles written in the web component are scoped to the web component by default. That means, in this case, I do not need to rely on the css-modules feature.
In order to add style to my component, I wrote a standard CSS file and import it into the component file.
import styles from "./MyComponent.css";
The styles
object is the actual styles string and can be embedded into the web component using the <style>
tag.
const MyComponent: Component<Props> = (props) => {
return <>
<style>{styles}</style>
{/*...*/}
</>;
}
Because class names are kept untouched by Vite, I can add class names as I would normally do in an HTML markup:
<div class="myComponent" />
Last step
After setting up my component, I imported the component file in the index.ts
file.
// src/index.ts
import "./MyComponent.tsx";
I then added the custom web component in the markup of the index.html
file (Vite's "demo" page).
<body>
<my-component some-prop="someValue">
</body>
Everything looked fine. I then built the lib (npm run build
) and got three files.
style.css
: can be ignored because style is also embedded in the JS.my-component.es.js
: the ES module output JSmy-component.umd.js
: the universal module output JS
Both modules seem to work fine when imported into an HTML document, but the UMD is way smaller because minified.
Conclusion
This process is quite straightforward once you know what needs to be configured. I think it is a good starting point, for me, to learn SolidJS and to dip a toe in the web components world.