Getting Started with lit
Using lit 3.1 with TypeScript 5.5 and rollup 4.20
So I've been wanted to try for sometime but what put me off was the lack of a comprehensive documentation from scratch assuming a little knowledge of TypeScript and build tools by the learner. Because that's where I was coming from. Had it been JavaScript it would've been easier but I want to start using TypeScript since it has been starting to be more appealing for development.
Let's look at this example : https://lit.dev/tutorials/intro-to-lit/ in TypeScript. The option to choose TypeScript is the toggle button on the right hand side.
There are 2 files included in the example - you can see the 2 tabs - my-element.ts
and index.html
. Create these 2 files with ditto code in some directory, say, getting-started
. Added here incase the tutorial has the code changed later on.
my-element.ts
import {LitElement, html} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('my-element')
export class MyElement extends LitElement {
@property()
version = 'STARTING';
render() {
return html`
<p>Welcome to the Lit tutorial!</p>
<p>This is the ${this.version} code.</p>
`;
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<script type="module" src="my-elements.js"></script>
<style>
body {
font-family: 'Open Sans', sans-serif;
font-size: 1.5em;
padding-left: 0.5em;
}
</style>
</head>
<body>
<my-element></my-element>
</body>
</html>
The tutorial example assumes you know TypeScript configuration if working on TypeScript and some knowledge about build tools - obviously - since it is a lit tutorial exclusively and not the entire web stack.
https://lit.dev/docs/tools/requirements/ says "Lit is published as ES2021." but let's specify ES2022 in tsconfig.json
in the same getting-started
directory, which is as below :
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "node",
"experimentalDecorators": true,
"useDefineForClassFields": false,
"lib": ["ES2022", "dom"],
"target": "ES2022",
"outDir": "./dist",
"baseUrl": "./",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
}
}
There are some npm packages to be installed (assuming you have NodeJS, I have 21.7.3) - instead of installing them one by one - just add this package.json
file in getting-started
directory.
{
"dependencies": {
"lit": "^3.1.4",
"rollup": "^4.20.0",
"typescript": "^5.5.4"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@web/dev-server": "^0.4.6",
"@web/rollup-plugin-copy": "^0.5.1",
"@web/rollup-plugin-html": "^2.3.0",
"rollup-plugin-summary": "^2.0.1"
},
"type": "module"
}
lit is the main package for lit, typescript is for the language used and rollup is used for building for production which will be explained at the end. The devDependencies are for mainly for rollup except for a web dev server (line having version 0.4.6) and terser for minifying the code (terser replaces the once widely used uglify-js during it's time)
npm i
should install everything without any errors creating a node_modules
sub-directory in the directory getting-started
.
Now in the terminal in the getting-started
directory, run tsc
which will convert my-elements.ts
to my-elements.js
. In case tsc doesn't work enter sudo npm i -g typescript
in terminal. This installed TypeScript 5.5.4 on my macOS. Or on Windows, open PowerShell in Administrator mode and run npm i -g typescript
and close the administrator PowerShell terminal and open a new non-admin PowerShell terminal and cd into the directory getting-started
.
tsc
will compile all .ts files to .js files into a folder called dist
(which we specified in tsconfg.json
as "outDir": "./dist",
). tsc my-element.ts
will compile to JavaScript with but will neglet the tsconfig.json
configuration file which is of no good because then it'll spit out all sorts of TypeScript compilation.
Now run npx web-dev-server --node-resolve --watch --open
- this will open localhost:8000 but will throw an error saying my-elements.js is not found (404).
If we edit the index.html file to specify the my-elements.js file in dist folder it'll work :
<script type="module" src="dist/my-elements.js"></script>
Ideally this shouldn't be done while development and there should be a way to specify the target folder containing the js files. I'll update this portion when I get some clarity on this.
Now your localhost:8000 should show this :
Now to build it for production. lit
recommends and explains the use of rollup
which is new to me too. But there are several mismatches in their documentation at https://lit.dev/docs/tools/production/ for the rollup.config.js
file. Here's my version :
// Import rollup plugins
import { rollupPluginHTML as html } from "@web/rollup-plugin-html";
import {copy} from '@web/rollup-plugin-copy';
import resolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
// import minifyHTML from 'rollup-plugin-minify-html-literals';
import summary from 'rollup-plugin-summary';
export default {
plugins: [
// Entry point for application build; can specify a glob to build multiple
// HTML files for non-SPA app
html({
input: 'index.html',
}),
// Resolve bare module specifiers to relative paths
resolve(),
// Minify HTML template literals
// minifyHTML(),
// Minify JS
terser({
ecma: 2021,
module: true,
warnings: true,
}),
// Print bundle summary
summary(),
// Optional: copy any static assets to build directory
copy({
patterns: ['images/**/*'],
}),
],
output: {
dir: 'build',
},
preserveEntrySignatures: 'strict',
};
I couldn't install rollup-plugin-minify-html-literals
on my macOS and Windows machines.
But I realised that rollup-plugin-minify-html-literals
was used only for minifying HTML here. So I commented out the minifyHTML()
call in rollup.config.js
file - and also it's import.
Now run rollup -c
- I had to do sudo npm i -g rollup
before running rollup -c
again. It would've created a build in the build
folder.
Now goto the build
folder and you'll there are 2 files - index.html
and my-elements.js
- to run index.html run a simple webserver in the build folder like
npx web-dev-server --node-resolve --watch --open
or
php -S localhost:8000
if you have PHP installed.
and you'll be able to see the text on your localhost:8000 webpage.
Happy litting.