Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

High quality Front-End

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Wird geladen in …3
×

Hier ansehen

1 von 174 Anzeige

High quality Front-End

Herunterladen, um offline zu lesen

All too often front-end JavaScript code has been considered a second class citizen, and when treated without due care and attention it can be buggy and hard to maintain. This attitude is changing though, and thanks to the rapid growth in popularity of JavaScript as a first-class language, there is a large and expanding ecosystem of tools that a developer should know to make their client-side code as “clean” as the rest of their stack.
This talk aims to introduce and discuss how to implement modularisation, functional idioms and testing in JavaScript in an idiomatic way, to allow you to code JavaScript to a higher quality and, ultimately, more sustainably.

All too often front-end JavaScript code has been considered a second class citizen, and when treated without due care and attention it can be buggy and hard to maintain. This attitude is changing though, and thanks to the rapid growth in popularity of JavaScript as a first-class language, there is a large and expanding ecosystem of tools that a developer should know to make their client-side code as “clean” as the rest of their stack.
This talk aims to introduce and discuss how to implement modularisation, functional idioms and testing in JavaScript in an idiomatic way, to allow you to code JavaScript to a higher quality and, ultimately, more sustainably.

Anzeige
Anzeige

Weitere Verwandte Inhalte

Andere mochten auch (20)

Anzeige

Ähnlich wie High quality Front-End (20)

Anzeige

Aktuellste (20)

