SlideShare a Scribd company logo
Building a JS widget
...from whiteboard to delivery
Tudor Barbu
@motanelu
Components
Backend Frontend(s)
<div id="widget"></div>
<script type="text/javascript">
new Messaging.Widget({
selector: '#widget',
userId: 1,
// other configuration
})
</script>
> 768px
< 768px
Path to the widget
Know your customer!
Who is the customer?
Users - final customers that
● live in different geographies
● use “exotic” browsers
● have different connection speeds
● different expectations (realtime, file uploads)
Marketplaces, customers that
● are built on different technologies, ranging
from React to Smarty & PHP
● want to be able to customize the widget, but
without breaking it
● have different build systems (or none)
● have dedicated frontend teams (or not)
● have sometimes hard to predict release
cycles
And they don’t always update
to the latest version!
Messaging engineer waiting for a marketplace
update
First set of requirements:
● cross-platform / responsive
● customizable look-n-feel
● support browsers you didn’t know exist
● ...without breaking customizations /
responsiveness
● support React, direct injection via script tag
and everything in between
● be able to update the widget to newer
versions without relying on input from the
marketplaces
● don’t forget about cool features like sending
images from your phone, real-time and so on
Yandex Browser
● deprecated APIs with the new ones being
developed at the moment
● server doesn’t support real-time, but we still
want it (polling)
● ...and A/B tests, we need to be able to run tests,
independent of the marketplace
“Dream” requirements
1 Abstract the API
4 Update & A/B tests
2 Develop the widget
3 Handle customizations
1 Abstract the API
Connector
External library (npm install)
Abstracts the access to the API
connector.on('counter-update', entity => {
// do something
})
// ajax - ticks handled internally
import axios from 'axios'
import EventEmitter from 'events'
const bus = new EventEmitter();
axios
.get('url')
.then(response => {
bus.emit('counter-update', {})
})
// socket
import io from 'socket.io-client'
import EventEmitter from 'events'
const bus = new EventEmitter();
socket
.on('counter-push-received', data => {
bus.emit('counter-update', {})
})
WidgetConnector
import axios from 'axios'
// inside the use case
url = `/v1/getConversation/?id=${conversationId}`
axios.get(url)
.then(response => {
return ConversationEntity.legacy(response)
})
import axios from 'axios'
// inside the use case
url = `/api/v2/conversation/${conversationId}`
axios.get(url)
.then(response => {
return ConversationEntity.create(response)
})
const promise = connector.useCase()
.getConversation.execute(conversationId)
promise
.then((conversation) => {
conversation.markAsRead()
})
.catch((error) => {
// handle
})
Test
Unit tests
Karma / chai / sinon
PhantomJS
Release
release on tag
build on Travis
npm registry / Artifactory
Vue + Vuex + VueRouter
DOM API
Widget
<template>
<ul class="msg-list__items" ref="conversationsList">
<conversations-list-item
v-for="conversation in conversations"
:conversation="conversation"
:key="conversation.conversationId"
/>
</ul>
</template>
Architecture
● <conversation-menu> and <*-item> have state injected
from the parent
● everything else gets it from Vuex
● child components are agnostic with regards to the state of
the parent
● container components handle their own events (infinite
scrolling) and load additional children as required
DOM API directly
...practice frowned upon by the Vue community!
1. The target element of the event is a link or a form field.
2. The target element, or any of its ancestors up to but not including the <body>,
has an explicit event handler set for any of the mouse events. This event
handler may be an empty function.
3. The target element, or any of its ancestors up to and including the document
has a cursor: pointer CSS declarations.
https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
Click anywhere on the page and close it!
const body = document.querySelector('body')
body.addEventListener('click', (event) => {
closeMenu()
})
Doesn’t work!!!
// ...
overlay = document.createElement('div')
overlay.id = 'messaging-widget-overlay'
overlay.style.position = 'absolute'
overlay.style.top = 0
overlay.style.right = 0
overlay.style.bottom = 0
overlay.style.left = 0
overlay.style.background = 'transparent'
overlay.style.display = 'none'
overlay.style.zIndex = 2100
overlay.addEventListener('click', () => {
events.$emit('close-menus')
})
document.querySelector('body').appendChild(overlay)
// ...
<html>
<head>
<!-- header stuff -->
</head>
<body>
<section id="header"></section>
<section id="content">
<div id="messaging">
<!-- widget goes here -->
</div>
</section>
<section id="footer"></section>
<div id="messaging-widget-overlay"
...
></div>
</body>
</html>
export default {
name: 'Widget',
created () {
// ...
this.injectMetaTags()
},
beforeDestroy () {
// ...
this.removeMetaTags()
},
// ...
}
<meta
id="messaging-widget-meta-viewport"
name="viewport"
content="width=device-width,
initial-scale=1.0, maximum-scale=1.0,
user-scalable=no"
>
<meta
id="messaging-widget-meta-format-detection"
name="format-detection" content="telephone=no"
>
<meta
id="messaging-widget-meta-http-equiv"
http-equiv="X-UA-Compatible"
content="IE=edge"
>
3 Customizations
* Block element modifier
** Not the actual logo
* **
Layout
● Handles positioning of various elements
● Ensures responsiveness
● Should not be overridden by the marketplace
Theme
● Handles colors and border radii
● Injects the icons as data-urls
● Should be overridden by the marketplace
Vertical media query
(height < 400)
FAAST
* Frontend as a Service Technology
4 Update & A/B tests
<script
type="text/javascript"
src="cdn://faast.min.js">
</script>
<script type="text/javascript">
faast(
'messaging-widget',
'<env>',
{siteName: 'test'},
additionalConfiguration
)
.then(fn => {
new Messaging.Widget({
// configuration here
})
// call fn() to remove created elements
})
.catch(error => {
// do something
})
</script>
Create
<script>
tags
Fulfill the
promise
What’s the version for site name?
<script src="..."> & <link href="...">
JSON response
All files finished loading
FAAST server
FAAST API CLI tools
FAAST client
● Vanilla js - new XmlHttpRequest(...)
● 140 lines of code (with comments :) )
● Guarantees the order of the scripts
● Waits for all scripts to load before fulfilling the
promise
● Provides a clean-up mechanism
● cssBefore <selector> and jsBefore <selector>
{
"environment": "pre",
"resourceName": "messaging-widget",
"scripts": [
"https://cdn/messaging.widget.min.js?v=0dbb87d9"
// more files here
],
"styles": [
"https://cnd/messaging.widget.min.css?v=0dbb87d9"
// more files here
],
"version": "1.7.1"
}
<link rel="stylesheet" href="messaging.min.css">
<link rel="stylesheet" href="site-theme.css">
FAAST Marketplace site
normal flow
cssBefore: <selector>
const promise = faast(
'messaging-widget',
'pre',
{siteName: 'test'},
{cssBefore: 'link[rel=stylesheet]:first-of-type'}
)
Pros and cons:
~ 15kb of duplication, as icons are included with data urls
...but the widget will work even if the site theme is broken or missing
Player 2 has entered the game...
● Native react component (3rd js repository)
● Published to Artifactory as npm package
● Wraps around FAAST which wraps around the widget
(Wrapception)
Hydra of nondeterministic bugs
Test & release
Pain points
● Entanglement - React / FAAST / Widget
● Slow booting machines in Saucelabs (45’ - 1h)
● Not really mockable
● It must be deployed to other sites automatically
*without breaking them*
● Tickets should receive business validation before
being deployed (manual step)
● 1-2 releases per week on normal flow
Minimal set of tests
● Run against a small number of browsers
● Cover the basic functionality
● Run on mocked responses to account for
common mistakes
● Designed to run fast
● Act as an early warning system
Full set of tests
● Run against all supported browsers
● Cover most functionality
● Slow, only when releasing
● Run on live APIs
Triggered releaseContinuous delivery
www.spinnaker.ioCore contributor
● Open source delivery platform
● Multi cloud provider
● Acts like a pipeline
● Jobs are handled by Travis
● Used by Google, Netflix, Schibsted :)
FAAST
Messaging
Preprod
Business
validation
All sites preAll sites pro
(waiting period)
(engineer) (minimal)
(tag)
(full with mocks)
Release procedure (wip)
Normal
flow
(full with live APIs)
Cool?
jobs.schibsted.com
@Schibsted_Eng
bytes.schibsted.com
github.com getbem.com travis-ci.org nightwatchjs.org facebook.github.io/react AWS S3
sass-lang.com spring.io karma-runner Saucelabs webpack Phantomjs
AWS EC2AWS DynamoDByarnCassandra
Tools

