Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Taming the Beast

111 views

Published on



What do you do when your codebase gets too big?

Ember is perfect for “ambitious applications”. But what about really ambitious applications? Apps with hundreds of thousands of lines of code, teams that span countries, and users all over the world? Or apps in high liability environments where regressions from upgrades could cost millions of dollars or even put people in danger?

Recent advances in two tools present an opportunity to structure a project that is easy to work in and upgrade, but without the pain points of past solutions. Those tools are Ember Engines, and Yarn workspaces.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Taming the Beast

  1. 1. Beast Taming The Managing a really ambitious codebase
  2. 2. Luke Deniston
  3. 3. • Four kids • Luke Deniston
  4. 4. • Four kids • Rock and roll • Luke Deniston
  5. 5. • Four kids • Rock and roll • MAGIC THE GATHERING Luke Deniston
  6. 6. The beast
  7. 7. Complexity
  8. 8. –Edsger W. Dijkstra (1972) The competent programmer is fully aware of the strictly limited size of his own skull; therefore he approaches the programming task in full humility, and among other things he avoids clever tricks like the plague
  9. 9. The Root Cause of Failure in Complex IT Projects: Complexity Itself
  10. 10. Developers Two stories Computers
  11. 11. Memoizing a function
  12. 12. Senior engineer
  13. 13. Inevitable
  14. 14. • Abstracting • Subdividing Strategies
  15. 15. 25,000+ GROWERS 10,700+ AGRONOMISTS 3,000+ RETAIL LOCATIONS 60+ FOOD 
 COMPANIES 3,300+ PARTNER INTEGRATIONS 150,000+ GROWERS 
 MANAGED © AGRIAN INC. 2020—AGRIAN INC. CONFIDENTIAL 2020
  16. 16. AG RETAIL © AGRIAN INC. 2020—AGRIAN INC. CONFIDENTIAL 2020
  17. 17. FOOD COMPANIES © AGRIAN INC. 2020—AGRIAN INC. CONFIDENTIAL 2020
  18. 18. ONE PLACE FOR ALL OF YOUR PARTNER INTEGRATIONS SATELLITE IMAGERY APPLICATION DATA EC & OM SOIL MAPPING PLANTING DATA FIELD SAMPLES HARVEST DATA CROP PLANNING PLANTING RX FERTILITY/ CP RX REPORTING MANAGEMENT ZONE CREATION ANALYTICS © AGRIAN INC. 2020—AGRIAN INC. CONFIDENTIAL 2020
  19. 19. Satellite) Zone Creation
  20. 20. Pesticide label compliance/rx
  21. 21. Ember And Rails The journey
  22. 22. Repomageddon The journey
  23. 23. Yarn Workspace + Ember engines
  24. 24. • developed by Facebook • Npm has almost caught up • Yarn 2 rewrite: Angry? Yarn Workspace + Ember engines
  25. 25. • 1 repo, many packages • Packages can import each other • Like npm link but actually works Yarn Workspace + Ember engines
  26. 26. • Specific type of EMBER add-on • more like an application: Own container and registry • Built and booted by host • Routable or rootless • Optionally lazy loaded • Code isolation Yarn Workspace + Ember engines
  27. 27. Perfection
  28. 28. { "private": true, "workspaces": ["packages!/*"] } Workspaces /package.json
  29. 29. { "name": "package-b", "version": "1.0.0", "dependencies": { "package-a": "1.0.0" } } { "name": "package-a", "version": "1.0.0", } packages/package-b/package.jsonpackages/package-a/package.json Workspaces
  30. 30. { "name": "package-b", "version": "1.0.0", "dependencies": { "package-a": "1.0.0" “left-pad": "1.0.0" } } { "name": "package-a", "version": “1.0.0", "dependencies": { "left-pad": "1.0.0" } } packages/package-b/package.jsonpackages/package-a/package.json Workspaces
  31. 31. { "name": "package-b", "version": "1.0.0", "dependencies": { "package-a": "1.0.0" “left-pad": "1.0.0" } } { "name": "package-a", "version": “1.0.0", "dependencies": { "left-pad": "1.0.1" } } packages/package-b/package.jsonpackages/package-a/package.json Workspaces
  32. 32. package.json ⌄ packages | > host-app | > engines | > shared-files | > published-addon | > shared-addons (styles/models/components) | > shared-addons (specific funtionality) Workspaces
  33. 33. ember-engines.com
  34. 34. → ember addon my-engine → ember install ember-engines Add ember-cli-htmlbars as a dependency Configure index.js Configure config/environment.js Configure addon/engine.js Engines: Setup
  35. 35. const EngineAddon = require('ember-engines/lib/engine-addon'); module.exports = EngineAddon.extend({ name: 'my-engine' }); index.js Engines: Setup
  36. 36. module.exports = function(environment) { const ENV = { modulePrefix: 'my-engine', environment: environment } return ENV; }; config/environment.js Engines: Setup
  37. 37. import Engine from 'ember-engines/engine'; import Resolver from 'ember-resolver'; import loadInitializers from 'ember-load-initializers'; import config from './config/environment'; const { modulePrefix } = config; const Eng = Engine.extend({ modulePrefix, Resolver }); loadInitializers(Eng, modulePrefix); export default Eng; addon/engine.js Engines: Setup
  38. 38. Router.map(function() { }); /packages/host-app/app/router.js Engines: Setup this.mount('my-engine'); this.mount('my-engine-b', { resetNamespace: true, path: '/blarg' }); this.mount('my-engine-b', { as: 'motor', path: '/motor' });
  39. 39. {{mount "my-engine"}} {{mount "my-engine" model=(hash title="Foo")}} Engines: Setup
  40. 40. const EngineAddon = require('ember-engines/lib/engine-addon'); module.exports = EngineAddon.extend({ name: 'my-engine', }); lazyLoading: { enabled: true, }, Engines: tips config/environment.js
  41. 41. import { setupTest } from 'ember-qunit'; import engineResolverFor from 'ember-engines/test-support/engine-resolver-for'; import Resolver from 'ember-resolver'; export default function(hooks){ const engineResolver = engineResolverFor('crop-records-engine'); const resolver = Resolver.extend({ namespace: { modulePrefix: 'dummy' }, resolve() { return this._super(!!...arguments) !|| engineResolver.resolve(!!...arguments); }, }).create(); return setupTest(hooks, { resolver }); } my-engine/tests/helpers/setup-test.js
  42. 42. export default Engine.extend({ dependencies: { services: ['store'] } }); my-engine/addon/engine.js Engines: tips const App = Application.extend({ engines: { myEngine: { dependencies: { services: ['store'] } } } }); host-app/app/app.js
  43. 43. Error! Engines: tips !// session is shared, store is not let userModel = this.session.user; this.store.createRecord('foo', { createdBy: user })
  44. 44. package.json ⌄ packages | > host-app | > engine-a | > engine-a-models Engines: tips
  45. 45. Replace This With Your Real Tests Use the last argument to assert Use prettier or eslint Be careful with addons Use typescript Use tailwind Controversy!
  46. 46. @lukedeniston lukedeniston.com luke@lukedeniston.com Thanks!

×