## Getting Started
* Install Dependencies
```
npm init
npm install --save-dev ts-node typescript tslib express @types/express
```
## Create your web server
* Create `server.ts` in root folder of your app.
```typescript
import * as express from 'express';
import * as http from 'http';
import * as path from 'path';
import { AddressInfo } from 'net';
const app = express();
const PORT = 3000;
const HOST_NAME = `localhost`;
const PUBLIC_FOLDER = 'public';
app.use(`/${PUBLIC_FOLDER}`, express.static(path.resolve(PUBLIC_FOLDER)));
app.all('/*', function(req: express.Request, res: express.Response) {
res.sendFile('index.html', { root: path.resolve(PUBLIC_FOLDER) })
})
const server = http.createServer(app);
server.listen(PORT, HOST_NAME)
.on('listening', function() {
const { port, address } = server.address() as AddressInfo;
console.log(`Express server started on port ${port} at ${address}.`);
})
```
* Create `public` folder
* Create `public/index.html`
```html
TypeScript Web Component
Hello World.
```
* Create scripts in package.json
```json
"scripts": {
"serve": "ts-node -O '{ \"module\": \"commonjs\" }' server.ts"
}
```
* Run your server
```
npm run serve
```
* Browse your application
```
http://localhost:3000
```
## Create Web Components
* Create `src` folder
* Create `src/hello-world.ts`
* "Hello World" Custom Elements
```typescript
class HelloWorld extends HTMLElement {
connectedCallback() {
this.innerHTML = `Hello World.
`
}
}
customElements.define('hello-world', HelloWorld);
```
* Update `public/index.html` file
```html
TypeScript Web Component
```
## Setup Build tools using Rollup
* Add build dependencies
```
npm install --save-dev rollup rollup-plugin-typescript2 rollup-plugin-node-resolve
```
* Create `build.ts`
```typescript
import * as path from 'path';
import { rollup } from 'rollup';
const typescript2 = require('rollup-plugin-typescript2');
const resolve = require('rollup-plugin-node-resolve');
const ENTRY_FILE = `src/hello-world.ts`;
const rollupConfig = {
inputOptions: {
treeshake: true,
input: ENTRY_FILE,
external: [],
plugins: [
typescript2({
check: false,
cacheRoot: path.join(path.resolve(), 'node_modules/.tmp/.rts2_cache'),
useTsconfigDeclarationDir: true
}),
resolve()
],
onwarn (warning) {
if (warning.code === 'THIS_IS_UNDEFINED') { return; }
console.log("Rollup warning: ", warning.message);
}
},
outputOptions: {
sourcemap: true,
exports: 'named',
file: 'public/bundle.js',
name: 'hello-world',
format: 'es'
}
}
function rollupBuild({ inputOptions, outputOptions }): Promise {
return rollup(inputOptions).then(bundle => bundle.write(outputOptions));
}
rollupBuild(rollupConfig);
```
* Add scripts to your package.json
```json
"scripts": {
...
"build": "ts-node -O '{ \"module\": \"commonjs\" }' build.ts"
}
```
* Build & Run your application
```
npm run build && npm run serve
```
* Browse your app
```
http://localhost:3000
```
* Expected error when running the application
* In the browser (chrome) open the DevTools (right click the browser then Inspect)
* Go to console tab of the browser
* Check the error (in red color)
```
bundle.js:17 Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function.
at new HelloWorld (bundle.js:17)
at bundle.js:24
```
* Cause of the error.
```
This error means, that you need a polyfill for browser that do support (!) Custom Elements.
That sounds a bit strange, but Custom Elements are defined for EcmaScript 2015+
(bases upon classes) and for supporting older browser, we normally compile down to EcmaScript 5 today.
The output of your javascript is in es5 format.
```
* How to resolve or fix?
* Install custom-elements polyfill.
```
npm i @webcomponents/custom-elements
```
* In your `server.ts` file add `node_modules` folder as one of your static folders
```typescript
app.use(`/node_modules`, express.static(path.resolve('node_modules')));
```
* Add polyfill as script tag in your `public/index.html`
```html
```
* Run your application
```
npm run serve
```
* Browse your app
```
http://localhost:3000
```