More Related Content

What's hot

Backbone.js
Backbone.jsBackbone.js
Backbone.js
VO Tho
 
VueJS Introduction
VueJS IntroductionVueJS Introduction
VueJS Introduction
David Ličen
 
Introduction to VueJS & Vuex
Introduction to VueJS & VuexIntroduction to VueJS & Vuex
Introduction to VueJS & Vuex
Bernd Alter
 
An introduction to Vue.js
An introduction to Vue.jsAn introduction to Vue.js
An introduction to Vue.js
Javier Lafora Rey
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
TrevorBurnham
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
TechExeter
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service Worker
Chang W. Doh
 
Packing it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to nowPacking it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to now
Derek Willian Stavis
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
Javier Abadía
 
Vuex
VuexVuex
Developing large scale JavaScript applications
Developing large scale JavaScript applicationsDeveloping large scale JavaScript applications
Developing large scale JavaScript applications
Milan Korsos
 
Vue 淺談前端建置工具
Vue 淺談前端建置工具Vue 淺談前端建置工具
Vue 淺談前端建置工具
andyyou
 
Service worker - Offline Web
Service worker - Offline WebService worker - Offline Web
Service worker - Offline Web
Bruno Oliveira
 
An Introduction to Vuejs
An Introduction to VuejsAn Introduction to Vuejs
An Introduction to Vuejs
Paddy Lock
 
