Skip to content

Lit DOM Elements. Example Repository to document how to create and publish web components with Lit & Vite

License

Notifications You must be signed in to change notification settings

DevboiDesigns/devboi-test-component

Repository files navigation

Lit & Vite Web Component

Example Repository to document how to create and publish web components with vite & lit.

Create a Vite & Lit web component and publish to NPM and consume in a new project.

Create Web Component

Example setup for a package named devboi-test-component. Be sure to replace all instances of this name with your own package name.

  1. Create package:
npm create vite@latest devboi-test-component -- --template lit-ts
  1. Delete assets, public dist, sample element, and remove favicon from index.html.

  2. Create vite.config.js:

Depending on your project externalize deps that shouldn't be bundled

import { resolve } from "path"
import { defineConfig } from "vite"

export default defineConfig({
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, "src/index.ts"),
      name: "NewCmp",
      // the proper extensions will be added
      fileName: "devboi-test-component",
    },
    rollupOptions: {
      // make sure to externalize deps that shouldn't be bundled
      // into your library
      external: ["lit"],
    },
  },
})
  1. Create some test components to export in the src dir:
  • one-element.ts
import { LitElement, html } from "lit"
import { customElement, property } from "lit/decorators.js"

@customElement("one-element")
class OneElement extends LitElement {
  @property({ type: String }) oneName = "Default Company Name"

  render() {
    return html`<pre>${this.oneName}</pre>`
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "one-element": OneElement
  }
}
  • two-element.ts
import { LitElement, html } from "lit"
import { customElement, property } from "lit/decorators.js"

@customElement("two-element")
class TwoElement extends LitElement {
  @property({ type: String }) twoName = "Default Company Name"

  render() {
    return html`<pre>${this.twoName}</pre>`
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "two-element": TwoElement
  }
}
  1. Create a barrel file entry point in the src dir and export all components:
  • src/index.ts
export * from "./one-element"
export * from "./two-element"
  1. Update tsconfig.json:
{
  "compilerOptions": {
    "target": "es2017",
    "module": "es2015",
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "experimentalDecorators": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "outDir": "./types",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "useDefineForClassFields": false
  },
  "include": ["src/**/*.ts"]
}
  1. Setup index.html and test new components with npm run dev:

Make sure to import the new src/index.ts export file.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Test Component</title>
    <link rel="stylesheet" href="./src/index.css" />
    <script type="module" src="/src/index.ts"></script>
  </head>
  <body>
    <one-element oneName="One-Name"></one-element>
    <two-element twoName="TwoName"></two-element>
  </body>
</html>
  1. Setup package.json:
  • Remove:
    • private

Update the peer dependencies

  • Add:
    • name of package
    • type
    • files
    • main
    • module
    • exports
    • repository
{
  "name": "devboi-test-component",
  "version": "0.0.1",
  "type": "module",
  "files": ["dist", "types"],
  "main": "./dist/devboi-test-component.umd.cjs",
  "module": "./dist/devboi-test-component.js",
  "exports": {
    ".": {
      "import": "./dist/devboi-test-component.js",
      "require": "./dist/devboi-test-component.umd.cjs"
    }
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/DevboiDesigns/devboi-test-component"
  },
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "peerDependencies": {
    "lit": "^3.2.1"
  },
  "devDependencies": {
    "typescript": "~5.6.2",
    "vite": "^6.0.5"
  }
}

Publish

npm publish --access public

Testing in a new project

Load the module via skypack:

<script
  type="module"
  src="https://cdn.skypack.dev/devboi-test-component"
></script>

Create a new empty directory with an index.html file and add the below code. You should see the components in the browser.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script
      type="module"
      src="https://cdn.skypack.dev/devboi-test-component"
    ></script>
    <title>Test Component</title>
    <style>
      * {
        background-color: black;
        color: white;
      }
    </style>
  </head>
  <body>
    <one-element oneName="Test&nbsp;Name"></one-element>
    <fake-element fakeName="FakeName"></fake-element>
    <two-element twoName="Two&nbsp;Name"></two-element>
  </body>
</html>

Notes

  • The repo also contains a branch config_using_vue for setting up the project to use Vue files.

Interesting helpful links:

Star on GitHub 🤩

If you found this example to be helpful star this project on GitHub.

GitHub stars


Source code

License

About

Lit DOM Elements. Example Repository to document how to create and publish web components with Lit & Vite

Topics

Resources

License

Stars

Watchers

Forks