High quality Front-End

  1. 1. High-Quality Front End @SwamWithTurtles David Simons, Softwire
  2. 2. W H O A M I ? • David Simons • @SwamWithTurtles • swamwithturtles.com • Technical Lead on a range of projects • Mostly JS or Java around data visualisation • Open-source contributor • Background in Statistics & Simulation
  3. 3. W H O A M I ? • Softwire • Software Consultancy in London & Bristol • We work on a lot of projects What you see today is knowledge gained through hard-won experience.
  4. 4. W H AT A R E W E TA L K I N G A B O U T T O D AY ? PA S T P R E S E N T F U T U R E JavaScript’s Legacy The Modern Ecosystem & Solutions Practical Next Steps
  5. 5. W H AT A R E W E TA L K I N G A B O U T T O D AY ? • Some of the problems of JavaScript - and the impacts of them • Native, languages and third party solutions to these problems
  6. 6. W H AT W E ’ R E N O T TA L K I N G A B O U T • HTML/CSS • Server-side JavaScript • (In-Depth) Discussions of ES6/ES2015 • In-Depth Discussions of any JavaScript library
  7. 7. Ho w D i d We E n d U p He r e ?
  8. 8. A ( B R I E F ) H I S T O RY O F J AVA S C R I P T T I M E F O R A
  9. 9. H I S T O RY O F J AVA S C R I P T • First developed in 1995 by Brendan Eich to provide and support user- interaction • Much maligned, but the only real way to run interactive scripts on the browser-side code
  10. 10. B A S I C S O F J AVA S C R I P T • Interpreted by browsers* according to a set of rules (ECMAScript) • Combination of scripting language, functional language and object- oriented language
  11. 11. W H Y J AVA S C R I P T WA S S O M A L I G N E D ?
  12. 12. H O W J AVA S C R I P T U S E D T O W O R K • Swathes of code from sites like DynamicDrive and then tinkered and added.
  13. 13. H O W J AVA S C R I P T U S E D T O W O R K • In more professional outfits… • Things may have been done better, but if so, people were fighting the ecosystem
  14. 14. W H AT P R O B L E M S A R E T H E R E ? S O …
  15. 15. O N E B I G ‘ L U M P ’ O F F I L E S W E D O N ’ T L I K E
  16. 16. O N E B I G ‘ L U M P ’ O F F I L E S • One big, long script with loads of global variables was added to page that had the potential to conflict • No easy way to encapsulate code
  17. 17. O N E B I G ‘ L U M P ’ O F F I L E S • Very hard to unit test well
  18. 18. L A C K O F C L A S S E S W E D O N ’ T L I K E
  19. 19. P R O T O T Y PA L I N H E R I TA N C E • No Classes • No Classical Inheritance
  20. 20. I T S S C O P I N G W E D O N ’ T L I K E
  21. 21. J AVA S C R I P T ’ S S C O P E • JavaScript has “functional” scope
  22. 22. var func = function() { var localVar = 7; console.log(localVar); } console.log(localVar);
  23. 23. I M P L I C AT I O N S • No such thing as “private variable” - if we want to make sure that a variable is not accessible everywhere we have to embed it in a function
  24. 24. I T S T Y P E S Y S T E M W E D O N ’ T L I K E …
  25. 25. J AVA S C R I P T ’ S “ U N D E F I N E D ” T Y P E S • null • undefined • NaN
  26. 26. T Y P E C A S T I N G • 1 + true = • {} + 1 = • 1 + {} = 
 • 2 + false = • “2” + false =
  27. 27. T Y P E C A S T I N G • 1 + true = 2 • {} + 1 = 1 • 1 + {} = 
 “1[object Object]” • 2 + false = 2 • “2” + false = “2false”
  28. 28. T R U T H Y A N D FA L S E • Every variable gets cast to either true or false • Falsey variables: • 0, “”, false, null, undefined, NaN • Every other value is truth - that is, cast to true
  29. 29. W H Y D O W E C A R E A B O U T T H I S * ? B U T I N E E D T O K N O W *aka… How do we sell this to the business?
  30. 30. W H Y C L E A N C O D E ?
  31. 31. W H Y C L E A N C O D E ? • There are many good books written extolling the virtues of clean code
  32. 32. R E A D A B L E • You aren’t the only person working on your code. • Readable code eases learning (including future you) of what you are doing on the project • Including use of standard patterns
  33. 33. E N C A P S U L AT E D • Layered or encapsulated architectures make code more understandable • If these are driven by business or functional concerns, they are swappable • Enhancements are broken into smaller bits
  34. 34. T E S T E D • Testing provides assurance that changes don’t break old functionality • Ensuring code is unit- testable enforces good design decisions • It provides running documentation of your code
  35. 35. W H Y N O W ?
  36. 36. W H Y N O W ? • Rise of web development • More is being done on the client side
  37. 37. W H Y N O W ? • JavaScript is in the spotlight because of Node.js and its use as a DB query language in (e.g.) MongoDB
  38. 38. W H Y N O W ? • Developers are spoilt with the range of mid- and back-tier language so no longer feel like they have to say “yes” to bad tooling
  39. 39. T H E B O T T O M L I N E
  40. 40. T H E B O T T O M L I N E • Poorly tested code is error- prone, likely to regress and like to need correction • Poorly written code increases the cost of software maintenance, software enhancement and team changes. • Poor tooling decreases productivity and increases employee churn.
  41. 41. T H E B O T T O M L I N E • Bad software is more expensive. • Lots of legacy JavaScript is bad.
  42. 42. R E C A P 1 2 3 JavaScript is the only (modern) language that can be run on browsers Due to historical context, it’s unpleasant to work with and lacking in modern features These problems significantly impact the cost, quality and timescales of a project.
  43. 43. W H AT CA N W E D O B E T T E R ?
  44. 44. B E T T E R J AVA S C R I P T W E C A N W R I T E …
  45. 45. A B A D W O R K M A N • “A bad workman blames his tools” • Sometimes you work against the idioms of the language • “Transliterated” C# code is not always good JavaScript
  46. 46. A P R O V I S O • “A good workman knows when his tools are inadequate, and is always seeking to find better more effective tools.” • Sometimes a language sets up a ridiculous paradigm to adhere to. • *ahemXSLTahem*
  47. 47. S O B E F O R E W E M O V E O N … • A few things that make me want to bang JavaScript code against a brick wall.
  48. 48. U N D E R S TA N D I T S L A N G U A G E F E AT U R E S
  49. 49. VA N I L L A . J S
  50. 50. I T ’ S J U S T J AVA S C R I P T • Lots of misunderstanding about JavaScript • (I blame jQuery) • It’s not as featureless as you may think!
  51. 51. Y O U ’ R E W R I T I N G J AVA S C R I P T. N O T C #
  52. 52. Y O U ’ R E W R I T I N G J AVA S C R I P T. N O T C # • You don’t have classes. You don’t have (classical) inheritance. • You don’t have strong types • You can use prototypes, or take advantage of the dynamically typed nature of the language
  53. 53. Y O U ’ R E W R I T I N G J AVA S C R I P T. N O T C # • JavaScript is very functional, and has many patterns revolving around (e.g.) callbacks. • You can’t avoid them.
  54. 54. J AVA S C R I P T I S A F U N C T I O N A L L A N G U A G E
  55. 55. J AVA S C R I P T I S A F U N C T I O N A L L A N G U A G E • We can use functional idioms like “map” and “filter” and “reduce” (post-IE8) • So stop iterating through for loops
  56. 56. R E I N V E N T I N G T H E W H E E L A V O I D
  57. 57. T H E J AVA S C R I P T E C O S Y S T E M J A VA S C R I P T L I B R A R I E S
  58. 58. T H E E C O S Y S T E M • JavaScript doesn’t have a load of stuff built in - it’s fairly bare bones. • But - because of the prevalence (and quality) of it, a lot of people have supplemented it. • Plug and Play Ecosystem
  59. 59. T H E E C O S Y S T E M • These modules are hosted on repositories centrally (or private versions if you have private code) • The big ones are bower (more client- side) and npm (more server-side) • (Think of NuGet, Maven Central)
  60. 60. B O W E R
  61. 61. B O W E R • Bower manages a central repository of JavaScript libraries • Bower manages a bower.json file in your codebase that teaches it what dependency you need. • Typically use the CLI • bower install -- save [moduleName]
  62. 62. I N T E R E S T I N G J AVA S C R I P T L I B R A R I E S E X A M P L E S O F
  63. 63. G R A P H I C S , C H A R T I N G A N D R E N D E R I N G • D3.js (& wrappers) • “Data-Driven Documents” i.e. styling the DOM conditionally on value • Wrapped by Chart.js, C3 and NVD3 to provide charting libraries
  64. 64. F O R M AT T I N G L I B R A R I E S • NumeralJS/Moment • Take raw strings and format them as dates or numbers using format strings (“DDMMYY” or “$0.00” • Provide lots of domain- specific methods
  65. 65. P R O M I S E S & F U N C T I O N S • Q • Adds promises to JavaScript, to get rid of callback hell. • Lodash • Provides lots of functional idioms for object and array manipulation
  66. 66. M O D U L E S W R I T E O U R C O D E I N
  67. 67. M O D U L A R I S AT I O N : W H AT A N D W H Y ? M O D U L A R J A VA S C R I P T
  68. 68. W H AT I S A M O D U L E ? A self-contained piece of code, that doesn’t expose internal dealings
  69. 69. H O W T O M A K E M O D U L E S • JavaScript has no in-built way of creating modules (yet!) so we have to do it ourself. • JavaScript design patterns has an example of how this could work…
  70. 70. T H E S A N D B O X PAT T E R N var module = function() { var foo = “private”; return { getVar: function() { return foo; }, setVar: function(newFoo) { foo = newFoo; } } }
  71. 71. B U T… • Don’t reinvent the wheel!
  72. 72. E S 2 0 1 5 I T ’ S C O M I N G N A T I V E …
  73. 73. B R O W S E R S U P P O R T F O R E S 2 0 1 5
  74. 74. R E Q U I R E J S M O D U L A R J A VA S C R I P T
  75. 75. R E Q U I R E . J S • Require.JS is a “module loader” framework • You define one or more “entry points” • Require.JS will encapsulate your modules by default, and allow you to define dependencies between the modules.
  76. 76. M O D U L E S C A N B E … • Your own code • or Third party libraries downloaded through (e.g.) Bower • Most will now support RequireJS and other module loaders by default.
  77. 77. D E F I N I N G A M O D U L E define([dependencies], function(depNames) { //stuff you want to keep “private” return module; })
  78. 78. D E F I N I N G A M O D U L E define([“lodash”], function(_) { var array = [1, 2, 3]; var addOne = function(x) { return x + 1; } return _.map(array, addOne); })
  79. 79. N O T J U S T J AVA S C R I P T F R O N T- E N D C O D E T H A T ’ S
  80. 80. W H Y D O N ’ T W E J U S T D U M P J AVA S C R I P T ?
  81. 81. W H Y D O N ’ T W E J U S T D U M P J AVA S C R I P T ? • The alternatives: • Flash • Java Applets • Server-side Rendering (JSPs, Razor) • For complex client interaction, JavaScript is the only option
  82. 82. J AVA C A S T Y O U R M I N D S T O
  83. 83. T H E J V M W R I T T E N J AVA J AVA B Y T E C O D E J V M ( “ J AVA V I RT U A L M A C H I N E ” ) U N I X W I N D O W S
  84. 84. T H E J V M W R I T T E N J AVA J AVA B Y T E C O D E J V M ( “ J AVA V I RT U A L M A C H I N E ” ) U N I X W I N D O W S G R O O V Y S C A L A
  85. 85. S O W H E N W E S E E T H I S PAT T E R N … J AVA S C R I P T J AVA S C R I P T R U N T I M E C H R O M E S A FA R I
  86. 86. … W E S TA R T T O T H I N K J AVA S C R I P T J AVA S C R I P T R U N T I M E C H R O M E S A FA R I “ C O M P I L E D T O J S ” L A N G U A G E S
  87. 87. C O M P I L E D T O J S L A N G U A G E S https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS Early Adopters: Different languages with to-JS compilers
  88. 88. T Y P E S C R I P T O U R W I N N E R …
  89. 89. T Y P E S C R I P T • Strongly typed • Adds missing features (e.g. classes, modules, package manager) • Strict superset of Javascript • Backwards compatible with other libraries due to Open Source type mappings
  90. 90. T Y P E S C R I P T class Node { labels:string[] = []; constructor() { } getLabels():string[] { return this.labels; } addLabel(label:string) { if(this.labels.indexOf(label) < 0) { this.labels.push(label); } } }
  91. 91. T E S T I N G A U T O M A T E D
  92. 92. W H Y T E S T C O D E ? T E S T I N G J A VA S C R I P T
  93. 93. W H Y T E S T ? • Reduce Regressions • Reduce bugs in new and old features
  94. 94. W H Y T E S T ? • Make code more maintainable • Aids understanding through documentation • Reduce the cost of change
  95. 95. W H Y T E S T ? • Improve Design • Untestable code is bad code • Forces you to think and plan
  96. 96. H O W T O T E S T Y O U R F R O N T- E N D ? • Functional testing with Selenium • Unit testing • Ideally both!
  97. 97. W E ’ R E G O I N G T O TA L K A B O U T U N I T T E S T I N G • But some great references to functional testing • https://code.google.com/p/ robotframework/wiki/ HowToWriteGoodTestCases • http://www.seleniumhq.org/docs/ 01_introducing_selenium.jsp • http://martinfowler.com/bliki/ PageObject.html • https://www.youtube.com/watch? v=FSWGVh5qJ4k
  98. 98. U N I T T E S T I N G J A VA S C R I P T T E S T I N G
  99. 99. W H AT I S A U N I T T E S T ? • Testing isolated parts of functionality • Allows you to test simple, small parts of the system • Significantly easier when modules are involved!
  100. 100. H O W D O W E D O T H I S I N J AVA S C R I P T ? • It can be hard • JavaScript testing isn’t as prevalent part of the native language as NUnit/JUnit are. • There are loads of libraries for it though.
  101. 101. T H E J AVA S C R I P T U N I T T E S T I N G L I F E C Y C L E • Writing a test • Creating any necessary test doubles • Making any relevant assertions • Running the tests
  102. 102. W R I T I N G A T E S T • We don’t have classes any more, so tests are nested functions. • JS test frameworks encourage a full “BDD” style test description: • describe what unit your testing, and • say what it should do
  103. 103. M O C H A describe('Array', function() { describe('#indexOf()', function () { it('should return -1 if value isn’t present', function () { assert.equal(-1, [1,2,3].indexOf(5)); assert.equal(-1, [1,2,3].indexOf(0)); }); }); });
  104. 104. M O C H A • Mocha is a lightweight test framework • ‘describe’ and ‘it’ callbacks to get nicely rendered test suites • Basic assertions • Before/After hooks • Support for asynchronous tests
  105. 105. T E S T D O U B L E S I N J AVA S C R I P T T E S T I N G J A VA S C R I P T
  106. 106. W H AT I S A T E S T D O U B L E ? • When unit testing, a way to isolate dependencies using a simplified object under your control
  107. 107. W H AT I S A T E S T D O U B L E ? • Stub - source of controlled data • Mock - set up to acted on as expected • Spy - Record information and respond to questions • Dummy - based around but not used • Fake - Mostly working, with dangerous or complex logic stripped out
  108. 108. D I Y T E S T D O U B L E S var stubGateway = { save: function() { return [1, 2, 3]; } } describe(“The Data User”, function() { it(“should give you the data count”, function() { var dataUser = dataUser(stubGateway); assert.equal(dataUser.dataCount.length, 2); }) })
  109. 109. T H I S I S E A S I E R I N J AVA S C R I P T • Dynamic typing means we don’t need any overcomplicated interfaces or types • But libraries do exist for more complex use cases.
  110. 110. T E S T D O U B L E S W I T H S I M O N describe(“The Data User”, function() { it(“should give you the data count”, function() { var spyCallback = sinon.spy(); var dataUser = dataUser(spyCallback); dataUser.saveData(); assert(spyCallback.calledOnce); }) })
  111. 111. A S S E R T I O N S • Often, default assertion libraries are harder to read and limited in functionality • There’s a JS library for that!
  112. 112. C H A I tea.should.have.property('flavors') .with.length(3); doc.should.be.an(‘object'); expect(answer, 'topic [answer]’) .to.equal(42); assert.lengthOf(foo, 3, ‘foo should has a length of 3');
  113. 113. T E S T R U N N E R S • The tests need to be run somewhere • Either in a browser or on a client-side “JavaScript runtime” (typically Node.js)
  114. 114. T E S T R U N N E R S • Third party ‘test runners’ exist to manage this process for you and give you nice outputs. • Karma is a stable, well- supported runner • Wallaby.JS integrates with your IDE to provide in-line coverage and continuous test running.
  115. 115. B U I L D I N G Y O U R C O D E W H E N I T C O M E S T O
  116. 116. W H AT W E ’ V E TA L K E D A B O U T S O FA R • Third party libraries • Modules • Languages that compile to JavaScript • Testing
  117. 117. W H AT W E ’ V E TA L K E D A B O U T S O FA R • These all require external processes to the JavaScript • It’s no longer good enough to just statically serve files
  118. 118. B U I L D T O O L S • We need build tools to ensure that any steps are run in an automated and deterministic manner
  119. 119. O T H E R B U I L D T O O L S
  120. 120. W H AT T H E Y D O • Automate necessary build steps • Compile Code • Fetch Dependencies • Run Tests • Produce Executables
  121. 121. T H E J AVA S C R I P T B U I L D T O O L S • Like everything else, there’s loads out there at the moment • We favour the relative maturity of Grunt
  122. 122. G R U N T • Grunt stores its config in a “Gruntfile” (think .csproj or pom.xml) • These contain its dependencies and descriptions of the processes you may want it to run • Most of what it can do is third party
  123. 123. G R U N T • Can be made to run from other build tools (inc. MSBuild and Maven) • This means you only have to “build” your project once to have it run.
  124. 124. E X A M P L E O F A G R U N T F I L E module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
  125. 125. E X A M P L E O F A G R U N T F I L E module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
  126. 126. E X A M P L E O F A G R U N T F I L E module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
  127. 127. E X A M P L E O F A G R U N T F I L E module.exports = function(grunt) { grunt.initConfig({ jshint: { files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'], options: { globals: { jQuery: true } } }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['jshint']); };
  128. 128. G R U N T TA S K S grunt.loadNpmTasks('grunt-karma'); grunt.initConfic({ karma: { unit: { configFile: 'karma.conf.js' } } }); grunt.registerTask('test', [‘jshint’, ’karma’]);
  129. 129. G R U N T ’ S P L U G I N A R C H I T E C T U R E
  130. 130. S A M P L E P L U G I N S • Test runners for all major testing ecosystems • Compilers for most third party libraries • Test Coverage (with Istanbul) • Pre-compilers for SASS/LESS • Rerun tasks when certain “watched” files are changed
  131. 131. G L U E I T T O G E T H E R A N D N O W W E
  132. 132. W H Y W R I T E F R O N T- E N D C O D E ?
  133. 133. S E R V E R - S I D E C O D E I S A R E A L O P T I O N • Razor for .NET and JSPs/ Thymeleaf for Java • Keep all logic in the server- side, and only send rendered content
  134. 134. B U T F O R S O M E P R O B L E M S … • Can be very slow, since all computation must be done before sending the response • Forces a page refresh every time new data appears • Limits ways clients can interact
  135. 135. J Q U E RY
  136. 136. J Q U E RY I S G O O D F O R S O M E T H I N G S • DOM Manipulation • Ajax Requests • Very specific visual/UI concerns
  137. 137. B U T I T ’ S B L O AT E D • Early JavaScript was hard to maintain and add to, so most libraries bootstrapped ‘$’. • It contained everything, and people assumed jQuery was native JS.
  138. 138. A N D M I X E S C O N C E R N • jQuery had visual/DOM manipulation and data processing libraries • Everyone forgot their clean code principles
  139. 139. S O W H AT D O W E D O W I T H J Q U E RY ? • Use it for DOM manipulation and Ajax requests… • … but encapsulate these parts to provide better structure to your code.
  140. 140. T H E R E ’ S P L U G I N S F O R T H AT ! E N C A P S U L A T I N G U I S H A P I N G C O D E ?
  141. 141. T H E M V * PAT T E R N • Separate the concerns of getting and storing the data (model) with how this affects the visual aspects of the page • Like the MVC pattern in web servers.
  142. 142. E X A M P L E S : K N O C K O U T J S • “MVVM” - model-view- view model var viewModel = { age: ko.observable(12) } <input data-bind=”value: age” /> ko.applyBindings(viewModel)
  143. 143. E X A M P L E S : A N G U L A R J S • “MVW” - model-view- whatever function controller($scope) { $scope.names = [‘Sally’, ‘Sam’] } <div ng-controller=”controller”> <ul> <li ng-repeat="name in names"> {{ name }} </li> </ul> </div>
  144. 144. M V * F R A M E W O R K S • There are loads of good client-side frameworks to use - Ember, Backbone as well as others. • They all have a common purpose in separating the concerns of the data and displaying it
  145. 145. W H I C H F R A M E W O R K S H O U L D I U S E ?
  146. 146. W H I C H F R A M E W O R K S H O U L D I U S E ? • Our experience is focused on the relative maturity of KnockoutJS and AngularJS. • We’re keeping our eye on React and Ember
  147. 147. A N G U L A R J S V S . K N O C K O U T • Set-Up Costs: Knockout • Browser Support: Knockout • Community Support: Angular • Ease of Learning: Knockout • Testability: Angular • Features: Angular http://www.softwire.com/blog/2015/ 09/15/angularjs-vs-knockoutjs-part-3/
  148. 148. T L ; D R • We like AngularJS on larger greenfield projects where up-front costs will pay dividends • The small size of KnockoutJS makes it better to start migrating legacy projects, and on small projects.
  149. 149. R E C A P 1 2 3 4 Many of JS’s failings are solved by discipline, libraries or using higher-level languages Modules organise code and exist in ES2015+, TypeScript and third party libraries JavaScript should be tested, and frameworks (Mocha, Jasmine…) exist to make this painless UI-shaping code should be encapsulated with MV* frameworks (Knockout, Angular)
  150. 150. W H AT D O I D O N OW ?
  151. 151. G R E E N F I E L D P R O J E C T… S O I ’ M O N A
  152. 152. A R C H I T E C T Y O U R F R O N T- E N D C O D E
  153. 153. A R C H I T E C T Y O U R F R O N T- E N D C O D E • Don’t abandon ‘evolving design’ but do future proof your architecture • Plan the libraries and frameworks you’ll use • Structure your application • Encapsulate concerns
  154. 154. O U R I D E A L F R O N T- E N D T E C H S TA C K
  155. 155. A P R O V I S O • Every project is different • This is what we think in the abstract, but a range of different project concerns may change your mind.
  156. 156. L A N G U A G E • TypeScript • Built-in module system and package manager • Strongly typed • Can use JS’s significant ecosystem with types
  157. 157. B U I L D T O O L • Grunt • Compiles and minimises TypeScript • Will run tests and provide coverage
  158. 158. T E S T I N G E C O S Y S T E M • Mocha, for the framework • Chai for assertions • Sinon (if needed) for mocking/stubbing • Karma to run tests, plus WallabyJS for in-IDE coverage.
  159. 159. M V * F R A M E W O R K S • AngularJS for projects that will run for a while • KnockoutJS for smaller or less complex projects
  160. 160. M I G R AT I N G L E G A C Y J AVA S C R I P T I ’ M S T U C K …
  161. 161. O N L E G A C Y C O D E • It’s rarely feasible or cost- effective to do everything in one big go. • So we present some tactical “quick wins”
  162. 162. B O Y S C O U T R U L E • “Leave the codebase cleaner than how you found it.” • Migrate away from old or bad language features, and towards third party libraries and functional paradigms where possible
  163. 163. A D D A B U I L D T O O L • Early on it will provide little value, but is also cheap • But doing this early maximises the value of other changes… • … and prevents a costly big migration in the future.
  164. 164. M I G R AT E T O M O D U L E S G R A D U A L LY • Modularisation will significantly improve your code’s maintainability and reuse. • Add Require.js • Whenever you work on a piece of functionality in the ‘ball of mud’, extract it.
  165. 165. T E S T I N G • Once modularised, unit tests can be added. • These are often hard to write due to the lack of testing in mind • Functional Selenium tests can test the underlying user journeys to guard against regressions.
  166. 166. A D D K N O C K O U T • Knockout can be migrated to gradually, without requiring significant up- front investment. • Best targeted tactically at any place with significant DOM manipulation based on data.
  167. 167. W H AT W E D O N ’ T R E C O M M E N D • Quarantining the old ‘bad’ code and starting from scratch moving forward • Prohibits code re-use • JS has a nasty habit of using global variables or randomly changing things • Leads to poor understanding and no ownership of the old code.
  168. 168. W H AT W E D O N ’ T R E C O M M E N D • Attempting to adopt codebase-shaping frameworks in an incremental manner (where there are smaller alternatives) • AngularJS • TypeScript
  169. 169. R E C A P 1 2 3 Your front-end code should be a first-class consideration of any architecture We recommend a stack of TypeScript, Grunt, Mocha, Chai, Karma and an MV* package There are tactical steps you can make to migrate legacy JS - it’s not “all or nothing”.
  170. 170. T O R EC A P
  171. 171. T H E PA S T 1 2 3 JavaScript is the only (modern) language that can be run on browsers Due to historical context, it’s unpleasant to work with and lacking in modern features These problems significantly impact the cost, quality and timescales of a project.
  172. 172. T H E P R E S E N T 1 2 3 4 Many of the failings are solved by discipline, libraries or using higher-level languages Modules organise code and exist in ES2015+, TypeScript and third party libraries JavaScript should be tested, and frameworks (Mocha, Jasmine…) exist to make this painless Integrating with HTML should be encapsulated with MV* frameworks
  173. 173. T H E F U T U R E 1 2 3 Your front-end code should be a first-class consideration of any architecture We recommend a stack of TypeScript, Grunt, Mocha, Chai, Karma and an MV* package There are tactical steps you can make to migrate legacy JS - it’s not “all or nothing”.
  174. 174. Questions? @SwamWithTurtles David Simons, Softwire

×