Service worker API
Service worker APIService worker API
Service worker API
Giorgio Natili
 
Meet VueJs
Meet VueJsMeet VueJs
Meet VueJs
Mathieu Breton
 
iPhone Appleless Apps
iPhone Appleless AppsiPhone Appleless Apps
iPhone Appleless Apps
Remy Sharp
 
The Point of Vue - Intro to Vue.js
The Point of Vue - Intro to Vue.jsThe Point of Vue - Intro to Vue.js
The Point of Vue - Intro to Vue.js
Holly Schinsky
 
Drupal point of vue
Drupal point of vueDrupal point of vue
Drupal point of vue
David Ličen
 
Vue.js is boring - and that's a good thing
Vue.js is boring - and that's a good thingVue.js is boring - and that's a good thing
Vue.js is boring - and that's a good thing
Joonas Lehtonen
 

What's hot (20)

Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
VueJS Introduction
VueJS IntroductionVueJS Introduction
VueJS Introduction
 
Introduction to VueJS & Vuex
Introduction to VueJS & VuexIntroduction to VueJS & Vuex
Introduction to VueJS & Vuex
 
An introduction to Vue.js
An introduction to Vue.jsAn introduction to Vue.js
An introduction to Vue.js
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 
Instant and offline apps with Service Worker
Instant and offline apps with Service WorkerInstant and offline apps with Service Worker
Instant and offline apps with Service Worker
 
Packing it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to nowPacking it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to now
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
 
Vuex
VuexVuex
Vuex
 
Developing large scale JavaScript applications
Developing large scale JavaScript applicationsDeveloping large scale JavaScript applications
Developing large scale JavaScript applications
 
Vue 淺談前端建置工具
Vue 淺談前端建置工具Vue 淺談前端建置工具
Vue 淺談前端建置工具
 
Service worker - Offline Web
Service worker - Offline WebService worker - Offline Web
Service worker - Offline Web
 
An Introduction to Vuejs
An Introduction to VuejsAn Introduction to Vuejs
An Introduction to Vuejs
 
