unic - frontend development-in-complex-projects
DESCRIPTION
Talk by Thomas Jaggi and Romy Wysseier at the Frontend Conference Zurich 2012TRANSCRIPT
Frontend development in complex projects Frontend Conference Zurich 2012
Rosmarie Wysseier & Thomas Jaggi 9th September 2012
© Unic - Seite 2
• Gymnasium (Psychology and Economy)
• Creative Media Diploma, SAE Zürich, 2004
• Bachelor of Computer Science
University of Applied Sciences Bern, 2009
Rosmarie Wysseier
© Unic - Seite 3
Thomas Jaggi
• MSc Food Science (Major in Human
Nutrition) from ETH Zurich
• Fiddling around with frontend
technologies since before it was cool
© Unic - Seite 4
• Founded in 1996 in Switzerland
• We design, develop and maintain premium e-business solutions
for e-commerce, digital communication and collaboration
• We are an independent, owner-operated group with 270 employees
• Sales of 38 million CHF i.e. 33 million Euro (2011)
• 7 offices: Amsterdam, Bern, Brussels, Karlsruhe, Munich, Vienna and Zurich
Unic at a glance
© Unic - Seite 5
What we are going to talk about
• Writing maintainable and scalable
HTML / CSS
• Data mocking
• Unit testing
• Continuous integration
© Unic - Seite 6
• Lots of people involved
• Multiple devs / teams are working on the same project
• Sometimes in parallel, sometimes one after another
• High degree of uncertainty
• Detail specifications and/or design might still be in the works
• Interface frontend – backend not yet defined
Starting point
© Unic - Seite 7
Agenda
• Writing maintainable and scalable
HTML / CSS
• Data mocking
• Unit testing
• Continuous integration
© Unic - Seite 8
• Issue #1: HTML code is highly redundant
• Issue #2: CSS is location-dependent
• Issue #3: CSS assumes too much about the markup
• Issue #4: JS is not adequately separated from HTML / CSS
• Issue #5: No consistent coding style
Exemplary issues
Issue #1 HTML code is highly redundant
probably copyright-protected screenshot of “The Office”
© Unic - Seite 10
Click to edit Master title style
«The customer just told me he wants
this search form in the header, after
all.»
– Project manager
© Unic - Seite 11
• Design templates for every existing page type
• Usually: 1 design template = 1 HTML file
• Changing the structure means changing dozens of HTML files
• Find & replace has its limits
Problem: Redundant HTML code is difficult to maintain
© Unic - Seite 12
• Modularization of the HTML
• Our tool of choice: Middleman (http://middlemanapp.com)
Solution
© Unic - Seite 13
• Layout file:
• Partial:
Using partials in middleman
<html>
<head>
<title>My Site</title>
</head>
<body>
<%= partial "header" %>
<%= yield %>
</body>
</html>
<header>
<a href="#" class="logo“>Home</a>
</header>
© Unic - Seite 14
• Build process necessary
• HTML for one page type spread over many files
Disadvantages
Issue #2 CSS is location-dependent
probably copyright-protected screenshot of “The Office”
© Unic - Seite 16
Click to edit Master title style
«The customer just told me he wants to
to use this teaser in the main content
area, too.»
– Project manager
© Unic - Seite 17
Problem: Location-dependent CSS is not flexible
#sidebar a {
color: #c30;
text-decoration: none;
}
#sidebar .teaser {
background-image: linear-gradient(to bottom, #ddd, #fff);
padding: 1em;
}
#sidebar .teaser h3 {
font-size: 1.2em;
font-weight: normal;
margin-bottom: 1em;
}
© Unic - Seite 18
• Modularization
• Approach: OOCSS
Solution
© Unic - Seite 19
Click to edit Master title style
«Basically, a CSS “object” is a repeating
visual pattern, which can be abstracted
into an independent snippet of HTML,
CSS, and possibly JavaScript. Once
created, an object can then be reused
throughout a site.»
– OOCSS (https://github.com/stubbornella/oocss/wiki)
© Unic - Seite 20
• Some famous methodologies:
• OOCSS by Nicole Sullivan (https://github.com/stubbornella/oocss/)
• SMACSS by Jonathan Snook (http://smacss.com/)
• BEM by Yandex (http://bem.github.com/)
Multiple approaches
© Unic - Seite 21
• OOCSS:
• SMACSS:
• BEM
Examples (based on how I understand their docs)
<div class="teaser featured">
<h3 class="title">Title</h3>
<div class="bd">Blabla</div>
</div>
<div class="teaser is-featured">
<h3>Title</h3>
<div class="body">Blabla</div>
</div>
<div class="teaser teaser_type_featured">
<h3 class="teaser__title">Title</h3>
<div class="teaser__body">Blabla</div>
</div>
Issue #3 CSS assumes too much about the markup
probably copyright-protected screenshot of “The Office”
© Unic - Seite 23
Click to edit Master title style
«We can’t strictly implement your
HTML structure, our CMS renders
additional tags.»
– Backend developer
© Unic - Seite 24
• Before:
• After:
Example
<div class="block-teaser">
<h3>Title</h3>
<div class="content“>Blabla</div>
</div>
<div class="block-teaser">
<span id="hfk42342kj:ksa89080hajlk">
<h3>Title</h3>
</span>
<div class="content“>Blabla</div>
</div>
© Unic - Seite 25
• Avoid
• Immediate child selector:
• Adjacent sibling selector:
• And similar ones
• Use additional classes instead:
Problem: CSS assumes too much about the markup
.block-teaser > h3 {}
.block-teaser .xy + h3 {}
.block-teaser .title {}
// or faster regarding
// selector matching:
.block-teaser-title {}
Slide updated to reduce confusion
© Unic - Seite 26
• Missing out on generally useful selectors
• Extra markup
Disadvantages
Issue #4 JS is not adequately separated from HTML / CSS
probably copyright-protected screenshot of “The Office”
© Unic - Seite 28
Click to edit Master title style «Your JavaScript does not work. How
about testing before shipping?»
– Backend developer
© Unic - Seite 29
• JavaScript functionality is coupled too tightly to CSS selectors used for styling
• E.g.: Changing a class breaks the JS
Styling hooks used as JS hooks
© Unic - Seite 30
• HTML:
• JS:
Example
<div class=“carousel">
<ul>
<li>Hi there</li>
<li>Hi there 2</li>
</ul>
</div>
$(function() {
var $target = $('.carousel‘),
carousel = new Carousel($target);
carousel.init();
});
© Unic - Seite 31
• Use namespaced classes as your JS “hooks” (i.e. “js-carousel”)
• Use data attributes instead of classes
Solution
© Unic - Seite 32
Example
<div class="carousel" data-init="carousel“ data-options='{}'>
<ul data-role="items">
<li data-role="item">Hi there</li>
<li data-role="item">Hi there 2</li>
</ul>
</div>
© Unic - Seite 33
• Performance of attribute selectors
• Extra markup
Disadvantages
Issue #5 No consistent coding style
probably copyright-protected screenshot of “The Office”
© Unic - Seite 35
Click to edit Master title style
«I just refactored your multi-line
declarations into single-line ones
because I like them better.»
– Other frontend developer
© Unic - Seite 36
• Indentation, spaces: CSS/JS is difficult to read
• Structure: Specific parts are hard to find
• Versioning: Refactoring messes up history
Problem: Every developer follows his own private styleguide
© Unic - Seite 37
• Use soft-tabs with a two space indent.
• Put spaces after : in property declarations.
• Put spaces before { in rule declarations.
• Use hex color codes #000 unless using rgba.
• Use // for comment blocks (instead of /* */).
• Document styles with KSS
Example: Github (https://github.com/styleguide/css)
© Unic - Seite 38
• Takes a lot of time to develop / agree on
• Restricting
Disadvantages
© Unic - Seite 39
• Curated by Chris Coyier, http://css-tricks.com/css-style-guides/:
• Google HTML/CSS Style Guide
(http://google-styleguide.googlecode.com/svn/trunk/htmlcssguide.xml)
• WordPress CSS Coding Standards
(http://make.wordpress.org/core/handbook/coding-standards/css/)
• «Idiomatic CSS» by Nicolas Gallagher (https://github.com/necolas/idiomatic-css)
• …
Other examples
Strive to make everyone’s life easier.
probably copyright protected screenshot of “The Office”
© Unic - Seite 41
Agenda
• Writing maintainable and scalable
HTML / CSS
• Data mocking
• Unit testing
• Continuous integration
© Unic - Seite 42
• Mock a GET-Request
Data mocking
• Mock REST (i.e. with Backbone)
$.get('/js/data/data.json', function(data) {
alert('This was easy');
});
POST /collection
GET /collection[/id]
PUT /collection/id
DELETE /collection/id
© Unic - Seite 43
Click to edit Master title style How can we mock this data
© Unic - Seite 44
var oldBackboneSync = Backbone.sync;
Backbone.sync = function(method, model, options) {
…
if (method == "delete" || method == "update")
// handle id in URL
…
// is URL mocked?
if (urls[baseUrl])
…
// is method mocked?
…
return response[method];
else
oldBackboneSync(method, model, options);
}
Mock of REST requests
© Unic - Seite 45
BackboneMock = {
"/request_mocks/collection/": {
"read": function () {
return [{
"id": "1",
"title": "This was hard work!"
}]
},
"create": function () {
return {
"id": Math.floor(Math.random()*10000)
}
},
"delete": function () {
return {};
}
}
};
Mock of REST requests
© Unic - Seite 46
Agenda
• Writing maintainable and scalable
HTML / CSS
• Data mocking
• Unit testing
• Continuous integration
© Unic - Seite 47
Click to edit Master title style Who does write unit tests for
JavaScript
© Unic - Seite 48
• Tests should cover the most important pieces of code
• You should test the interface with the backend carefully
• You should not test styling or plugins
Unit testing
© Unic - Seite 49
Agenda
• Writing maintainable and scalable
HTML / CSS
• Data mocking
• Unit testing
• Continuous integration
© Unic - Seite 50
Click to edit Master title style Does anybody have a CI server for the
frontend
© Unic - Seite 51
Continuous Integration
HAML HTML
SCSS CSS
JS JS
layout, partials
@import "partials/base";
//= require 'plugins'
Middleman
© Unic - Seite 52
Continuous Integration
SVN
Check updates
Jenkins
Ruby server
Apache server
Source
Deploy
HTML
JS
CSS
© Unic - Seite 53
Release Management
JS
CSS
HTML
Mocks
Automated Release
Adaption in System
Automated Release
© Unic - Seite 54
Belpstrasse 48
3007 Bern
Tel +41 31 560 12 12
Fax +41 31 560 12 13
www.unic.com
Unic AG
© Unic - Seite 55
Senior Frontend Engineer
Senior Frontend Engineer
Rosmarie Wysseier
Thomas Jaggi