• Stars
    star
    294
  • Rank 141,303 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 11 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A boilerplate for Backbone projects that share code server/client, render server/client, and scale through modular architecture.

Ezel

image

A boilerplate for Backbone projects that share code server/client, render server/client, and scale through modular architecture. Used at Artsy to bootstrap new projects, see our blog post on it.

Introduction

Ezel makes it easy to write and maintain Backbone apps that run in the browser and on the server using Node.js. Built on popular libraries like Express, Backbone, and Browserify, Ezel isn't a framework or library of its own, but rather a boilerplate of libraries and patterns that can be leveraged or abandoned as needed.

Ezel has three main philosophies...

Modularity

Instead of managing growing complexity in projects by imposing rigid monolithic structure, Ezel encourages breaking your project up into smaller pieces that are easy to maintain and refactor independently.

Flexiblity

Don't get locked into choosing between single page app or fully server-side rendered pages. Ezel's modular structure and shared server/client code makes it easy to decide what patterns and tools are best on a case by case basis.

Run on Both Sides

Ezel shares javascript modules that run in the browser and on the server. This means you can optimize initial page load and SEO by sharing templates that can render on the server or client. This also makes it easy to test all of your code in Node.js using benv and zombie for robust, fast, and easy to set up tests.

Getting Started

Installation

  1. Install Node.js
  2. Install the Ezel project generator globally npm install -g ezel
  3. Generate your project ezel myapp (Use ezel --coffeescript myapp for coffeescript) and cd to the directory.
  4. Install node modules npm install
  5. Run the server make s
  6. Visit localhost:4000 and see an example that uses the GitHub API.

Overview

First it would be good to familiarize yourself with the tools Ezel is built on.

At its heart Ezel is just a Backbone app and therefore relies on an external API as its data source. This can come in a variety of forms and it's up to you to choose the best technology to serve your data over HTTP.

Once you understand how the above tools work, diving into Ezel is just a matter of understanding its patterns. After this, when you're ready, you can generate a new clean project without the Github example code by using ezel --clean.

Project vs. Apps vs. Components

Monolithic frameworks tend to organize your code by type such as /views, /stylesheets, /javascripts, etc. As your app grows larger this becomes an awkward and unmaintainable way to delineate parts of your project. Ezel encourages grouping files into conceptual pieces instead of by type.

There are three different levels of this organization:

Project

Refers to the root, "global", level and contains the initial setup/server code and project-wide modules such as models, collections, and libraries. Setup code is extracted into /lib/setup to encourage modularizing and testing your setup code.

Apps

Apps are small express applications that are mounted into the main project. What distinguishes apps from one another is that they conceptually deal with a certain section of your website, and are often separated by a full page-refresh. As such an app could be a complex thick-client "search" app, or a simple static "about" page.

Apps should strive to be self-contained and shouldn't require into other apps. However, apps will often need project-level modules so requiring into components, models, collections and libraries are fine. It's encouraged to namespace your CSS classes inside an app by the app name to avoid conflicts, e.g. apps/user may use h1.user-header. It's also encouraged to use app-level public folders for static assets and namespace your filenames by app name e.g. /apps/user/public/images/user-icon.png which can be referenced normally in templates and stylesheets e.g. /images/user-icon.png.

The organization of these apps are up to you, for a simple app you may put all of your code into one express instance exported in a single index.js file. More complex apps may have their own /routes, /stylesheets, etc. folders or even look like its own Ezel project with components and sub-apps.

Large web projects often have a wide range of needs on a case by case basis. Instead of trying to solve every problem with the same architecture, Ezel remains flexible and modular so you can pick the right tools and patterns for the job.

Components

Components are portions of UI re-used across apps and are simply a folder containing a mix of stylesheets, templates, and client-side code that can be required piece-meal. These can be thought of like a jQuery UI widget, Bootstrap component, Backbone view, or component.js component. Components can be as simple a stylesheet and template, more complex like an autocomplete widget, or even a massive modal window pieced together from smaller components.

Components should strive to be a library of self-contained UI and therefore shouldn't require into apps, however, it's totally fine to require into /lib or other components. It's encouraged to namespace your CSS classes in a component by the component name to avoid conflicts, e.g. components/autocomplete may use li.autocomplete-list-item. It's also encouraged to use component-level public folders for static assets and namespace your filenames by component name e.g. /components/autocomplete/public/images/autocomplete-icon.png which can be referenced normally in templates and stylesheets e.g. /images/autocomplete-icon.png.

