Slide 1

Slide 1 text

Ember CLI Addons

Slide 2

Slide 2 text

Who the heck is this guy? ● DockYarder ● Ember Core Team ● General Open Source Addict twitter: rwjblue github: rwjblue

Slide 3

Slide 3 text

Thank You!!

Slide 4

Slide 4 text

What is Ember CLI?

Slide 5

Slide 5 text

What is Ember CLI? ● Convention over Configuration ● ES6 Modules ● Blueprints/Generators ● Test Harness ● A Metric Crap-tonne more.

Slide 6

Slide 6 text

CLI == Command Line (duh) ember build ember generate ember new ember serve ember test

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Creating a Project npm install -g ember-cli ember new my-project cd my-project

Slide 9

Slide 9 text

Creating a Project % tree app -d app ├── components ├── controllers ├── helpers ├── models ├── routes ├── styles ├── templates │ └── components └── views

Slide 10

Slide 10 text

Creating a Project % tree tests -d tests ├── helpers └── unit

Slide 11

Slide 11 text

Creating a Project % ember server version: 0.0.46 Livereload server on port 35729 Serving on http://0.0.0.0:4200 Build successful - 444ms.

Slide 12

Slide 12 text

Generators % ember generate component async-select version: 0.0.46 installing create app/components/async-select.js create app/templates/components/async-select.hbs create tests/unit/components/async-select-test.js

Slide 13

Slide 13 text

Generators % cat app/components/async-select.js import Ember from 'ember'; export default Ember.Component.extend({ });

Slide 14

Slide 14 text

Generators import { test, moduleForComponent } from 'ember-qunit'; moduleForComponent('async-select'); test('it renders', function() { var component = this.subject(); equal(component.state, 'preRender'); this.append(); equal(component.state, 'inDOM'); });

Slide 15

Slide 15 text

Test Harness % ember test

Slide 16

Slide 16 text

Addons?

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Addons - What can they do? ● Pieces to a consuming application (Routes, Controllers, Views, Components, etc) ● Development Server Middlewares ● Blueprints (aka generators) ● Configuration ● Commands

Slide 19

Slide 19 text

Addons - What can they do? ● Modify Built Assets ● Update build output. ● Preprocessors

Slide 20

Slide 20 text

What “hooks” are there?

Slide 21

Slide 21 text

Addon Infrastructure Hooks ● constructor & init ● config ● blueprintsPath ● includedCommands ● serverMiddleware ● postBuild

Slide 22

Slide 22 text

Addon Build Hooks ● treeFor ● included ● postprocessTree

Slide 23

Slide 23 text

constructor & init ● Constructor is called with the current project as an argument. ● init is called just after the constructor ● Default is to store `this.project`

Slide 24

Slide 24 text

config ● Receives: ○ Currently building environment ○ Initial Application config ● Can augment application config ● Return an object to be merged with app ● Defaults to using `config/environment.js`

Slide 25

Slide 25 text

config

Slide 26

Slide 26 text

blueprintsPath ● No arguments ● Return the path for blueprints ● Defaults to `blueprints/` (if present)

Slide 27

Slide 27 text

blueprintsPath

Slide 28

Slide 28 text

includedCommands ● No arguments ● Return an object ○ key - command name ○ value - command instance or create options ● No default implementation.

Slide 29

Slide 29 text

includedCommands

Slide 30

Slide 30 text

serverMiddleware ● Receives an “options” argument: ○ app -- express instance ○ options ■ project ■ watcher ■ environment ● No default implementation.

Slide 31

Slide 31 text

serverMiddleware

Slide 32

Slide 32 text

serverMiddleware

Slide 33

Slide 33 text

postBuild ● Receives the `result` object from build: ○ directory -- path to build output ● No default implementation

Slide 34

Slide 34 text

included ● Called when the addon is included in a build ● Receives the `EmberApp` instance as an arg ● Generally used to call `app.import`

Slide 35

Slide 35 text

included

Slide 36

Slide 36 text

treeFor

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

● Returns a given type of tree (if present) ● Merged with application tree of same type ● Delegates to methods based on tree type ● Returns default tree (based on type) if present treeFor

