By Ryan LaBouve / @ryanlabouve
The LaBouves
The Problem: Many Ember apps under one brand
The Solution: A UI library via an Addon
To fill in the back story, when I started there was on white-labeled ionic app & a rails api, and we needed a dashboard
Developed ember dash
Next we built the main website in Ember as well
Next we built a tool for clients to customize their apps
And more apps just keeping coming, all while our brand is constantly evolving.
"Addons make it possible to easily share common code between applications"
— The Ember-CLI Docs
Demystifying the Process
What lured me in..
We need more than an input box, we need a color picker.
—MGMT
{{! app/application.hbs }}
Hex Color: {{input value=brandColor}}
step 1
step 1
step 2
cd ~/Desktop/myProject
ember install ember-spectrum-color-picker
step 2
// app/templates/application.hbs
Hex Color: {{spectrum-color-picker
color=brandColor
preferredFormat="hex"}}
{{brandColor}}
Color should update as user drags picker
—MGMT
Welp...
RTFM'ing
github.com/rsschermer/ember-spectrum-color-pickermoveFiresChange (default: false): when set to true, the color value will be updated in real time, instead of only once the user clicks the 'choose' button.
...easy enough
Note for future self:
Good documentation is not a waste of time
Hex Color: {{spectrum-color-picker
color=brandColor
preferredFormat="hex"
moveFiresChange=true}}
(no more cats, I promise)
How hard could it be?
An addon that simply makes things spin
ember addon spin-spin
ember g component spin-spin --pod
// will need since our UI still will live in templates
npm install --save ember-cli-htmlbars
{{yield}}
{{! /tests/dummy/app/templates/application.hbs}}
{{#spin-spin}}
Welcome to Ember
{{/spin-spin}}
Inside of the share-share folder
npm version 0.0.1
npm publish
cd ~/work/www
ember install spin-spin
...meanwhile in the www's application.hbs
{{#spin-spin}}
... whole contents of application.hbs
{{/spin-spin}}
Back in the addon we change animation-duration: 40000ms;
and commit.
npm version 0.0.2
npm publish
Next, let's go back into the project and run npm outdated
.
Updated packages.json to be version 0.0.2
and npm install
Last, if I had to publish every change I wanted to see live... that would be terrible
# inside of spin spin
npm link
cd ~/work/www
# inside of website
npm link spin-spin
ember serve
Now we are running directly form our addon.
Even better, we can get live reload to work.
~/spin-spin/index.js
/* jshint node: true */
'use strict';
module.exports = {
name: 'spin-spin',
isDevelopingAddon: function() {
return true;
}
};
First class live reload support.
So that is the basic plumbing we'll use to refactor our UI, let's move on to some specific examples and techniques
Hands Dirty
Candidates for Refactor
Candidates for Refactor
Ripe for refactor
ember new testAppA && ember new testAppB
cd testAppA
npm install --save-dev ember-cli-sass
mv app/styles/app.css app/styles/app.scss
bower install bootstrap-sass --save
echo "@import 'bower_components/bootstrap-sass/assets/stylesheets/_bootstrap';" >> app/styles/app.scss
(do same thing for app b)
Blank
Bootstrap
Grab some sample code from http://getbootstrap.com/getting-started/#examples
Project A
Project B
Customize Variables on easy side.
Updating Bootstrap Theme
With theme applied
// testAppA:
// app/styles/app.scss
@import "variables";
@import "theme";
@import 'bower_components/bootstrap-sass/assets/stylesheets/_bootstrap';
Instead of copying and pasting for every single theme change we make, let's roll this up into an addon.
Test App A
Test App B
ember addon egm-uilib
npm install --save ember-cli-htmlbars
bower install bootstrap-sass --save
npm install ember-cli-sass --save
# ... just like before
Just Checking
// in addon/styles/base.scss
body {
background: #bada55 !important;
}
// in consumer
// @import "variables";
// @import "theme";
// @import 'bower_components/bootstrap-sass/assets/stylesheets/_bootstrap';
@import "node_modules/egm-uilib/addon/styles/base";
@import "variables";
@import "theme";
@import 'bower_components/bootstrap-sass/assets/stylesheets/_bootstrap';
// In consumer
@import "node_modules/egm-uilib/addon/styles/base";
Link TestAppB and Import the 1 SASS file, and now A & B are powered by the same base!
Cyborg
Darkly
Flatly
United
Candidates for Refactor
Ripe for refactor
Here's our sample logos
And in reality there are likely tones of slight variations in quality, size, format, etc floating around
The addon project created follows these structure conventions:
app/ - | merged with the application's namespace. |
addon/ - | part of the addon’s namespace. |
blueprints/ - | contains any blueprints that come with the addon, each in a separate directory |
public/ - | static files which will be available in the application as /your-addon/* |
test-support/ - | merged with the application's tests/ |
tests/ - | test infrastructure including a "dummy" app and acceptance test helpers. |
vendor/ - | vendor specific files, such as stylesheets, fonts, external libs etc. |
ember-cli-build.js - | Compilation configuration |
package.json - | Node meta-data, dependencies etc. |
index.js - | main Node entry point (as per npm conventions) |
The addon project created follows these structure conventions:
app/ - | merged with the application’s namespace. |
addon/ - | part of the addon’s namespace. |
blueprints/ - | contains any blueprints that come with the addon, each in a separate directory |
public/ - | static files which will be available in the application as /your-addon/* |
test-support/ - | merged with the application’s tests/ |
tests/ - | test infrastructure including a “dummy” app and acceptance test helpers. |
vendor/ - | vendor specific files, such as stylesheets, fonts, external libs etc. |
ember-cli-build.js - | Compilation configuration |
package.json - | Node meta-data, dependencies etc. |
index.js - | main Node entry point (as per npm conventions) |
Lessons Learned
Stoke collaboration and embracing a mature software development cycle
npm link
and run tests while developing where possibleDummy App
into living documentationThe Journey is as useful as the destination
On the surface
Clear paths on fixing our original problems
On a deeper note, this was really my first deep dive into the ember ecosystem...
Go build addons
UI is a great place to start
Refactoring Shared UI into an Addon, the end
By Ryan LaBouve / @ryanlabouve