Advanced
Web Applications


JavaScript, Vite

Objectives

  • Node.js, npm, Vite
  • HTML, JavaScript, SASS, Typescript
  • Hot Redeployment
  • Deployment

Vite

Vite is a (zero-configuration) build tool. It is opinionated and comes with sensible defaults out of the box. Vite can be installed using npm. npm is distributed with Node.js. We employ vite to create a new project using "npm create" command, which is similar to "composer create-project" command.


npm create vite@latest
	
  • package.json
  • index.html
  • nesting with style.scss (npm install -D sass)
  • npm run dev
  • hot redeployment
  • npm run build

Typescript

Set initial counter value to "0" in counter.ts file.


setCounter("0");
	

article-service.ts


interface Article {
	identifier: string;
	title: string;
}

export async function fetchArticles(): Promise<Article[]> { /* ... */ }
	

main.ts


import { fetchArticles } from "./article-service.ts";

async function renderArticles() {
	const articles = await fetchArticles();
	/* TODO: Render articles */
}
	

Multiple entry points

Unless developing single-page-application we may need multiple entry files. It works just fine for "dev", but same is not true for "build".

Build tools often provide tool-specific way of configuration. In case of Vite, we can employ vite.config.js file to configure multiple entry points.


// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
	build: {
		rollupOptions: {
			input: {
				main: resolve(__dirname, 'index.html'),
				content: resolve(__dirname, 'content.html'),
			},
		},
	},
})
	

Deployment

Run "build" command and check the output, the "./dist" directory. Would it work when deployed to you home directory at webik?

Assignment: Vite

./practical-03/vite

Create a Vite project with Typescript. The project must contain three entry points: index.html, list.html and about.html. All pages must contain navigation bar with links to all other pages.

The list.html list articles from ./api/v1/articles (as defined in PHP, ORM practical) and show them using an ordered list. See code fragment on the next slide. index.html must contain string "index" and about.html must contain string "about", besides those strings the content is up to you.

  • Configure the build so the application can be deployed to any location, i.e. paths must start with "./".
  • The application must contain separate Typescript file with service for loading the data.
  • Style the application using custom styles in SCSS file.
  • Use Vanilla JS, no React, Vue, etc...

Article list fragment

Example utilize same data as in PHP, ORM practical.


<ul class="article-list">
	<li class="item">
			<a href="./api/v1/article-detail/0">Using ORM in PHP</h2>
	</li>
	<li class="item">
			<a href="./api/v1/article-detail/1">Using Slim in PHP</h2>
	</li>
</li>
		

If there are no articles the page must contain following fragment:


<p>
	There are no articles.
</p>
		

Resources

Optional section about hot reloading.

Semestral team project

Extra: Hot Redeployment

Hot Module Replacement is capable of replacing JS code without the need of a reload. You can integrate with HRM using build tool API. This integration is usually handled by a framework, but we can interact with it as well. It works on level of modules ~ individual files ~ HMR boundary.

  • Create counter service in service.ts.
  • Add support for reload to consuming module.

HRM: service.ts


export const createService = () => {
	return {
		data: { counter: 1 },
		value() { return this.data.counter },
		increase() { this.data.counter += 5 }
	}
}
		

HRM: service.ts


import { createService } from "./service";
let service = createService();
...
if (import.meta.hot) {
	import.meta.hot.accept(["./service"], ([serviceModule]) => {
		// Get next service.
		const nextService = serviceModule.createService();
		// Move data from old to new.
		nextService.data = service.data;
		// Replace old with new.
		service = nextService;    
	})
}
		

Call order

  • vite:beforeUpdate - old version
  • load/run - new version script
  • accept - in old version with new module given
  • vite:afterUpdate - new version
Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.