refactoring the disaster no one is talking about
play

Refactoring the Disaster No One Is Talking About - PowerPoint PPT Presentation

@ petetasker @ptasker Refactoring the Disaster No One Is Talking About deliciousbrains.com/loopconf How We're Handling JavaScript Tech Debt in WP Migrate DB Pro @ petetasker @ptasker ABOUT ME WP Migrate DB Pro developer Canadian, Eh!


  1. @ petetasker @ptasker Refactoring the Disaster No One Is Talking About deliciousbrains.com/loopconf

  2. How We're Handling JavaScript Tech Debt in WP Migrate DB Pro

  3. @ petetasker @ptasker ABOUT ME • WP Migrate DB Pro developer Canadian, Eh! 🍂 • First conference talk 😲 •

  4. WP Migrate DB Pro

  5. Outline: • What is technical debt? • Symptoms • Understand the code • Get your test on! • Refactor

  6. What disaster 🔦 ?

  7. What is tech debt? Easy > Better™

  8. $('.migrate-db-button').click(function (event) { doing_ajax = true; $.ajax({ success: function (data) { doing_ajax = false; wpmdb.functions.long_func = function () { doing_ajax = true; $.ajax({ // ... }); }; } }); // end ajax });

  9. $('.migrate-db-button').click(function (event) { doing_ajax = true; $.ajax({ success: function (data) { doing_ajax = false; wpmdb.functions.long_func = function () { doing_ajax = true; $.ajax({ // ... }); }; } }); // end ajax });

  10. $('.migrate-db-button').click(function (event) { doing_ajax = true; $.ajax({ success: function (data) { doing_ajax = false; wpmdb.functions.long_func = function () { doing_ajax = true; $.ajax({ // ... }); }; } }); // end ajax });

  11. How does this happen?

  12. Symptoms • Long functions, deeply nested code • The “the only one who can ever change this code is Pete 😭 ” e fg ect • Global variables and functions 


  13. 💩

  14. Understanding the code 🤕

  15. Get your test on 💼

  16. To get this…

  17. Requires this… You need this…

  18. const findText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).value; }, '#old-url' ); expect( findText ).to.be.equal( `//${process.env.REMOTE_SITE}` ); await page.waitFor( '[value=Pull]' ); await page.click( '[value=Pull]' ); const successText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).innerHTML; }, '.progress-title' ); //Check header for string expect( successText ).to.include( process.env.REMOTE_SITE );

  19. const findText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).value; }, '#old-url' ); expect( findText ).to.be.equal( `//${process.env.REMOTE_SITE}` ); await page.waitFor( '[value=Pull]' ); await page.click( '[value=Pull]' ); const successText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).innerHTML; }, '.progress-title' ); //Check header for string expect( successText ).to.include( process.env.REMOTE_SITE );

  20. const findText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).value; }, '#old-url' ); expect( findText ).to.be.equal( `//${process.env.REMOTE_SITE}` ); await page.waitFor( '[value=Pull]' ); await page.click( '[value=Pull]' ); const successText = await page.evaluate( ( sel ) => { return document.querySelector( sel ).innerHTML; }, '.progress-title' ); //Check header for string expect( successText ).to.include( process.env.REMOTE_SITE );

  21. Refactor • Globals and ‘this’ • Code splitting • ‘New JS™’

  22. dev.to

  23. function wpmdb_call_next_hook( ) { const wpmdb = window.wpmdb; if ( !wpmdb.common.call_stack.length ) { wpmdb.common.call_stack = wpmdb.common.hooks; } var func = wpmdb.common.call_stack[ 0 ]; wpmdb.common.call_stack.shift(); func.call( this ); } Window {}

  24. // ‘use strict’ function wpmdb_call_next_hook( ) { const wpmdb = window.wpmdb; if ( !wpmdb.common.call_stack.length ) { wpmdb.common.call_stack = wpmdb.common.hooks; } var func = wpmdb.common.call_stack[ 0 ]; wpmdb.common.call_stack.shift(); func.call( this ); } undefined

  25. // ‘use strict’ function wpmdb_call_next_hook( ) { const wpmdb = window.wpmdb; if ( !wpmdb.common.call_stack.length ) { wpmdb.common.call_stack = wpmdb.common.hooks; } var func = wpmdb.common.call_stack[ 0 ]; wpmdb.common.call_stack.shift(); func.call( this ); } window.wpmdb_call_next_hook(); Window {}

  26. Code Splitting (or why I ❤ Webpack)

  27. /** * Wrapper for wpmdb.functions, assigned in Webpack entry file */ export default class WPMDBCommon { constructor() {} // Previously wpmdb.functions.wpmdb_migration_type() wpmdb_toggle_migration_action_text() { // ... } // ... }

  28. import WPMDBCommon from './src/js/helpers/wpmdbCommon'; // window.wpmdb.functions = {…} wpmdb.functions = new WPMDBCommon(); function importAll( r ) { r.keys().forEach( function( file ) { if ( !file.includes( 'wpmdbCommon.js' ) ) { r( file ); } } ); } importAll( require.context( 'imports-loader?$=>window.jQuery!./src', true, /^(.*\.(js|sass|scss$))/im ) );

  29. import WPMDBCommon from './src/js/helpers/wpmdbCommon'; // window.wpmdb.functions = {…} wpmdb.functions = new WPMDBCommon(); function importAll( r ) { r.keys().forEach( function( file ) { if ( !file.includes( 'wpmdbCommon.js' ) ) { r( file ); } } ); } importAll( require.context( 'imports-loader?$=>window.jQuery!./src', true, /^(.*\.(js|sass|scss$))/im ) );

  30. import WPMDBCommon from './src/js/helpers/wpmdbCommon'; // window.wpmdb.functions = {…} wpmdb.functions = new WPMDBCommon(); function importAll( r ) { r.keys().forEach( function( file ) { if ( !file.includes( 'wpmdbCommon.js' ) ) { r( file ); } } ); } importAll( require.context( 'imports-loader?$=>window.jQuery!./src', true, /^(.*\.(js|sass|scss$))/im ) );

  31. import WPMDBCommon from './src/js/helpers/wpmdbCommon'; // window.wpmdb.functions = {…} wpmdb.functions = new WPMDBCommon(); function importAll( r ) { r.keys().forEach( function( file ) { if ( !file.includes( 'wpmdbCommon.js' ) ) { r( file ); } } ); } importAll( require.context( 'imports-loader?$=>window.jQuery!./src', true, /^(.*\.(js|sass|scss$))/im ) );

  32. ‘New JS™’ 😄

  33. // Before $( $table_select ).append( '<option' + selected + 'value="' + table + '">' + table + size + '</option>' ); // After $( $table_select ).append( `<option ${selected} value="${table}"> ${table + size} </option>` );

  34. async recursiveTransferFiles( stage, status = null, batch_count = 10 ) { let response; try { response = await $.ajax( { // ... } ); const parsed_response = JSON.parse( response ); // Do stuff with response } catch ( error ) { // … } }

  35. async recursiveTransferFiles( stage, status = null, batch_count = 10 ) { let response; try { response = await $.ajax( { // ... } ); const parsed_response = JSON.parse( response ); // Do stuff with response } catch ( error ) { // … } }

  36. async recursiveTransferFiles( stage, status = null, batch_count = 10 ) { let response; try { response = await $.ajax( { // ... } ); const parsed_response = JSON.parse( response ); // Do stuff with response } catch ( error ) { // … } }

  37. async recursiveTransferFiles( stage, status = null, batch_count = 10 ) { let response; try { response = await $.ajax( { // ... } ); const parsed_response = JSON.parse( response ); // Do stuff with response } catch ( error ) { // … } }

  38. async recursiveTransferFiles( stage, status = null, batch_count = 10 ) { let response; try { response = await $.ajax( { // ... } ); const parsed_response = JSON.parse( response ); // Do stuff with response } catch ( error ) { // … } }

  39. Remember: • Understand the code • Get your test on! • Refactor Globals • Code splitting • ‘New JS™’ •

  40. @ petetasker @ptasker That’s all folks deliciousbrains.com/loopconf

Recommend


More recommend