Service worker API
Service worker APIService worker API
Service worker API
 
Meet VueJs
Meet VueJsMeet VueJs
Meet VueJs
 
iPhone Appleless Apps
iPhone Appleless AppsiPhone Appleless Apps
iPhone Appleless Apps
 
The Point of Vue - Intro to Vue.js
The Point of Vue - Intro to Vue.jsThe Point of Vue - Intro to Vue.js
The Point of Vue - Intro to Vue.js
 
Drupal point of vue
Drupal point of vueDrupal point of vue
Drupal point of vue
 
Vue.js is boring - and that's a good thing
Vue.js is boring - and that's a good thingVue.js is boring - and that's a good thing
Vue.js is boring - and that's a good thing
 

Similar to Building a js widget

Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMohammad Shaker
 
React native by example by Vadim Ruban
React native by example by Vadim RubanReact native by example by Vadim Ruban
React native by example by Vadim Ruban
Lohika_Odessa_TechTalks
 
A re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbaiA re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbai
Praveen Puglia
 
React: JSX and Top Level API
React: JSX and Top Level APIReact: JSX and Top Level API
React: JSX and Top Level API
Fabio Biondi
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
Astrails
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
jungkees
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Alessandro Molina
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWAREFIWARE
 
Angular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.xAngular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.x
Eyal Vardi
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Luciano Mammino
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
Igor Bronovskyy
 
Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017
Elyse Kolker Gordon
 
Love at first Vue
Love at first VueLove at first Vue
Love at first Vue
Dalibor Gogic
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
KatyShimizu
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
KatyShimizu
 
Service workers
Service workersService workers
Service workers
Pavel Zhytko
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
Nataliya Patsovska
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
jojule
 
Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기
Changwan Jun
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
Filippo Matteo Riggio
 

Similar to Building a js widget (20)

Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhone
 
React native by example by Vadim Ruban
React native by example by Vadim RubanReact native by example by Vadim Ruban
React native by example by Vadim Ruban
 
A re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbaiA re introduction to webpack - reactfoo - mumbai
A re introduction to webpack - reactfoo - mumbai
 
React: JSX and Top Level API
React: JSX and Top Level APIReact: JSX and Top Level API
React: JSX and Top Level API
 
Building and deploying React applications
Building and deploying React applicationsBuilding and deploying React applications
Building and deploying React applications
 
Service Worker - Reliability bits
Service Worker - Reliability bitsService Worker - Reliability bits
Service Worker - Reliability bits
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
 
