Exploring How lit-html Works: html and svg Function
Tags: javascript, typescript, webcomponents, devjournal
Published: 2020-01-04 13:51:36

In this series, How lit-html works, I will explore (not explain) internal implementation of [lit-html](https://lit-html.polymer-project.org/).

In [the previous post](https://dev.to/nozomuikuta/day-1-introduction-4log), we saw the contents of `/src` directory.

In this post, I will explore two functions, each of which is an entry point of the library.

# `html` and `svg` Function

Both `html` and `svg` are functions that receive a template literal and return an instance of `TemplateResult` and `SVGTemplateResult` classes, respectively.

```typescript
export const html = (strings: TemplateStringsArray, ...values: unknown[]) =>
    new TemplateResult(strings, values, 'html', defaultTemplateProcessor);
```

```typescript
export const svg = (strings: TemplateStringsArray, ...values: unknown[]) =>
    new SVGTemplateResult(strings, values, 'svg', defaultTemplateProcessor);
```

Before digging into the constructors, I will re-check what template literals (template strings) and tags are.

## Template Literals

According to [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals), template literals are string literals allowing embedded expressions.

```typescript
const name = 'Nozomu Ikuta'
const templateLiteral = `Hello, ${name}!`

console.log(templateLiteral) // => 'Hello, Nozomu Ikuta!'
```

## Tags (Tagged Templates)

Similarly, MDN says that tags allow us to parse template literals with a function. Tag itself is a function whose first argument is an array of strings, and whose the rest is the embedded expressions.

```typescript
const tag = (strings, value1, value2) => {
  console.log(strings); // => [ 'Hello, ', ' ', '!' ]
  console.log(value1);  // => 'Nozomu'
  console.log(value2);  // => 'Ikuta' 
  return `Goodbye, ${value1} ${value2}!`;
}
const firstName = 'Nozomu';
const lastName = 'Ikuta';
const tagged = tag`Hello, ${firstName} ${lastName}!`

console.log(tagged) // => 'Goodbye, Nozomu Ikuta!'
```

By default, each of embedded expressions is separately passed as an argument.

```typescript
const tag = (strings, value1, value2, ..., valueN) => { ... }
```

This is fine if it's clear the number of arguments to be passed. However, since lit-html can't know the number of them, it uses [the rest parameter syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). The rest parameter syntax enables a function to receive all the arguments as elements of an array.

```typescript
const tag = (strings, ...values) => {
  console.log(values) // => [ value1, value2, ..., valueN ]
}
```

This is also how `html` and `svg` functions can pass all the embedded expressions to the corresponding constructors.

# Summary

So far, I learned the following points:

- `html` function receives two arguments and pass them to `TemplateResult` constructor as well as two more arguments, `'html'` as as string, and `defaultTemplateProcessor`.
- `svg` function receives two arguments and pass them to `SVGTemplateResult` constructor as well as two more arguments, `'svg'` as a string, and `defaultTemplateProcessor`.

From the next posts, I will dig into the implementation of the constructors, what the passed arguments are, and how they are used.