- \n
- September 16th, 2019 \n
- Master of Ceremonies: Trek Glowacki (GitHub) \n
- \n
- Speaker: Marie Chatfield (GitHub) \n
- Slides \n
- Blog \n
The humble <div>
is a powerful and flexible element. Throw enough CSS and JavaScript on it, and a can be anything.\nBut should it be? “Semantic HTML” is a method of using elements that best match what your content means and does.\nBut how do you write better markup if you don’t know your options? Join the learning journey to fill your semantic HTML toolkit with the coolest elements you never knew existed. Learn specific elements to use in different scenarios and how to wield the full power of the HTML spec. You’ll write less code while making your pages more accessible and mobile-friendly!
Marie writes code and poetry, sometimes at the same time. As a front-end engineering enthusiast, she’s currently helping the fine folks at Pingboard build the world’s best org chart software. She is passionate about creating inclusive experiences and understanding foundational web technologies at a deeper level. Talk to her about rock climbing or Texas!
\n\n- \n
- Semantic HTML: Choosing elements based on their meaning \n
- Non-Semantic HTML: Choosing elements based on browser styles and/or using
<div>
for everything \n - Keeps readable layout even if styles are missing or JavaScript is disabled \n
- Page is still functional (e.g. forms can submit) \n
- Improves accessibility \n
- More context with less code \n
- Why Not Semantic HTML?\n
- \n
- Element not supported across browsers \n
- Specific UX/UI needs \n
- You are willing to implement, test, and ensure accessibility of custom alternative\n
- \n
- Does a library already exist, can I contribute? \n
- Accessible? \n
- Browser compatibility? \n
- Mobile devices? \n
- How hard is it to test & maintain? \n
\n
\n
- \n
<main>
\n<article>
\n<section>
\n<aside>
\n<nav>
\n<header>
\n<footer>
\n<forms>
\n<fieldset>
\n<legend>
\n<input>
\n- \n
- Supports many different types - \n
- Basic: checkbox, number, radio, range, text \n
- Formatted: email, tel, url \n
- Date/Time: date, datetime-local, month, time, week \n
- Form Controls: button, hidden, image, reset, submit \n
- Special: color, file, password, search \n
\n<select>
\n<option>
\n<optgroup>
\n<output>
\n- \n
- Unsupported by IE (won't break the site, just won't give you aria stuff) \n
\n<figure>
\n<figcaption>
\n<video>
\n- \n
- Format support varies by browser \n
\n<track>
\n- \n
- enables captions within
<video>
\n
\n- enables captions within
<audio>
\n- \n
- Most browsers don't support
<track>
inside this element, but if you put<audio>
inside<video>
, it can work \n
\n- Most browsers don't support
- Text Formatting\n
- \n
<pre>
\n<code>
\n- \n
- Executable code \n
\n<samp>
\n- \n
- Terminal output \n
\n<kbd>
\n- \n
- Keyboard imput \n
\n<var>
\n<q>
\n- \n
- Most browsers will add the quotation marks \n
\n<blockquote>
\n- \n
- Indented section \n
\n<cite>
\n- \n
- Italicizes its content \n
\n<abbr>
\n<dfn>
\n<address>
\n<time>
\n
\n
- \n
- Speaker: Sean Devine (GitHub) \n
Sean Devine is the proud father of 5 children, a lucky husband to his amazing wife Theresa, an active Ember/JavaScript (and Rails/Ruby) developer, and the Founder and CEO of XBE - a Construction Logistics business based in Chicago, IL. He is thankful every day that he bet his company on Ember, and is more excited than ever about where things headed. When not working, or parenting, or programming, Sean enjoys running, cycling, and the NBA.
\n\n\n\n\"Unless you have a large and sustainable development budget and are competing in a market where the user is the buyer and there is significant competition with feature parity, a hybrid mobile-first app is almost certainly your best option.\"
\n
Conclusion: Almost everyone should be using EmberJS and Corber!
\nHow did XBE decide on their tech stack?
\n- \n
- Situation\n
- \n
- People often have opinions about tech stacks without knowing any context the app will be built in \n
- Diverse User Base \n
- Broad & Deep Functionality \n
- Bootstrapped, Small Team \n
- Location-Centric Requirements \n
- User/Buyer Dichotomy \n
- Compulsory Usage \n
\n - Objective\n
- \n
- Maximize: Leverage \n
- Constraint: Location Tracking Requirement \n
- Constraint: Bootstrapped Budget \n
\n - Options\n
- \n
- Mobile-first web app with native tracking apps\n
- \n
- Viable \n
\n - Hybrid mobile-first app\n
- \n
- Viable \n
\n - Multiple \"native\" apps with feature parity\n
- \n
- Shockingly, this is the default choice of most companies\n
- \n
- Featuresets almost never stay in sync across platforms \n
\n - Non-viable: Too expensive\n
- \n
- Larger/venture-backed companies can trick themselves into thinking this option is best b/c cost isn't a constraint \n
\n
\n - Shockingly, this is the default choice of most companies\n
- Mobile web only\n
- \n
- Non-viable: Inadequate location tracking \n
\n
\n - Mobile-first web app with native tracking apps\n
- Decision\n
- \n
- Mobile-first \n
- Web-first \n
- Responsible design \n
- Distributed as a native app \n
\n - Development\n
- \n
- Build an app that \"feels\" right on a phone is the biggest challenge \n
- Corber config and build process feels opaque and magical \n
- Native app release process is cumbersome and manual \n
- If you build a solid mobile-first web app with Ember, the native apps come for free \n
\n - Outcome\n
- \n
- Maximized leverage \n
- Differentiated functionality \n
- On budget, low risk \n
- Significant option value \n
\n - Implications\n
- \n
- Know your situation and objective \n
- Accept your constraints \n
- Understand options in terms of your context \n
\n - Maturity: Accepting What Is True And Acting Accordingly \n
Note: This talk had lots of fun asphalt-related trivia not captured here.
\n\n- \n
- Speaker: Dan Gebhardt (GitHub) \n
- Slides \n
- Resources \n
Web workers bring a new layer of capabilities to web applications. Because workers operate on their own threads, they provide a way to perform processor-intensive tasks without affecting the responsiveness of an application. This talk will explore the different types of workers, including service workers and shared workers, and how to make the most of them in your Ember applications. We'll discuss the capabilities available to workers and explore different use cases, including progressive web apps.
\n\nDan is on the Ember.js core team, an editor of the JSON:API spec, and the creator of Orbit.js. He consults through Cerebris, the company he co-founded, and their partner Tilde. He loves to travel and hike with his family and fluffy dog.
\n\n\"This really is a talk about the power of organized labor\"
\n- \n
- Web Workers\n
- \n
- Dedicated \n
- Shared \n
- Service \n
\n - Main Thread: All processing done on the web happens here by default \n
- Workers are the only threading primitive on the web\n
- \n
- Offload processing work to workers so that it can occur in parallel \n
\n - \"Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.\" - Rob Pike (Go Creator) \n
- What happens when we exceed the limits of concurrency on the main thread? Jank.\n
- \n
- Things seem off when apps drop below 60 fps, meaning browsers need to repaint every 15 ms \n
\n - Perceived challenges to using workers\n
- \n
- New and unproven? No, they've been around since 2012 \n
- Lack of browser support? No, widely supported by browsers \n
- Lack of capabilities? No, give access to nearly every browser API \n
\n - Real challenges to using workers\n
- \n
- Awkward to use \n
- Awkward to test \n
- Lack of FE framework support \n
- All challenges are developer experience problems \n
\n - Characteristics of all workers\n
- \n
- Async communication \n
- No shared memory \n
- Controlled lifetime \n
- Access to browsers APIs \n
- No direct access to DOM \n
\n - Dedicated Workers\n
- \n
- Global browser support: High 90s percentile, even IE/Edge \n
- Supports ES modules \n
- Demo: Calculate fibonacci sequence of numbers in worker so that UI is not blocked \n
\n - Shared Workers\n
- \n
- ~36% global browser availability: Not yet supported in safari/edge/IE \n
- MessagePort \n
- Same demo, running in multiple browser windows\n
- \n
- Data synced across window via the shared worker \n
- Each window has its own store, but they're communicating via shared memory of the worker \n
- Built with OrbitJS & EmberJS \n
\n
\n - Service Workers\n
- \n
- Popular for building complete offline experiences \n
- Global browser support: High 90s percentile, no IE support \n
- Progressive Web App (PWA) Checklist\n
- \n
- Site is served over HTTPs \n
- Responsive \n
- App URL's load while offline \n
- Add to home screen \n
- Fast first load (because some assets are cached) \n
- And more ... \n
\n - Can even customize response to
fetch
\n
\n - DX Improvements\n
- \n
- ember-workers (Upcoming addon!)\n
- \n
- Uses rollup under the hood for tree-shaking, ES module support across all browsers, etc \n
- Makes workers accessible everywhere \n
\n - promise-worker\n
- \n
- Problem: Evented async can get awkward \n
- This NPM package wraps Evented code in promise syntax for async/await \n
\n - testing\n
- \n
- Write modular code \n
- Unit test your modules (w/o workers) \n
- Stub workers in your tests \n
- worker-box\n
- \n
- Toolbox for stubbing web workers \n
- More info: https://www.youtube.com/watch?v=JBnNp8MpRSM \n
\n
\n
\n - ember-workers (Upcoming addon!)\n
- \n
- Speaker: Ed Faulkner (GitHub) \n
- Slides \n
- Notes \n
Compilers have a reputation for being esoteric and intimidating. But they don't need to be! A compiler is just a program that writes programs. This talk will be a practical tour through the Embroider build system that also teaches compiler concepts along the way. With the power of multi-pass compilation, Embroider can take a long-lived, conventional Ember app and give it lazy loading, code splitting, and tree shaking. All without modifying the app's own code.
\n\nEd is a member of the Ember Framework core team. His open source code is running on mainstream gaming consoles, major social media sites, and hordes of enterprise applications. His consultancy, Polynomial LLC, leads ambitious software projects for a diverse group of businesses and nonprofits, and he is a lead developer for the Cardstack Project. https://cardstack.com
\n\n- \n
- A compiler is a program\n
- \n
- All programs have an input and output \n
- A compiler's input and output are both programs\n
- \n
- Input: Language A, Output: Language B \n
- Input is often easier for humans to read, output is often easier for machines to read\n
- \n
- Decompiler swaps these \n
\n
\n - Self-hosting Compiler: Input is the same or similar language to what the compiler is written in itself \n
- Transpiler: Input/Output are very similar \n
\n - Static: Facts you can know about a program before you run it \n
- Dynamic: Facts you cannot know about a program before you run it \n
- Compilers preserve the semantics of the input language to produce the same output in the resulting program \n
- Often the input language cannot produce an output itself without being compiled first\n
- \n
- Example: Ember app compiles to
dist/**
, browser cannot run the Ember app itself \n - Conceptually, however, your app has both an input and an output, regardless of the implementation details \n
\n - Example: Ember app compiles to
- Implementor's Trap: Neglecting the abstract semantics of your language, because you know \"how it really works\". \n
- Does Ember have clear abstract semantics? Overwhelmingly, yes!\n
- \n
- Follows standards \n
- APIs are implemented very carefully \n
- One area in particular needs improvement: Modules \n
- Ember has been rewritten into modules over time, but we're not all the way there yet. The way we use modules today doesn't take advantage of everything modules were designed for.\n
- \n
- Ex: We don't have a static meaning that goes from a ModuleSpecifier to a specific module in a specific package. \n
\n
\n - ModuleSpecifier\n
- \n
- ECMA spec leaves this up to implementation, not codified by JavaScript the language \n
\n - Module imports must be known before program is run\n
- \n
- No dynamic names for imported files \n
- No conditional imports \n
- Everything about
import
is designed to be static \n - For dynamic things, there's
import()
\n
\n - RFC: V2 Addon Format (Embroider compatibility)\n
- \n
- This RFC defines a new package format that is designed to make Ember packages (meaning both apps and addons) statically analyzable and more compatible with the rest of the NPM & Javascript ecosystem. This RFC is the first step in stabilizing Embroider as our next-generation build system. \n
\n - Embroider: Multi-Stage Compiler\n
- \n
- Takes multiple intermediate compilation steps before final output is generated \n
- Allows you to simplify the input over time so that very powerful low-level optimizations become possible in the final output \n
- Target a well-documented, stable shared solution language instead of trying to compile all the way to what the machine will read \n
- Workflow: Ember App & Addons ->
@embroider/compat
-> V2 Ember Packages ->@embroider/core
-> Plain JS/CSS/HTML ->@embroider/webpack
-> Browser-optimized JS/CSS/HTML \n
\n - Stage 1: Compat\n
- \n
- Runs custom broccoli trees \n
- Moves files so they match their import paths \n
- Recaptures modules that try to escape their package \n
- Applies custom preprocessors \n
- Generates
@embroider/synthesized-vendor
package to represent legacy non-package-scoped contents as a v2 package \n
\n - Stage 2: Core\n
- \n
- Synthesizes JavaScript entrypoints that
import
the required modules to boot the app \n - Resolves components and helpers and emites
import
statements for them at the top of each compiled template module \n - Uses dynamic
import()
to express potential split points like routes and lazy engines \n
\n - Synthesizes JavaScript entrypoints that
- Stage 3: Optimized Packaging\n
- \n
- Delegate to a standard JavaScript build tool\n
- \n
- Could be rollup, parcel, etc \n
- Flexibility to choose future tools that haven't even been written yet! \n
\n - Give it total freedom to decide how our entire module graph should be optimized for web delivery \n
\n - Delegate to a standard JavaScript build tool\n
- Benefits\n
- \n
- Complete pull-based builds \n
- Faster builds \n
- Use dynamic
import()
anywhere for arbitrary code splitting and lazy loading \n - Automated route-aware code splitting \n
- Import anything directly from NPM, statically or dynamically\n
- \n
[ember-auto-import](https://github.com/ef4/ember-auto-import)
is a polyfill for Embroider's third-party package import, but it doesn't work with Ember code \n
\n
\n - Keep moving forward. No big app rewrites. Ember <3 \n
- \n
- Speaker: Jessica Jordan (GitHub) \n
- Slides \n
Ever wondered where your component state went or where it came from? In this talk you will learn how arguments, decorators and tracked properties make state management of your component built in Ember Octane easier than ever before. In comparison with patterns known from traditional Ember apps, you will learn how to transform your modern components to predictable and future-proof building blocks of your application.
\n\nJessica is a member of the Ember Learning Core team and a software engineer at simplabs. She is an editor at The Ember Times and organizes the Ember Berlin meetup. She is passionate about open-source, CSS, art and comics.
\n\n- \n
- Stateful systems remember preceding events \n
- Types of State in JavaScript Apps: Local, Closure, Object, Global \n
- State Management in Ember apps is about Object State\n
- \n
- Service State \n
- Controller State \n
- Component State \n
\n - Managing Ember Component State\n
- \n
- Properties \n
- Arguments \n
- Lifecycle Hooks \n
- Event Handling \n
- Dependency Injections \n
- Data Loading \n
- Components own state and methods to manipulate local and external state \n
\n - State management can be hard! \n
- Common Symptoms of Hard to Manage State in Components include...\n
- \n
- Cyclical data flows \n
- Race conditions \n
- Overall unpredictable state changes \n
- Low performance \n
\n - Predictability for Initial State in Components\n
- \n
- It's not always clear where a property was set\n
- \n
- Was it passed in or defined in the component js (or both)? \n
\n - Octane: Named arguments bring clarity\n
- \n
this.args
\n- Data Ownership: \"Is it an argument or not?\" \n
- Getters make it easy to have default values without clobbering them with arguments \n
\n
\n - It's not always clear where a property was set\n
- Predictability of Component State over time\n
- \n
- Ambiguity about where properties are updated \n
- Holding & Loading of Data: Methods for Modifying Owned Data\n
- \n
- Automatic separation of concerns: Data management vs Presentation \n
- Other communities call this \"Container\" and \"Presentational\" components \n
\n - Octane: Enforce \"Data Down, Actions Up\" (DDAU) with Argument Immutability\n
- \n
- Pass down arguments and actions \n
- Send updated values up via actions \n
- No ambiguity about where properties are updated \n
\n - Modifying application-wide state with Components\n
- \n
- Service: Owner of application state \n
- Inject service into target instance: Component, Controller, or another Service \n
\n - Encouraged DDAU facilitates state management\n
- \n
- Encourages directed acyclical graphs (DAG) for data flow \n
- Easier separation of concerns \n
- Prevents accidental overwrites of computed properties \n
\n
\n - Predictability of Component State through API Clarity\n
- \n
- Octane: Glimmer components provide leaner, more intuitive API\n
- \n
- 11 Lifecycle hooks removed \n
- 29 event handlers removed \n
- 1 constructor added \n
- Single location of hooks \n
\n - Glimmer Component RFC \n
\n - Octane: Glimmer components provide leaner, more intuitive API\n
- Managing Component State for Optimal Performance\n
- \n
- Template-Only Components\n
- \n
- High-performing presentational UI \n
\n - Localize Component State for Efficient Garbage Collection\n
- \n
- Ember is good at cleaning up components, so you can ensure state doesn't stick around when it's not needed \n
\n - Avoid Repeated Rendering\n
- \n
- Reduces re-renders to the bare minimum \n
- @tracked (RFC) \n
\n
\n - Template-Only Components\n
- Experience the Future of Steady State with Ember Octane! \n
Like the cities they represent, interactive maps are complicated feats of engineering. They are resource-intensive microcosms of state management, requiring special data formats and styling specifications. When the needs of an application go beyond showing points on a map, cartographic applications can quickly grow unwieldy and unsustainable. Throw moving targets, messy data, and squeezed timelines into the mix, and you've got an enormous component that does everything – poorly. This talk discusses the latest mapping technology and approaches to building better components - map-based or otherwise.
\n\nMatt Gardner is a software engineer for the NYC Department of City Planning. Originally an urban planner, he pivoted into application development after seeing a gap in need for better software in government, specifically in the public advocacy realm. He and his team, Planning Labs, rebuilt the City of New York's digital zoning and land use map using EmberJS.
\n\n- \n
- We use maps every day \n
- Maps are used for more than just navigation \n
- Spatial relationships are important \n
- We can map social-political issues \n
- Basemap\n
- \n
- Static data that is always present \n
\n - Data layers\n
- \n
- Polygons \n
- Lines \n
- Points! \n
\n - Modern Technologies\n
- \n
- ArcGIS\n
- \n
- Early digital mapping tool \n
- Couldn't be used on the web \n
\n - MapQuest\n
- \n
- Web service launched in 1996 \n
- Very slow \n
\n - TILE\n
- \n
- Loads much faster \n
- \"Slippy maps\" \n
- Used by Google Maps, Open Street Map, etc (NOT EmberMap LOL) \n
- Serve tile information as vector data \n
- There are a lot of different ways to project a spherical shape onto a flat surface\n
- \n
- Assume the world is a square \n
- Start with one tile, double the number of tiles every level of zoom \n
\n
\n - GeoJSON\n
- \n
- Format for encoding geographic data structures \n
\n - Carto\n
- \n
- Location services \n
\n - MapboxGL\n
- \n
- Canvas-based JS library \n
- Accessibility Controls: mapbox-gl-accessibility \n
\n
\n - ArcGIS\n
- ember-leaflet \n
- ember-mapbox-gl \n
- Building a map component\n
- \n
- Started very long, one component \n
- Extracted smaller components as needed \n
- Don't abstract too early, you might not predict the evolving design correctly \n
\n - Testing\n
- \n
- Elaborate Stub \n
- Tricky: MapboxGL is event-driven \n
- Don't mock what you don't own (but it worked really well for us in this case) \n
\n - Map users seldom, if ever, question these authorities, and they often fail to appreciate the map's power as a tool of deliberate falsification or subtle propaganda. \n
- Mapping can be used deceptively\n
- \n
- Breaking data into more/less segments \n
- Stronger language \n
\n
- \n
- Speaker: James Steinbach (GitHub) \n
- Slides \n
We naturally invent stories to explain phenomena we can't understand. If your app leaves changes \"vague,\" users will make up explanations about how it works. Some developers see animation as a fancy gimmick to slap on at the end of a project. Others want to use it in a helpful way but aren't sure how. Both will learn that animation is a meaningful tool and how to use it effectively to reduce user error. In this talk, we'll avoid getting in the weeds with addons, JS libraries, or CSS frameworks. Instead we'll learn the ways that animation can aid your users and see practical UI examples.
\n\nJames is a senior developer with more than 10 years of front-end experience. If you let him talk, you're liable to get an earful about modular styles, accessible pages, cool CSS tricks, or random restaurant reviews (especially if pizza or BBQ are involved).
\n\n- \n
- Why do we animate elements?\n
- \n
- Set a client's site apart \n
- \"Make it pop!\" \n
- Show off dev skill \n
- Best Reason: Communicate Meaning About The Content \n
\n - We make up stories\n
- \n
- Whenever things happen, we automatically invent a narrative to explain those events \n
- We often do a bad job: \"post hoc ergo\", \"propter hoc\" aka \"Correlation does not imply causation\" \n
- Example: Athletes develop rituals based on random behavior they did while having a great performance \n
- Users develop digital rituals as well, based on trained behavior from past experiences \n
\n - Animation tells the right story\n
- \n
- When we animate an interface correctly, we make sure users don't make up the wrong story \n
\n - Show which pieces of content deserve the user's attention \n
- Indicate that the app or element is busy with an async action\n
- \n
- CSS can be keyed to
aria-busy=\"true\"
\n
\n - CSS can be keyed to
- Show relationships between elements \n
- Show the source of some content \n
- Show the destination of some content (e.g. \"Add to Cart\" button) \n
- Video: The Illusion Of Life \n
- Easing Curves\n
- \n
- Defines acceleration pattern for animations \n
animation-timing-function
\n- \n
- linear \n
- ease-in \n
- ease-out \n
- ease-in-out \n
\ncubic-bezier
\n- \n
- Custom function applying specific coordinates to the easing curve \n
\n
\n - Not all properties work well when animated\n
- \n
- Best:
opacity
,transform
\n - Decent:
[*-]color
\n - Avoid:
margin
,padding
,width
,height
,top
,right
,bottom
,left
,font-size
,border
,box-shadow
\n
\n - Best:
- Respect Your Users\n
- \n
- Users can indicate they don't want motion:
@media (prefers-reduced-motion: reduce)
\n - Nuclear option: Turn off everything \n
- Lighter option: Set timings (delay/duration) to 0 \n
\n - Users can indicate they don't want motion:
- If an animation is causing problems, remove it. The animation is not more important than your users being able to get through the app. \n
- \n
- Speakers:\n
- \n
- Jen Weber (GitHub) \n
- Preston Sego (GitHub) \n
\n
As Ms. Frizzle says, \"Take chances, make mistakes, get messy!\" Join two Ember developers as they livestream Ember Q&A from the Stack Overflow, the Discuss Forums, and the audience. In this activity, Jen and Preston will teach strategies for leveling up the skills necessary for positive interactions and and get answers to your own burning questions!
\n\n\nJen Weber is a member of the Ember Core Team. She works at Cardstack, making Web 3.0 accessible to everyone and empowering new creators. (she/her/they/them)
\n\nPreston Sego is an Open Source Enthusiast. He has a side project, emberclear.io, which is both a place to explore new features of the web platform, and help others learn Ember and frontend testing patterns. He works at CrowdStrike, helping build interfaces for the cloud-native endpoint protection platform built to stop breaches.
\n\n- \n
- 23,351 #EmberJS Questions on StackOverflow\n
- \n
- 66% of questions asked within the last 7 days are \"unanswered\" \n
- 27% of questions all-time are \"unanswered\" \n
- Some frameworks actually have worse statistics (React/Vue/etc) \n
\n - Components come in many shapes and forms, but they all need a template\n
- \n
- You can now generate \"glimmer components\" in Octane \n
\n - Decorators are not Ember-specific\n
- \n
- They allow you to label your code to give it additional functionality \n
\n - Angle-Bracket Notation\n
- \n
- Reference
this
to access properties \n
\n - Reference
- In Ember 3.14, reference
@model
in the route template to access the object returned from themodel()
hook - @rwjblue \n - In Octane, component arguments are immutable\n
- \n
- Will throw an Ember Error \n
- Arguments object uses the Proxy API \n
- Argument immutability is not deeply-nested, operates more like
const
\n
\n - Ember Guides provide cheat sheets comparing classic Ember patterns with Octane patterns \n
@tracked
\n- \n
- Decorator that marks things that need to be watched for changes \n
- Anything using the tracked property will update automatically \n
- A tracked property on the Route object will not update the Route template, because that template is actually backed by a Controller - @rwjblue \n
\n- Try to engage on StackOverflow\n
- \n
- Good questions:\n
- \n
- Provide extensive details \n
- Explain what's been tried already \n
\n - Good answers:\n
- \n
- State what version it applies to \n
- Links to docs \n
- Copy example code into the answer (don't just use a gist) \n
- Be gentle and kind \n
\n - Upvote when you see a good answer \n
- Comment on questions/answers \n
\n - Good questions:\n
- \n
- How to send action to route? (2-year-old StackOverflow question)\n
- \n
@action
decorator \n- Canonically, we would put actions on the controller and pass them down to components \n
- Question: Why can't we use the
action
helper with a string in the top-level route template?\n- \n
- Answer: You can! \n
\n
\n - How is Octane different from AJAX?\n
- \n
- Octane is an edition of Ember \n
- AJAX is a form of asynchronous data fetching, now superseded by
fetch
\n
\n - Will Embroider be ready for Octane?\n
- \n
- No, but you can experiment with it during development \n
- It will be a primary focus for the community after Octane ships \n
\n - How do we promote Ember?\n
- \n
- Talk about our success with Ember \n
- Talk about how stable our work lives are because of Ember \n
- Ember provides incremental improvements\n
- \n
- We've all saved a lot of time through Ember's upgrade process \n
- Steady, constant, incremental improvements over time instead of a \"Big Bang\" rewrite \n
\n - Octane's existence is proof that it's time to give Ember another look\n
- \n
- Delivered without a major release or breaking change! \n
\n - Give talks at local JS meetups\n
- \n
- Octane is all native JavaScript \n
\n
\n - When will angle brackets support nested components?\n
- \n
- Supported as of 3.10ish, there is also a polyfill:
[ember-angle-bracket-invocation-polyfill](https://github.com/rwjblue/ember-angle-bracket-invocation-polyfill)
\n
\n - Supported as of 3.10ish, there is also a polyfill:
- When will routeable components land?\n
- \n
- If you've been holding out for this feature, let it go and adopt the features that have replaced this concept, such as the routing service \n
\n - How do you go from intermediate to expert Ember developer?\n
- \n
- Write lots of code \n
- Make mistakes \n
- Ask for help \n
- Participate in Open Source\n
- \n
- Opportunity to learn from more experienced people \n
\n - Dive into Ember's source code, look at stack traces \n
\n
- \n
- Speaker: Lisa Backer (GitHub) \n
- Slides \n
The testing world is full of ways to simulate data and user interaction. Mocks, spies, stubs, and timers all allow you to focus your tests and remove unwanted interference. Maybe you've tried to set them up and been overwhelmed or maybe you've never even heard of them. Core concepts can help developers frame their thoughts about testing and structuring tests. We'll explore those core concepts and look at how to leverage existing libraries like Sinon.js, Pretender.js, and even ember-cli-mirage, with examples to make your test suite more stable and reliable.
\n\nLisa is a senior engineer at DockYard, helping large clients integrate Ember.js at scale with a commitment to quality. This commitment has led to a passion for testing. She has 20 years of web development experience ranging from consulting and product development, to helping nonprofit institutions in both paid and volunteer capacities.
\n\n- \n
- Focus on thoughtful tests rather than a high quantity of tests \n
- Unit Tests are useful for testing pure functions where the return value is only determined by its input values, without any observable side effects. \n
- Container Tests test the functionality around an Ember class instance by setting up the application's container. \n
- Rendering Tests test the interactions between various parts of the application, such as behavior between UI controls. \n
- Application Tests test user interaction and application flow in order to verify user stories or a feature from an end-user perspective. \n
- SinonJS\n
- \n
- Spies: Record information about when functions are called\n
- \n
- Data: number of calls, arguments, errors, etc \n
- Can be created anonymously or called on an existing function on an object \n
- Use when you want to verify a callback or ensure a function was called with specific inputs \n
\n - Stubs\n
- \n
- Mock the output of a function \n
- Also has properties of spies \n
- Use when you need to simulate different responses from systems that are complicated to initialize \n
\n - Fakes\n
- \n
- Combines stub and spy behavior only for anonymous functions \n
- Use when you can't remember whether to use a spy or stub \n
\n - Mocks\n
- \n
- Combines stub and spy behavior with pre-defined assertions \n
- Use if you like to set up your assertions at the beginning when you define your behavior \n
\n - Timers\n
- \n
- Synchronous implementation for testing async behaviors (e.g.
setTimeout
) \n
\n - Synchronous implementation for testing async behaviors (e.g.
\n - Spies: Record information about when functions are called\n
- Using Sinon in Ember\n
- \n
ember-sinon
\n- \n
- Provides the
sinon
package as an import \n
\n- Provides the
- Solutions for handling sinon setup/cleanup have evolved over time:\n
- \n
ember-sinon-qunit
->ember-sinon-sandbox
->ember-sinon-sinoff
->ember-sinon-qunit
\n- \n
- Use
[ember-sinon-qunit](https://github.com/elwayman02/ember-sinon-qunit)
moving forward \n
\n- Use
ember-sinon-chai
->ember-cli-chai
(no cleanups/test setup, needs sandbox) \n
\n
\n - TestDouble.js\n
- \n
- Simpler, opinionated mocking library \n
\n - Jest\n
- \n
- Chai-like assertion syntax \n
- Automatic mocking \n
- Manual mocking \n
- Snapshot tests \n
- Can include test coverage \n
- Note: Does not run in browser \n
\n - There's a lot of commonly accepted wisdom around mocking that isn't always applicable \n
- Don't mock what you don't own \n
- \n
- \n
Speaker: Spencer Price (GitHub)
\n \n - \n
Slides: https://speakerdeck.com/spencer516/modifiers-the-good-and-the-camp
\n \n
During the rush up to Ember Conf and the formal release of Ember Octane, Element modifiers seemed to magically appear through a series of blog posts that identified a brand-new base tool for Ember applications. Since they are still so new: When should we use them? How should we use them? When should we not use them? In this talk, we'll explore a number of use cases and explore how to model them using modifiers. Some good; some ambiguous; some plain silly.
\n\nSpencer is an Engineering Manager for Movable Ink in New York City. He has been building applications with Ember for over seven years and has been experimenting with use cases for modifiers ever since they were formally announced in February. Outside of work, you'll find me blocking people's view at Broadway shows, walking my obnoxiously happy dog, or watching good movies.
\n\n- \n
- Camp: \"It is the love of the exaggerated, the 'off', of things-being-what-they-are-not.\" \n
- \"What it does is to find the success in certain passionate failures.\" \n
- \"The whole point of Camp is to dethrone the serious. Camp is playful and anti-serious.\" \n
- Concept\n
- \n
- A small reusable tool, like a Helper, that attaches behavior to elements through lifecycle events \n
- Example: Autofocus\n
- \n
- Only works on initial Page Load, which is problematic in SPAs \n
element.focus()
needs to be fired instead \n
\n - Cannot be expressed by HTML alone\n
- \n
- Does not run service-side in Fastboot \n
\n
\n - History of Ember Modifiers\n
- \n
{{action}}
- attaches event listeners to elements\n- \n
- Supports an
on=\"EVENT_TYPE'
argument \n
\n- Supports an
{{bind-attr}}
modifier to set element attributes\n- \n
- Deprecated in 1.11, Removed in 2.0 \n
\n- Autofocus before Modifiers\n
- \n
- Could have used
didInsertElement
to callelement.focus()
\n - Could have written a mixin \n
- Octane: Create an action that calls
element.focus()
, usedid-insert
modifier to trigger it \n
\n - Could have used
\n - Creating Modifiers\n
- \n
setModifierManager
API\n- \n
- Not recommended, lots of low-level stuff to wade through \n
\nember-oo-modifiers
\n- \n
- Recommended \n
- Autofocus: Create a modifier class that implements
didInsertElement
to callelement.focus()
\n- \n
- Usage:
<input {{autofocus}} />
\n - Custom:
<MySpecialInput {{autofocus}} />
\n- \n
- Inside the component:
<input ...attributes />
\n
\n - Inside the component:
\n - Usage:
\nember-functional-modifiers
\n- \n
- Recommended \n
\n
\n - Good Use Cases\n
- \n
draggable
\n- \n
- Accept a callback for the updated position:
{{draggable this.updatePosition}}
\n
\n- Accept a callback for the updated position:
track-on
\n- \n
- Fire tracking events \n
\nflyover
\n- \n
- Tooltip/popup modifier \n
launch-pad
- Tether to the element that the flyover in anchored to \n
\ndid-resize
\n- \n
- Fire action when the element resizes \n
[ember-did-resize-modifier](https://github.com/gmurphey/ember-did-resize-modifier)
\n
\nfocus-trap
\n- \n
[ember-focus-trap](https://github.com/josemarluedke/ember-focus-trap)
\n
\n
\n - Campy Use Cases\n
- \n
scoped
\n- \n
- Borrowed idea from
ember-provider
(Not really maintained, doesn't work in glimmer) \n - Based on React/Redux's Provider concept \n
- Problems:\n
- \n
- Wouldn't work with wormholes \n
- Another global state? \n
\n
\n- Borrowed idea from
- split-view\n
- \n
- Turns all child elements into resizeable split views \n
[ember-split-view-modifier](https://github.com/OAGAnalytics/ember-split-view-modifier)
\n- \n
- Uses Split.js \n
\n- Problems:\n
- \n
- Unmanaged elements \n
- Conditional elements don't work \n
- Component-based API could be better \n
\n
\n - predict-on\n
- \n
- Similar to
on
modifier, but with predictions \n - guess-js \n
- Fun idea, \"I have no idea how to do this\" \n
\n - Similar to
\n - Very Campy Use Cases\n
- \n
- ón\n
- \n
- Fire action randomly 90% of the time \n
\n - expletive\n
- \n
- Draws box around mis-aligned elements \n
\n - pointy-cursor\n
- \n
- Keeps cursor oriented toward the clickable element at all times \n
\n
\n - ón\n
- If someone tells you \"this is a bad idea\", say \"no, this is a campy idea\" \n
- If you find yourself saying \"this is a bad idea\", find the fun in people's passionate failures. \n
- \n
- Speaker: Olivia Liddell \n
- Slides \n
Olivia Liddell is a Cloud Training Specialist at Cloudbakers. She is a former Chicago Public Schools teacher who now specializes in technology training and change management. She is passionate about teaching, mentoring, and distance running.
\n\n- \n
- What does risk taking look like?\n
- \n
- Google Image search shows a lot of images for \"risk taking\"\n
- \n
- Leaps of faith across a chasm \n
- Tightrope walking \n
\n - Risk taking doesn't have to be a big leap across a canyon\n
- \n
- Take small steps forward \n
\n
\n - Google Image search shows a lot of images for \"risk taking\"\n
- I want it all to work right away, no mistakes\n
- \n
- Really, I just don't want to feel inadequate \n
\n - Taking smaller steps makes it easier to see your path \n
- Taking small steps forward is still moving forward \n
- Trying something new does not take away from who you already are \n
- Growth Mindset\n
- \n
- Shift away from a \"Fixed Mindset\" \n
- Share and reflect on both your successes and struggles \n
- View your struggles and setbacks as opportunities to teach others \n
- Seek out positive and encouraging communities \n
\n - Risk Taking:\n
- \n
- Taking small steps forward \n
- Enhancing your current skill set \n
- Shifting towards a growth mindset \n
\n - Live Bravely! \n
- \n
- Speakers:\n
- \n
- Melanie Sumner (GitHub) \n
- Sean Massa (GitHub) \n
\n
- \n
- Thank you for coming \n
- ~100 attendees, over half from outside of Chicago \n
- Thank you to our sponsors \n
- Trek did such a great job as emcee! (there were flowers) \n
- We had a lot of fun putting this event together, but these events are a lot of work!\n
- \n
- Please give us feedback: Whether you enjoyed it or not, we need to hear from you so we can make future years even better. \n
- We won't judge you regardless, we appreciate everything you tell us about the event \n
\n - Please let speakers know if you liked their talks, talk to them about those topics \n
- After Party! \n