Build, test, and publish vanilla Web Components with a little spice
🚧 Nutmeg is in active development and it's APIs are still in flux.
Nutmeg is here to help you build, test, and publish Web Components in minutes.
By default you get the following:
- Custom Elements v1
- Shadow DOM v1
- TypeScript
- lit-html
- Karma test runner with headless browser launchers
- Git
- MIT license
- Web Component best practices
Generating a Nutmeg Web Component skeleton with npm init has the API <element-name> [property:type...]
.
npm init @nutmeg hello-world name:string
This will create a hello-world
directory, stub out a base Web Component class HelloWorld
that extends the Nutmeg Seed
base class, and install the default dependencies. You can use either fullName
or full-name
for multi-word properties and full-name
will be used for HTML attributes and fullName
will be used in JavaScript.
Note: Yarn is not supported but may work.
Properties must be valid TypeScript types. For example string
, boolean
, number
, string[]
, Element
.
npm init @nutmeg grilled-cheese quantity:number pickles:boolean cheese:string[]
Properties are the public API of your Web Component and external code can set/get them.
export class GrilledCheese extends Seed {
@property() public bread: string;
@property() public cheese: string[];
@property() public pickles: boolean;
@property() public quantity: number;
...
}
The @property()
decorator provides some nice features out of the box. There are two kinds of properties.
- Primitive:
boolean
,string
, andnumber
. - Complex: any types that are not primitive.
Any properties decorated with @property
will automatically render when set.
- boolean:
grilledCheese.pickle = true;
=><grilled-cheese pickle></grilled-cheese>
- number:
grilledCheese.quantity = 5;
=><grilled-cheese quantity="5"></grilled-cheese>
- string:
grilledCheese.bread = 'sourdough';
=><grilled-cheese bread="sourdough"></grilled-cheese>
On instantiation of a Web Component a one-time loading and JSON parsing happens of complex properties. In the following example cheese
has the type of string[]
. When connected the component will have the attribute removed and the value set as a property after JSON.parse
.
The following example:
<grilled-cheese cheese="[\"sharp cheddar\"]"></grilled-cheese>
Yields:
grilledCheese.cheese.includes('sharp cheddar') === true;
<grilled-cheese></grilled-cheese>
$
and $$
are shortcuts provided for quickly selecting elements within the shadowRoot.
$
is a shortcut forthis.shadowRoot.querySelector
.$$
is a shortcut forthis.shadowRoot.querySelectorAll
.
You can now serve the component for development on http://localhost:8080 by running:
npm start
With start
running you can make edits to the component and see the changes take effect automatically without manually refreshing.
Running the tests from within hello-world
.
npm test
Components are generated with AppVeyor, CircleCI, and TravisCI pre-configured to run tests on Windows, macOS, and Linux respectively.
Publishing to NPM is easy but make sure you are logged in first with npm login
. Be sure to fill out package.json
values like author and update the name in readme.md
if you change it.
npm publish
Once published, it's recommended that you set up Renovate to keep your dependencies current. Nutmeg has already setup a default renovate config for you, you just have to install the free GitHub app.
Out of the box many of the Google Web Fundamentals Custom Element Best Practices are handled automatically.
- HelloWorld built using
nutmeg new hello-world name:string
. - TwitterStatus for embedding tweets.
Nutmeg is released under an MIT license.