Slide 39

Slide 39 text

treeFor ● Uses `addon.treePaths` object to determine paths on disk (relative to addon dir) for each tree type ● Uses `addon.treeForMethods` object to determine which internal methods to call for a given type

Slide 40

Slide 40 text

treeFor ● app ● styles ● templates ● addon ● vendor ● test-support ● public

Slide 41

Slide 41 text

treeForApp ● Receives tree at `treePaths[‘app’]` (defaults to addons `app/` directory) ● Return value is merged with the application’s app tree.

Slide 42

Slide 42 text

treeForStyles ● Receives tree at `treePaths[‘styles’]` (defaults to addons `app/styles/` directory) ● Return value is merged with the application’s styles tree (also `app/styles/`)

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

treeForTemplates ● Receives tree at `treePaths[‘templates’]` (defaults to addons `app/templates/` directory) ● Return value is merged with the application’s templates tree (also `app/templates/`)

Slide 45

Slide 45 text

treeForAddon ● Receives tree at `treePaths[‘addon’]` (defaults to addons `addon/` directory) ● Returned tree is build into a standalone package under the addon’s namespace. ○ ES6 -> `vendor.js` ○ Styles -> `vendor.css` ○ Templates -> `vendor.js` ○ JSHint (when developing addon)

Slide 46

Slide 46 text

treeForVendor ● Receives tree at `treePaths[‘vendor’]` (defaults to addons `vendor/` directory) ● Return value is merged with the application’s vendor tree (defaults to `vendor/`)

Slide 47

Slide 47 text

treeForTestSupport ● Receives tree at `treePaths[‘test-support’]` (defaults to addons `test-support/` directory) ● Return value is merged with the application’s test tree (generally in `test/`)

Slide 48

Slide 48 text

treeForPublic ● Receives tree at `treePaths[‘public’]` (defaults to addons `public/` directory) ● Return value is merged with the application’s public tree. ● Default is to make addons `public/` nested under addon name in final `dist/`

Slide 49

Slide 49 text

postprocessTree ● Receives 2 arguments: ○ Type of post processing (currently only all) ○ Receives tree after build ● Output of processing all addons is returned from `app.toTree()`

Slide 50

Slide 50 text

Basic Guidelines ● Keep all code in `addon/` ● import and re-export in `app/` if needed (mostly for components and templates) ● Allows extension of your addon ● Allows easier unit testing

Slide 51

Slide 51 text

Discovery

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Discovery ● Search project dependencies ○ Look for `ember-addon` in keywords ● Search `package.json`’s `ember-addon` key for `paths`

Slide 54

Slide 54 text

Discovery - App

Slide 55

Slide 55 text

Discovery - Addon

Slide 56

Slide 56 text

Creating an Addon

Slide 57

Slide 57 text

Creating From outside of a project to create a new standalone addon: `ember addon my-foo` From within an existing project to create an in-repo addon: `ember generate in-repo-addon my-foo`

Slide 58

Slide 58 text

Creating - External

Slide 59

Slide 59 text

Creating - In Repo

Slide 60

Slide 60 text

Creating - Minimal Addon

Slide 61

Slide 61 text

Testing an Addon

Slide 62

Slide 62 text

Testing ● Default generator creates a test app ● Unit tests ● Integration tests (against test/dummy app)

Slide 63

Slide 63 text

Testing - Unit

Slide 64

Slide 64 text

Testing - Acceptance

Slide 65

Slide 65 text

Testing - Acceptance

Slide 66

Slide 66 text

Dependencies

Slide 67

Slide 67 text

Dependencies SHOOT ME NOW!!!

Slide 68

Slide 68 text

Dependencies ● NPM Package for “node-land” tooling ● Bower Package for “browser-land” tooling ● `bower.json` as a way for apps to override ● Blueprint for addon name, for installing bower packages needed

Slide 69

Slide 69 text

Dependencies

Slide 70

Slide 70 text

Dependencies

Slide 71

Slide 71 text

Lets see it!

Slide 72

Slide 72 text

The End