Models & Collections

Model code is meant to work on the server and client so it must strictly be domain logic around your data. Model code can't use APIs only available to the browser or node such as accessing the file system or the XMLHttpRequest object.

Backbone.sync is used as a layer over HTTP accessible on both sides. Any HTTP requests made in model and collection code therefore must be wrapped in a Backbone class or used by an anonymous instance e.g. new Backbone.Model().fetch({ url: '/api/system/up', success: //... }).

Libraries

Libraries are a place to store modules that are used across apps and don't pertain to domain logic or UI that can be better handled by models or components. These can be server only such as a library zipping uploaded files, browser-only such as an HTML5 Canvas library, or even shared such as a date parsing library that can be used on both the server and client.

Testing

Tests are broken up into project-level, app-level, and component-level tests that are run together in make test. This boilerplate comes stocked with a suite of tests for the Github API example, so please take a look around for examples.

Project-level Tests

Project-level tests involve any library, model, or collection tests. Because Ezel model code can run on the server you can easily test it in node without any extra ceremony and testing these parts should be straight-forward. In the case that you need to test model or collection fetching/persisting it's encouraged to stub Backbone.sync.

Component-level Tests

Components should have tests inside their own /test folders to try to be self-contained. Because components contain view code meant to run in a browser you can use benv to set up a fake browser environment and require these modules for unit testing like any other module.

App-level Tests

App-level tests can come in a number of different forms, but often involve some combination of route, template, client-side, and integration tests. Like components, apps should have their own tests under /test folders. Given that apps can vary in complexity and number of components they use, it's up to you to decide how to structure and test their parts.

Some common practices are to split up your route handlers into libraries of functions that pass in stubbed request and response objects. Templates can be directly compiled with jade and asserted against the generated html. Client-side code can be unit tested in node using benv (Backbone views can help wrap code into testable methods). Finally a suite of integration tests use Zombie and boot up a version of the project with a fake API server found under /test/helpers/integration.

All of these techniques ensure your code remains decoupled, your tests run fast, and you stay happy and productive.

Build Scripts & Configuration

Ezel uses simple configuration and build tools that are standard with most environments.

A Makefile designates build commands. When more complex build scripts are needed it's encouraged to wrap them in libraries that can be run via node lib/script.js.

Configuration is handled entirely by environment variables. For ease of setup there is a .env file that declares sensible defaults for development. For non-sensitive config data like NODE_ENV it's encouraged to use sharify (e.g. var sd = require('sharify').data; console.log(sd.NODE_ENV)) which you can add to in lib/setup. For sensitive data on the server simply use process.env. Be careful not to add sensitive data to sharify as it will expose it on the client.

Asset Pipeline

Ezel's asset building is mostly handled by Browserify and Stylus with middleware for development and a make assets task to output more production ready files to public/assets. Place your asset packages in /assets, point your script and style tags to /assets/ in your views, and Ezel will wire the rest up for you.

Ezel's focus on modularity makes it easy to build up light-weight asset packages that are focused for your needs. This combined with rendering on the server makes it a great option for optimizing initial page load.

A common pattern would be to build asset packages per-app. For instance you may have a "search" app that uses assets from a layout component, an autocomplete component, and the search app's own client-side code and stylesheets. In this case you would create an /assets/search.styl that imports stylesheets from components/layout, components/autocomplete and app/search/stylesheets, and ditto for javascripts. In the view of the search app you would include script( src='/assets/search.js' ) and link( href='/assets/search.css' ) and Ezel will wire up the rest.

More Repositories

1

eigen

The Art World in Your Pocket or Your Trendy Tech Company's Tote, Artsy's mobile app.
TypeScript
3,480
star
2

eidolon

The Artsy Auction Kiosk App.
Swift
2,711
star
3

fresnel

An SSR compatible approach to CSS media query based responsive layouts for React.
TypeScript
1,098
star
4

README

👋 - The documentation for being an Artsy Engineer
TypeScript
1,044
star
5

artsy.github.io

The Artsy Engineering Open-Source Developers Blog
SCSS
1,015
star
6

emission

⚠️ Deprecated repo, moved to artsy/eigen ➡️ React Native Components
TypeScript
621
star
7

force

The Artsy.net website
TypeScript
550
star
8

metaphysics

Artsy's GraphQL API
TypeScript
355
star
9

reaction

Artsy's publishing components
TypeScript
355
star
10

Emergence

TV. Shows.
Swift
353
star
11

garner

A set of Rack middleware and cache helpers that implement various caching strategies.
Ruby
347
star
12

scroll-frame

Retain your scroll position between pages using an iframe. Especially helpful for infinite scrolling views.
JavaScript
312
star
13

Swift-at-Artsy

Repo for the notes for Swift at Artsy
Swift
284
star
14

energy-legacy

LEGACY - Artsy Folio, The Partner iPhone / iPad app.
Objective-C
209
star
15

palette

Artsy's design system
TypeScript
203
star
16

react-redux-controller

Library for creating a controller layer to link React and Redux, on top of react-redux.
JavaScript
97
star
17

hokusai

Artsy's Docker / Kubernetes CLI and Workflow
Python
87
star
18

positron

Positron is Artsy Writer or the editorial tool and API for Artsy.
TypeScript
85
star
19

day-schedule-selector

A jQuery plugin to render a weekly schedule and allow selecting time slots in each day.
JavaScript
85
star
20

mobile

Mobile Team TODO
84
star
21

benv

Stub a browser environment in node.js and headlessly test your client-side code.
JavaScript
72
star
22

flare

Artsy iPhone Launch Marketing Page
CoffeeScript
63
star
23

team-navigator

An internal HR product for Artsy's team
JavaScript
62
star
24

sharify

Easily share data between Browserify modules meant to run on the server and client.
JavaScript
61
star
25

x-react-native

Conference Details for Artsy x React Native
TypeScript
49
star
26

backbone-super-sync

Isomorphic Backbone.sync adapter using superagent.
JavaScript
47
star
27

jenkins-backup-s3

A collection of scripts to backup Jenkins configuration to S3, as well as manage and restore those backups
Python
46
star
28

graphql-slack-updater

A weekly Travis task that sends our GraphQL updates to Slack
Ruby
40
star
29

meta

Artsy on Artsy.
39
star
30

Specs

The Artsy CocoaPods Specs
Ruby
37
star
31

doppler

Artsy.net developer website.
Ruby
37
star
32

detect-responsive-traits

Determine responsive traits to only server-side render markup truly needed.
TypeScript
36
star
33

gris

Gris is a framework for building hypermedia API services using Grape, Roar and ActiveRecord
Ruby
35
star
34

artsy-2013

The 2013.artsy.net static site using Node.js for some preprocessors.
CoffeeScript
33
star
35

the-art-genome-project

Gene names and definitions
JavaScript
33
star
36

elderfield

The Artsy Alexa (Echo) skill.
JavaScript
33
star
37

peril-settings

Artsy's peril settings
TypeScript
30
star
38

2014.artsy.net

CoffeeScript
25
star
39

artsy-ruby-client

Artsy API Ruby Client
Ruby
25
star
40

express-reloadable

Automatically hot-swap Express server code without the restart
JavaScript
25
star
41

Artsy-Authentication

Cocoa libraries dealing with Authentication for Artsy. Yawn, boring
Objective-C
22
star
42

dupe-report

A tool for reporting new webpack bundle duplicates to github and slack
TypeScript
21
star
43

Artsy-UILabels

This is our Artsy styled UILabel subclasses.
Objective-C
20
star
44

Artsy-OSSUIFonts

Open source variants of the Artsy fonts, wrapped as a CocoaPod
Beef
18
star
45

Mitosis

Artsy Chat Bot for Facebook Messenger
JavaScript
17
star
46

atomic-store

Atomic event store for Scala/Akka
Scala
17
star
47

momentum

Shared utilities for managing and deploying OpsWorks apps at Artsy. [DEPRECATED]
Ruby
15
star
48

orbs

CircleCI orbs used at Artsy
Shell
15
star
49

lint-changed

Lint files that have changed since master
TypeScript
14
star
50

artsy-eigen-web-association

A tiny app that serves the apple-app-site-association required for iOS Handoff related features.
JavaScript
14
star
51

javascriptures

Demo projects for javascripture sessions
JavaScript
14
star
52

estella

Make your Ruby objects searchable with Elasticsearch.
Ruby
13
star
53

echo

Eigen's floating administration lab up in the clouds
Shell
13
star
54

graphql-workshop

A workshop for understanding GraphQL by exploring Metaphysics
13
star
55

Artsy-UIColors

Consolidated UIColors used in the Artsy iOS Apps
Ruby
12
star
56

emission-nebula

Handles weekly deploys of Emission to TestFlight
Ruby
12
star
57

cohesion

Artsy's analytics schema
TypeScript
12
star
58

yeoman-generator-artsy

A Yeoman generate for Artsy CLI apps
JavaScript
11
star
59

stitch

Helps your Component and Template dependencies peacefully coexist
JavaScript
11
star
60

renovate-config

Shared renovate configurations
JavaScript
11
star
61

vscode-artsy

A VS Code extension for the Artsy Tech Stacks
11
star
62

money_helper

A simple module to assist in formatting unambiguous prices and price ranges in international currencies
Ruby
11
star
63

artsy-passport

Wires up the common auth handlers for Artsy's node based apps using http://passportjs.org.
JavaScript
10
star
64

aprb

[Deprecated] Artsy public radio notifications in Slack.
Elixir
10
star
65

next

Tools an utilites for Next.js by Artsy
JavaScript
10
star
66

eigen-artefacts

CocoaPods dependencies used in Eigen.
C++
10
star
67

Artsy-UIButtons

Artsy's UIButton subclasses
Objective-C
10
star
68

codemods

Various codemods used around Artsy
TypeScript
10
star
69

relay-workshop

Home for Artsy's Relay peer learning tutorials
TypeScript
9
star
70

studio

TypeScript
9
star
71

palette-zeplin-extension

See Artsy's palette components inside Zeplin directly
JavaScript
9
star
72

artsy.github.io-gatsby

re-write Engineering Blog
TypeScript
8
star
73

biesenbach

The Artsy Google Home application.
JavaScript
8
star
74

microgravity-deprecated

The Artsy.net mobile website:
CoffeeScript
8
star
75

palette-mobile

Artsy's Design System on Mobile
TypeScript
8
star
76

Aerodramus

An Objective-C API for interacting with artsy/echo
Objective-C
8
star
77

aprd

Artsy's Real-time Slack Notification Service (aka Artsy Public Radio)
Elixir
8
star
78

artsy-backbone-mixins

A library of Backbone mixins that DRY up some common domain logic and Artsy API rabbit holes.
JavaScript
8
star
79

energy

Artsy Folio, The Partner iPhone / iPad app.
TypeScript
7
star
80

backbone-cache-sync

Server-side Backbone.sync adapter that caches requests using Redis.
JavaScript
7
star
81

kaws

API for collections, our SEO optimized marketing landing pages
TypeScript
7
star
82

horizon

Visual representations of release pipelines
Ruby
7
star
83

guides

The Engineers Guide to the Artsy Universe
7
star
84

hack-playdate-gallery

Lua
7
star
85

forque

A home for modern admin UIs; successor to Torque
TypeScript
7
star
86

APR

Artsy Private Radio
Elixir
7
star
87

browserify-dev-middleware

Middleware to compile browserify files on request for development purpose.
JavaScript
7
star
88

artsy-xapp

Tiny lib to fetch and refresh an xapp token from Artsy
JavaScript
7
star
89

auto-config

Artsy's shared auto release config
6
star
90

volley

Datadog StatsD ingestion for client-side data
TypeScript
6
star
91

rosalind

Admin app for batch operations on genomes
JavaScript
6
star
92

bucket-assets

Uploads a folder of static assets to an s3 bucket with convenient defaults.
JavaScript
6
star
93

extraction

UI components shared between Eigen and Emission.
Objective-C
6
star
94

to-title-case

Capitalizes your titles as per The Chicago Manual of Style
TypeScript
6
star
95

miasma

Smoke tests for Artsy, and possible successor to Vapor
JavaScript
6
star
96

update-repo

JS library for updating other repositories
TypeScript
6
star
97

cli

TypeScript
6
star
98

convection

Rails application for consignments
Ruby
5
star
99

performance-monitor

TypeScript
5
star
100

graphql-page_cursors

Add page cursors to your Rails GQL schema
Ruby
5
star