Angular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.xAngular 1.x vs. Angular 2.x
Angular 1.x vs. Angular 2.x
 
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
Universal JS Web Applications with React - Web Summer Camp 2017, Rovinj (Work...
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017Building Universal Web Apps with React ForwardJS 2017
Building Universal Web Apps with React ForwardJS 2017
 
Love at first Vue
Love at first VueLove at first Vue
Love at first Vue
 
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Enterprise-Grade Serverless
 
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
 
Service workers
Service workersService workers
Service workers
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
 
Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기Serverless 프레임워크로 Nuxt 앱 배포하기
Serverless 프레임워크로 Nuxt 앱 배포하기
 
Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2Mobile App Development: Primi passi con NativeScript e Angular 2
Mobile App Development: Primi passi con NativeScript e Angular 2
 

Recently uploaded

Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
MayankTawar1
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
Sharepoint Designs
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Hivelance Technology
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
NaapbooksPrivateLimi
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
Jelle | Nordend
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
XfilesPro
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 

Recently uploaded (20)

Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
 
Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024Explore Modern SharePoint Templates for 2024
Explore Modern SharePoint Templates for 2024
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
Multiple Your Crypto Portfolio with the Innovative Features of Advanced Crypt...
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Visitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.appVisitor Management System in India- Vizman.app
Visitor Management System in India- Vizman.app
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 

Building a js widget

  • 1. Building a JS widget ...from whiteboard to delivery Tudor Barbu @motanelu
  • 2.
  • 5. <div id="widget"></div> <script type="text/javascript"> new Messaging.Widget({ selector: '#widget', userId: 1, // other configuration }) </script> > 768px < 768px
  • 6. Path to the widget
  • 8. Who is the customer?
  • 9. Users - final customers that ● live in different geographies ● use “exotic” browsers ● have different connection speeds ● different expectations (realtime, file uploads)
  • 10. Marketplaces, customers that ● are built on different technologies, ranging from React to Smarty & PHP ● want to be able to customize the widget, but without breaking it ● have different build systems (or none) ● have dedicated frontend teams (or not) ● have sometimes hard to predict release cycles
  • 11. And they don’t always update to the latest version! Messaging engineer waiting for a marketplace update
  • 12. First set of requirements: ● cross-platform / responsive ● customizable look-n-feel ● support browsers you didn’t know exist ● ...without breaking customizations / responsiveness ● support React, direct injection via script tag and everything in between ● be able to update the widget to newer versions without relying on input from the marketplaces ● don’t forget about cool features like sending images from your phone, real-time and so on Yandex Browser
  • 13. ● deprecated APIs with the new ones being developed at the moment ● server doesn’t support real-time, but we still want it (polling) ● ...and A/B tests, we need to be able to run tests, independent of the marketplace
  • 15. 1 Abstract the API 4 Update & A/B tests 2 Develop the widget 3 Handle customizations
  • 16. 1 Abstract the API Connector External library (npm install) Abstracts the access to the API
  • 17. connector.on('counter-update', entity => { // do something }) // ajax - ticks handled internally import axios from 'axios' import EventEmitter from 'events' const bus = new EventEmitter(); axios .get('url') .then(response => { bus.emit('counter-update', {}) }) // socket import io from 'socket.io-client' import EventEmitter from 'events' const bus = new EventEmitter(); socket .on('counter-push-received', data => { bus.emit('counter-update', {}) }) WidgetConnector
  • 18. import axios from 'axios' // inside the use case url = `/v1/getConversation/?id=${conversationId}` axios.get(url) .then(response => { return ConversationEntity.legacy(response) }) import axios from 'axios' // inside the use case url = `/api/v2/conversation/${conversationId}` axios.get(url) .then(response => { return ConversationEntity.create(response) }) const promise = connector.useCase() .getConversation.execute(conversationId) promise .then((conversation) => { conversation.markAsRead() }) .catch((error) => { // handle })
  • 19.
  • 20. Test Unit tests Karma / chai / sinon PhantomJS Release release on tag build on Travis npm registry / Artifactory
  • 21. Vue + Vuex + VueRouter DOM API Widget
  • 22. <template> <ul class="msg-list__items" ref="conversationsList"> <conversations-list-item v-for="conversation in conversations" :conversation="conversation" :key="conversation.conversationId" /> </ul> </template> Architecture ● <conversation-menu> and <*-item> have state injected from the parent ● everything else gets it from Vuex ● child components are agnostic with regards to the state of the parent ● container components handle their own events (infinite scrolling) and load additional children as required
  • 23.
  • 24. DOM API directly ...practice frowned upon by the Vue community!
  • 25. 1. The target element of the event is a link or a form field. 2. The target element, or any of its ancestors up to but not including the <body>, has an explicit event handler set for any of the mouse events. This event handler may be an empty function. 3. The target element, or any of its ancestors up to and including the document has a cursor: pointer CSS declarations. https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html Click anywhere on the page and close it! const body = document.querySelector('body') body.addEventListener('click', (event) => { closeMenu() }) Doesn’t work!!!
  • 26. // ... overlay = document.createElement('div') overlay.id = 'messaging-widget-overlay' overlay.style.position = 'absolute' overlay.style.top = 0 overlay.style.right = 0 overlay.style.bottom = 0 overlay.style.left = 0 overlay.style.background = 'transparent' overlay.style.display = 'none' overlay.style.zIndex = 2100 overlay.addEventListener('click', () => { events.$emit('close-menus') }) document.querySelector('body').appendChild(overlay) // ... <html> <head> <!-- header stuff --> </head> <body> <section id="header"></section> <section id="content"> <div id="messaging"> <!-- widget goes here --> </div> </section> <section id="footer"></section> <div id="messaging-widget-overlay" ... ></div> </body> </html>
  • 27. export default { name: 'Widget', created () { // ... this.injectMetaTags() }, beforeDestroy () { // ... this.removeMetaTags() }, // ... } <meta id="messaging-widget-meta-viewport" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" > <meta id="messaging-widget-meta-format-detection" name="format-detection" content="telephone=no" > <meta id="messaging-widget-meta-http-equiv" http-equiv="X-UA-Compatible" content="IE=edge" >
  • 29. * Block element modifier ** Not the actual logo * ** Layout ● Handles positioning of various elements ● Ensures responsiveness ● Should not be overridden by the marketplace Theme ● Handles colors and border radii ● Injects the icons as data-urls ● Should be overridden by the marketplace
  • 31. FAAST * Frontend as a Service Technology 4 Update & A/B tests
  • 32. <script type="text/javascript" src="cdn://faast.min.js"> </script> <script type="text/javascript"> faast( 'messaging-widget', '<env>', {siteName: 'test'}, additionalConfiguration ) .then(fn => { new Messaging.Widget({ // configuration here }) // call fn() to remove created elements }) .catch(error => { // do something }) </script> Create <script> tags Fulfill the promise What’s the version for site name? <script src="..."> & <link href="..."> JSON response All files finished loading FAAST server
  • 33. FAAST API CLI tools FAAST client ● Vanilla js - new XmlHttpRequest(...) ● 140 lines of code (with comments :) ) ● Guarantees the order of the scripts ● Waits for all scripts to load before fulfilling the promise ● Provides a clean-up mechanism ● cssBefore <selector> and jsBefore <selector> { "environment": "pre", "resourceName": "messaging-widget", "scripts": [ "https://cdn/messaging.widget.min.js?v=0dbb87d9" // more files here ], "styles": [ "https://cnd/messaging.widget.min.css?v=0dbb87d9" // more files here ], "version": "1.7.1" }
  • 34. <link rel="stylesheet" href="messaging.min.css"> <link rel="stylesheet" href="site-theme.css"> FAAST Marketplace site normal flow cssBefore: <selector> const promise = faast( 'messaging-widget', 'pre', {siteName: 'test'}, {cssBefore: 'link[rel=stylesheet]:first-of-type'} ) Pros and cons: ~ 15kb of duplication, as icons are included with data urls ...but the widget will work even if the site theme is broken or missing
  • 35.
  • 36. Player 2 has entered the game... ● Native react component (3rd js repository) ● Published to Artifactory as npm package ● Wraps around FAAST which wraps around the widget (Wrapception) Hydra of nondeterministic bugs
  • 38. Pain points ● Entanglement - React / FAAST / Widget ● Slow booting machines in Saucelabs (45’ - 1h) ● Not really mockable ● It must be deployed to other sites automatically *without breaking them* ● Tickets should receive business validation before being deployed (manual step) ● 1-2 releases per week on normal flow
  • 39. Minimal set of tests ● Run against a small number of browsers ● Cover the basic functionality ● Run on mocked responses to account for common mistakes ● Designed to run fast ● Act as an early warning system Full set of tests ● Run against all supported browsers ● Cover most functionality ● Slow, only when releasing ● Run on live APIs
  • 41. www.spinnaker.ioCore contributor ● Open source delivery platform ● Multi cloud provider ● Acts like a pipeline ● Jobs are handled by Travis ● Used by Google, Netflix, Schibsted :)
  • 42. FAAST Messaging Preprod Business validation All sites preAll sites pro (waiting period) (engineer) (minimal) (tag) (full with mocks) Release procedure (wip) Normal flow (full with live APIs)
  • 44. github.com getbem.com travis-ci.org nightwatchjs.org facebook.github.io/react AWS S3 sass-lang.com spring.io karma-runner Saucelabs webpack Phantomjs AWS EC2AWS DynamoDByarnCassandra Tools