Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Taming huge Angular applications at bol.com

Taming huge Angular applications at bol.com

At the backoffice of bol.com, fifteen autonomous development teams are working together to build and maintain huge Angular applications. Knowing that every team gets the best out of themselves through a large degree of autonomy, we decided not to force anyone to choose for a particular framework or development paradigms, which introduces lots of different challenges. One of them is maintaining consistency. In order to keep everything sane, we choose for a different approach: Building a framework independent Design System with Web Components.

This talk:
* Provides an overview of the enterprise application landscape and organization of teams at the backoffice of bol.com
* Covers the daily challenges faced by teams in extremely dynamic, enterprise environments
* Covers the pros and cons of using Angular
* Covers what a Design System is and how it helps solving those challenges

Stefan Nieuwenhuis

September 30, 2019
Tweet

More Decks by Stefan Nieuwenhuis

Other Decks in Technology

Transcript

  1. @stefannhs Taming huge enterprise applications with Mono repos, Design Systems

    & Web Components Software Engineer Archaeology Waterpolo Stefan Nieuwenhuis Skydiving Books Developer Avocado
  2. @stefannhs 1999 - bol.com launch > 2000 - new categories

    2011 - retail platform 2013 - €1 bln. turnover
  3. @stefannhs // Corporate colors $palette-blue-main: rgb(051,102,204) !default; $palette-blue-dark: rgb(014,052,144) !default;

    $palette-blue-light: rgb(058,125,231) !default; $palette-blue-hover: rgb(245,247,252) !default; // Secondary colors $palette-red-main: rgb(248,087,105) !default; $palette-orange-main: rgb(251,120,093) !default; $palette-yellow-main: rgb(255,162,078) !default; $palette-lime-main: rgb(150,210,113) !default; $palette-green-main: rgb(051,204,131) !default; Style guide
  4. @stefannhs // Create an ES6 class which extends HTMLElement class

    AwesomeButtonComponent extends HTMLElement { … } // Register our awesome button component to the Custom Elements Registry customElements.define(‘my-awesome-button’, AwesomeButtonComponent); // Example usage in your app: <my-awesome-button></my-awesome-button> Custom Elements API
  5. @stefannhs // export class Animal export class Animal { constructor(name)

    { this.name = name; } greet() { return `Hello, my name is ${this.name}!`; } } ES Modules API // import class Animal import {Animal} from './lib-class-example.js'; const animal = new Animal('Mr. Mittens'); const name = animal.greet(); // --> Hello, my name is Mr. Mittens!;
  6. @stefannhs <h1> My Awesome button </h1> <p>This button is made

    possible w/ Web Components!</p> <my-button>Click me</my-button>
  7. @stefannhs <template id="myButton"> <style>button { border: 2px solid red; border-radius:

    5px; background: tomato; padding: 10px; color: white; font-weight: bold; text-transform: uppercase; cursor: pointer; }</style> <button><slot/></button> </template>
  8. @stefannhs class MyButtonElement extends HTMLElement { constructor() { super(); const

    template = document.getElementById('myButton'); // Shadow DOM this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild( template.content.cloneNode(true)); } }
  9. @stefannhs class MyButtonElement extends HTMLElement { constructor() { super(); const

    template = document.getElementById('myButton'); // Shadow DOM this.attachShadow({ mode: 'open' }); this.shadowRoot.appendChild( template.content.cloneNode(true)); } } // Define Custom Element customElements.define('my-button', MyButtonElement);
  10. @stefannhs <h1> My Awesome button </h1> <p>This button is made

    possible w/ Web Components!</p> <my-button>Click me</my-button>
  11. @stefannhs // Stencil controller import { Component, Prop } from

    '@stencil/core'; @Component({ tag: 'my-component', styleUrl: 'my-component.css', shadow: true }) export class MyComponent { render() { return <div>Hello world!</div>; } }
  12. @stefannhs // Stencil controller import { Component, Prop } from

    '@stencil/core'; @Component({ tag: 'my-button', styleUrl: 'my-button.css', shadow: true }) export class MyButtonElement { render() { return <button><slot/></button>; } }
  13. @stefannhs ... <script src="/build/mycomponent.js"></script> </head> <body> <h1> My Awesome button

    </h1> <p>This button is made possible w/ Web Components!</p> <my-button>Click me</my-button> </body>
  14. @stefannhs { "name": "@awesome-components-lib/buttons", "version": "5.0.1", "description": "Button Component", ...

    } { "name": "@awesome-components-lib/footer", "version": "1.0.0", "description": "Footer Component", ... } Semantic Versioning No interdependencies Scoped packages