Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New getting started doc #969

Merged
merged 2 commits into from
Apr 27, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
337 changes: 259 additions & 78 deletions docs/_guide/start.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,131 +8,312 @@ slug: start
* ToC
{:toc}

## Setup
There are two main ways to use LitElement:

You need npm and Node.js to work with LitElement. To install npm and Node.js, see the [instructions on NodeJS.org](https://nodejs.org/en/).

LitElement uses JavaScript modules to import dependencies by their npm package names. Since web browsers need to know a file's full URL to import it, your local development server needs to serve full, transformed URL paths to your web browser.
* **Creating reusable components to share with other developers.** Individual components or sets of related components are usually published to npm. To create a reusable component project, see [Create a LitElement component project](#component-project).

To deploy an optimized build that works on your target browsers, you'll also need a build toolset that can handle this transform, along with any bundling.
* **Creating app-specific components.** The source for these components may live as part of an application project. To add LitElement components to your app, see [Add LitElement to an existing project](#existing-project).

One option is Polymer CLI, which includes a development server that converts module names to paths on the fly; and a configurable build tool that packages your code for deployment.
## Create a LitElement component project {#component-project}

To install Polymer CLI with npm:
Get started writing a reusable LitElement component that could be published for others to use.

```bash
npm install -g polymer-cli
```
To get started working on a component locally, you can use one of these starter projects:

To serve a LitElement project locally:
* [LitElement JavaScript starter project ](https://github.com/PolymerLabs/lit-element-starter-js)
* [LitElement TypeScript starter project](https://github.com/PolymerLabs/lit-element-starter-ts)

```bash
polymer serve
```
Both projects define a LitElement component. They also add a set of optional tools for developing, linting, and testing the component:

See the [Polymer CLI documentation](https://polymer-library.polymer-project.org/3.0/docs/tools/polymer-cli) for more information on configuring these tools.
* Node.js and npm for managing dependencies. _Requires Node.js 10 or greater._
* A local dev server, [ES dev server](https://open-wc.org/developing/es-dev-server.html#getting-started).
* Linting with [ESLint](https://eslint.org/) and [lit-analyzer](https://www.npmjs.com/package/lit-analyzer).
* Testing with [Karma](https://karma-runner.github.io/latest/index.html).
* A static doc site built with [web component analyzer](https://www.npmjs.com/package/web-component-analyzer) and [eleventy](https://www.11ty.dev/).

Read on to create a component, or [download a sample LitElement project](https://github.com/PolymerLabs/start-lit-element).
None of these tools is _required_ to work with LitElement. They represent one possible set of tools for a good developer experience.

## Create a LitElement component
<div class="alert alert-info">

To create a new class based on LitElement:
**Alternative starting point.** As an alternative to the official LitElement starter projects, the open-wc project has a [project generator](https://open-wc.org/init/) for both web components using LitElement. The open-wc script asks a series of questions and scaffolds out a project for you.

1. In your project folder, install the `lit-element` package from npm:
</div>

`npm install lit-element`
### Download the starter project

2. Write your new element:
The quickest way to try out a project locally is to download one of the starter projects as a zip file.

* Import the `LitElement` base class and the `html` helper function.
* Create a new class that extends the `LitElement` base class.
* Implement `render` to define a template for your web component.
* Register your component's HTML tag with the browser.
1. Download the starter project from GitHub as a zip file:

**Example**
* [JavaScript starter project](https://github.com/PolymerLabs/lit-element-starter-js/archive/master.zip)
* [TypeScript starter project](https://github.com/PolymerLabs/lit-element-starter-ts/archive/master.zip)

_my-element.js_
1. Uncompress the zip file.

```js
{% include projects/docs/create/my-element.js %}
```
1. Install dependencies.

{% include project.html folder="docs/create" openFile="my-element.js" %}
```bash
cd <project folder>
npm i
```

### Use LitElement TypeScript decorators
<div class="alert alert-info">

You can use the `@customElement` TypeScript decorator to define your class as a custom element:
**Want it on GitHub?** If you're familiar with git you may want to create a GitHub repository for your starter project,
instead of just downloading the zip file. You can use the [GitHub template repository](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template) feature to create your own repository from the [JavaScript starter project ](https://github.com/PolymerLabs/lit-element-starter-js) or the [TypeScript starter project](https://github.com/PolymerLabs/lit-element-starter-ts). Then clone your new repository and install dependencies, as above.

```ts
{% include projects/docs/typescript/my-element.ts %}
```
</div>

{% include project.html folder="docs/typescript" openFile="my-element.ts" %}
### Try out your project

## Import a component
1. If you're using the TypeScript version of the starter, build the JavaScript version of your project:

### Import your own LitElement component
```bash
npm run build
```

In an HTML document:
To watch files and rebuild when the files are modified, run the following command in a separate shell:

```html
<head>
<script type="module" src="/path/to/my-element.js"></script>
</head>
<body>
<my-element></my-element>
</body>
```
```bash
npm run build:watch
```

In another JavaScript module:
No build step is required if you're using the JavaScript version of the starter project.

```js
// Use relative paths for peer dependencies
import './my-element.js';
1. Run the dev server:

class MyOtherElement extends LitElement{
render(){
return html`
<my-element></my-element>
`;
}
}
customElements.define('my-other-element', MyOtherElement);
```bash
npm run serve
```

1. Open the project demo page in a browser tab. For example:

[http://localhost:8000/dev/](http://localhost:8000/dev/)

Your server may use a different port number. Check the URL in the terminal output for the correct port number.


### Edit your component

Edit your component definition. The file you edit depends on which language you're using:

* JavaScript. Edit the `my-element.js` file in the project root.
* TypeScript. Edit the `my-element.ts` file in the `src` directory.

A couple of things to look for in the code:

* The code defines a class for the component (`MyElement`) and registers it with the browser as a custom element named `<my-element>`.

_JavaScript_

```js
export class MyElement extends LitElement { ... }
arthurevans marked this conversation as resolved.
Show resolved Hide resolved
customElements.define('my-element', MyElement);
```

_TypeScript_

```ts
@customElement('my-element')
export class MyElement extends LitElement { ... }
```


* The component's `render` method defines a [template](templates) that will be rendered as a part of the component. In this case, it includes some text, some data bindings, and a button. For more information, see [Templates](templates).

```js
render() {
return html`
<h1>Hello, ${this.name}!</h1>
<button @click=${this._onClick} part="button">
arthurevans marked this conversation as resolved.
Show resolved Hide resolved
Click Count: ${this.count}
</button>
<slot></slot>
`;
}
```

* The component defines some [properties](properties). The component responds to changes in these properties (for example, by re-rendering the template when necessary). For more information, see [Properties](properties).

_JavaScript_

```js
static get properties() {
arthurevans marked this conversation as resolved.
Show resolved Hide resolved
return {
name: {type: String}
}
}

constructor() {
super();
this.name = 'World';
}
```

_TypeScript_

```ts
@property({type: String})
name = 'World';
```

### Rename your component

You'll probably want to change the component name from "my-element" to something more appropriate. This is easiest to do using an IDE or other text editor that lets you do a global search and replace through an entire project.

1. If you're using the TypeScript version, remove generated files:

```bash
npm run clean
```

1. Search and replace "my-element" with your new component name in all files in your project (except in the `node_modules` folder).
1. Search and replace "MyElement" with your new class name in all files in your project (except in the `node_modules` folder).
1. Rename the source and test files to match the new component name:

JavaScript:

* `src/my-element.js`
* `src/test/my-element_test.js`

TypeScript:

* `src/my-element.ts`
* `src/test/my-element_test.ts`

1. Test and make sure your component is still working:

```bash
npm run build
npm run serve
arthurevans marked this conversation as resolved.
Show resolved Hide resolved
```

### Next steps

Ready to add features to your new component? Head over to [Templates](templates) for details on writing templates for your LitElement component.

For details on running tests and using other tools, see the starter project README:

* [TypeScript project README](https://github.com/PolymerLabs/lit-element-starter-ts/blob/master/README.md)
* [JavaScript project README](https://github.com/PolymerLabs/lit-element-starter-js/blob/master/README.md)

## Add LitElement to an existing project {#existing-project}

You don't need a lot of tooling for LitElement projects. Chances are if you have an existing set of tools, you can integrate LitElement into it with very limited changes. These instructions assume you're using npm for package management, and using a tool like Rollup or Webpack to bundle your code for production.

<div class="alert alert-info">

**If you're starting from scratch**, the open-wc project has a [project generator](https://open-wc.org/init/) that can scaffold out an application project using LitElement.

</div>

### Prerequisites

Your build system will need to handle consuming bare module specifiers:

```js
import {LitElement, html} from 'lit-element';
```

### Import a third-party LitElement component
Webpack automatically handles bare module specifiers; for Rollup, you'll need a plugin ([@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve)).

**Refer to third-party component documentation first.** To work with any existing component made by a third party, see its documentation. This guide should work for most LitElement-based components if they are published on npm.
### Install LitElement

Many components are published on npm and can be installed from the command line:
LitElement is available from npm:

```bash
cd my-project-folder
npm install package-name
npm i lit-element
```

In an HTML document, a component published on npm can be imported from the `node_modules` folder:
### Add an element

```html
<head>
<script type="module" src="node_modules/package-name/existing-element.js"></script>
</head>
<body>
<existing-element></existing-element>
</body>
```
Pick a location to store your LitElement components, and create a test element:

To import into another JavaScript module, use the component's package name:
_components/my-element.js_

```js
import 'package-name/existing-element.js';
import {LitElement, html} from 'lit-element';

class MyElement extends LitElement{
render(){
class MyElement extends LitElement {
render() {
return html`
<existing-element></existing-element>
<div>Hello from MyElement!</div>
`;
}
}

customElements.define('my-element', MyElement);
```

Import your component:

Index.js

```js
import './components/my-elements.js';
```

Use your component:

index.html

```html
<my-element></my-element>
```

At this point, you should be able to build and run your project and see the "Hello from MyElement!" message.

<div class="alert alert-info">

**Adjust for your build system.** How you import the component may vary slightly depending on your build system and project structure.
arthurevans marked this conversation as resolved.
Show resolved Hide resolved

</div>


### Optional: Use ES dev server

If you already have a dev server that works with your build system, it should work with LitElement. [ES dev server](https://open-wc.org/developing/es-dev-server.html) is an alternative dev server that provides a simple, bundler-free workflow. It performing a small number of useful transforms, including transforming bare module specifiers, transpiling to ES5 when needed, and adding polyfills for older browsers.
arthurevans marked this conversation as resolved.
Show resolved Hide resolved

1. Install es-dev-server

```bash
npm i -D es-dev-server
```

1. Add a dev server command to `package.json`:


```json
{
"scripts": {
"start": "es-dev-server --app-index index.html --node-resolve --watch --open"
}
}
```

1. Start ES dev server:

```bash
npm run start
```

### Supporting older browsers
arthurevans marked this conversation as resolved.
Show resolved Hide resolved

To support older browsers that don't support ES6 and the web components specifications, you'll need to take a few extra steps:

* Compile to ES5. Your build will also need to transform JavaScript modules into a format compatible with older browsers, like AMD.
arthurevans marked this conversation as resolved.
Show resolved Hide resolved
* Include the [web components polyfills](https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs). In almost all cases, you'll also want to include [custom-elements-es5-adapter.js](https://github.com/webcomponents/polyfills/tree/master/packages/webcomponentsjs#custom-elements-es5-adapterjs) to ensure that your ES5 version can also run on newer browsers.

If you need to support older browsers, there are two basic approaches you can take:

* Serve the ES5 version of the project to all browsers.
* Build both ES6 and ES5 versions of your project, and serve the ES6 version to modern browsers only.
arthurevans marked this conversation as resolved.
Show resolved Hide resolved


### Next steps

Ready to add features to your project? Head over to [Templates](templates) for details on writing templates for your LitElement component.

For more on building applications that use web components, see the open-wc recommendations on [Building](https://open-wc.org/building/).