Upgrade to Pro — share decks privately, control downloads, hide ads and more …

브런치 FE 심폐소생술

kakao
PRO
December 08, 2022

브런치 FE 심폐소생술

#레거시 #Test #리팩토링

브런치 FE 신입개발자의 현업 적응기를 통해, FE 레거시 개선에 대한 경험을 공유 하고 자 합니다.

발표자 : edward.kk
카카오 FE플랫폼팀에서 브런치를 담당하고 있는 에드워드 입니다.

lucas.ms
카카오 FE플랫폼팀에서 브런치를 담당하고 있는 루카스 입니다.

kakao
PRO

December 08, 2022
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. (feat. 신입 개발자의 우당탕탕 현업 적응기)
    Copyright 2022. Kakao Corp. All rights reserved. Redistribution or public display is not permitted without written permission from Kakao.
    브런치 FE 심폐소생술
    edward.kk lucas.ms


    카카오
    if(kakao)2022

    View Slide

  2. 브런치 서비스 소개
    브런치 (brunch.co.kr)


    글쓰기 플랫폼


    베스트셀러 제조기

    View Slide

  3. 신입 개발자가 119 부른 썰


    심폐소생술 시행


    차근 차근 재활치료


    세션 마무리

    View Slide

  4. 신입 개발자가 119 부른 썰


    심폐소생술 시행


    차근 차근 재활치료


    세션 마무리

    View Slide

  5. 신입 개발자가 119 부른 썰
    브런치 FE 담당자가 되다.

    View Slide

  6. 신입 개발자가 119 부른 썰
    브런치 FE 담당자가 되다.


    브런치 FE 탐방하다.

    View Slide

  7. 브런치 FE 탐방하다.
    코드에 담긴 간절한 기도 주문



    View Slide

  8. 브런치 FE 탐방하다.
    코드에 담긴 간절한 기도 주문



    2015년에 작성된 TODO 주석



    View Slide

  9. 브런치 프로파일
    브런치 FE 탐방하다.
    이름 브런치 FE
    출생일 2014
    사용 언어 ES3
    취미 Jquery
    즐겨 읽는 책 Spring (Velocity, Handlebars)
    좋아하는 음식 Grunt
    특이 사항 서버와 함께 같은 집에서 동거 중

    View Slide

  10. 신입 개발자가 119 부른 썰
    브런치 FE 담당자가 되다.


    브런치 FE 탐방하다.


    브런치 운영 이슈를 만나다.

    View Slide

  11. 브런치 운영 이슈를 만나다.
    사용자 행동 수집 오류 대응


    모바일 UI 미리보기 개선


    댓글 입력 오류 대응

    View Slide

  12. 브런치 운영 이슈를 만나다.
    사용자 행동 수집 오류 대응


    모바일 UI 미리보기 개선


    댓글 입력 오류 대응

    View Slide

  13. 사용자 행동 수집 오류 대응
    '티아라' 히스토리에 대해 아시는분 있을까요?

    View Slide

  14. 사용자 행동 수집 오류 대응
    ES3, prototype, jQuery 에 의존


    - JS 파일 간 Import , Export 불가
    window.B.Util = {


    setOnError: function () {...}


    ajax: function (options) {...}


    //...


    }
    var AbstractObject = function () {...};


    AbstractObject.prototype = {...}


    var Top = function () {


    //...


    }.inherit(AbstractObject);

    View Slide

  15. 사용자 행동 수집 오류 대응
    window.B.Util = {


    setOnError: function () {...}


    ajax: function (options) {...}


    //...


    }
    ES3, prototype, jQuery 에 의존

    View Slide

  16. 사용자 행동 수집 오류 대응
    window.B.Util = {


    setOnError: function () {...}


    ajax: function (options) {...}


    //...


    }

    B.Util.ajax({


    type: 'GET',


    //...


    })
    ES3, prototype, jQuery 에 의존

    View Slide

  17. 사용자 행동 수집 오류 대응
    거대한 전역 객체 window.B


    - 1000개 이상 x.prototype.x 모듈

    View Slide

  18. 브런치 운영 이슈를 만나다.
    사용자 행동 수집 오류 대응


    모바일 UI 미리보기 개선


    댓글 입력 오류 대응

    View Slide

  19. 모바일 UI 미리보기 개선

    View Slide

  20. 모바일 UI 미리보기 개선
    babel: {


    //...


    dist: {


    files: {


    "src/main/webapp/WEB-INF/static/js/transpiled/B.Brunchbook.DND2.js":


    "src/main/webapp/WEB-INF/static/js/B.Brunchbook.DND2.es6.js",


    }


    }


    }


    uglify: {


    //...


    build: {


    files: {


    "src/main/webapp/WEB-INF/static/product/B.Brunchbook.Preview.min.js": [


    "src/main/webapp/WEB-INF/static/js/transpiled/B.Brunchbook.DND2.js",


    “src/main/webapp/WEB-INF/static/js/B.Brunchbook.Preview.js",


    ],


    }


    }


    }


    handlebars: {


    //...


    compile: {


    files: {


    "src/main/webapp/WEB-INF/static/product/B.Article.Template.js": [


    "src/main/webapp/WEB-INF/handlebars/article*.hbs",


    ],


    }


    }


    }
    빌드 시스템 — Grunt


    - 개발환경에 따른 번들 경로 분기


    - 복잡한 빌드 설정

    View Slide

  21. 모바일 UI 미리보기 개선
    if 위 아래에 statement이 있으면 공백 라인이 추가되면 좋겠습니다.


    if 뒤에 space 한칸씩 넣어 주시면 좋을 것 같습니다.


    이게 vm 이라서 포멧팅이 잘 안되더라구요..


    indent가 다른 곳과 달라 보입니다.


    일관성있게 아래와 같이 변경되는 것이 좋을 것 같습니다.


    아래와 같이 공백 부탁드립니다.


    ...


    코드 리뷰


    - 코드에 일관된 lint 설정이 적용되어 있지 않음


    - 지저분한
    fi
    les changed


    - 리뷰시 수시로 코드의 컨벤션에 대한 충돌이 발생

    View Slide

  22. 브런치 운영 이슈를 만나다.
    사용자 행동 수집 오류 대응


    모바일 UI 미리보기 개선


    댓글 입력 오류 대응

    View Slide

  23. 댓글 입력 오류 대응

    View Slide

  24. 댓글 입력 오류 대응
    이거 뭐.. 3시간이면 되지않을까?

    View Slide

  25. 댓글 입력 오류 대응
    - 1400 줄 코드라인

    View Slide

  26. 댓글 입력 오류 대응
    - 1400 줄 코드라인


    - init 콜벡 지옥, props drilling
    comment
    -
    editor-1.0.js
    var Mentions = function (..., callback) {...}


    var Editor = function (..., options) {


    var _mentions = null;


    var initMentions = function () {


    _mentions = Mentions(mentions, addMentionView);


    };


    var init = function () {


    initMentions(options.floatMention)


    };


    init();


    return {...}


    };


    $.fn.editor = function (options) {


    var editor = new Editor(this, options));


    ...


    };


    View Slide

  27. 댓글 입력 오류 대응
    - 1400 줄 코드라인


    - init 콜벡 지옥, props drilling
    comment
    -
    editor-1.0.js
    var Mentions = function (..., callback) {...}


    var Editor = function (..., options) {


    var _mentions = null;


    var initMentions = function () {


    _mentions = Mentions(mentions, addMentionView);


    };


    var init = function () {


    initMentions(options.floatMention)


    };


    init();


    return {...}


    };


    $.fn.editor = function (options) {


    var editor = new Editor(this, options));


    ...


    };


    View Slide

  28. 댓글 입력 오류 대응
    - 1400 줄 코드라인


    - init 콜벡 지옥, props drilling


    - 심상치않은 entry
    comment
    -
    editor-1.0.js
    var CommentForm = function (options) {


    _editor = $view.find('.editor').editor({...});


    };
    var Editor = function (field, options) {...}


    $.fn.editor = function (options) {


    var editor = new Editor(this, options));


    return $.data(this[0], 'editor', editor);


    };
    B.Comment.js

    View Slide

  29. 댓글 입력 오류 대응
    - 1400 줄 코드라인


    View Slide

  30. 비상!!!!!!!!!

    View Slide

  31. 앞으로의 대응 이런 식으로 할 순 없다!

    View Slide

  32. 신입 개발자가 119 부른 썰
    브런치 FE 담당자가 되다.


    브런치 FE 탐방하다.


    브런치 운영 이슈를 만나다.


    119를 부르다.

    View Slide

  33. 119를 부르다.
    사용자 행동 수집 오류 대응


    ->
    코드 히스토리 부재


    ->
    오래된 개발환경
    모바일 UI 미리보기 개선


    ->
    복잡한 빌드 시스템


    ->
    코드 컨벤션
    댓글 입력 오류 대응


    ->
    구조화 되지 않은 코드


    ->
    Side Effect

    View Slide

  34. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제
    119를 부르다.
    구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  35. 신입 개발자가 119 부른 썰


    심폐소생술 시행


    차근 차근 재활치료


    세션 마무리

    View Slide

  36. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제
    진단서 평가
    구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  37. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  38. 빌드 시스템 개선
    ->
    Webpack 전환
    - es6 작성 환경 구성


    - 빌드 설정 개선


    - 최신 테스트/모니터링/린트 도구 도입을 위한 환경 구성


    View Slide

  39. 빌드 시스템 개선


    수동 테스트

    View Slide

  40. Webpack 전환 사이드 이펙트 해결 사례
    Webpack 적용 전

    View Slide

  41. Webpack 전환 사이드 이펙트 해결 사례
    Webpack 적용 후

    View Slide

  42. Webpack 전환 사이드 이펙트 해결 사례

    View Slide

  43. Webpack 전환 사이드 이펙트 해결 사례
    Jest Snapshot Test 결과

    View Slide

  44. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  45. 오래된 개발환경
    ->
    Import / Export 도입
    Import Export
    export default class EntryBanner {}


    export default class GuiderBrunchbook {}


    export default class LinkTop {}


    export default class PublisherFlickLineupList {}


    export default class PublisherToggleLineupList{}


    export default class CategoryFilter {}


    import { BrunchLocalStorage, DOM } from ‘@utils';


    import axiosInstance from '@utils/axios';


    import { NOW_SELECTOR } from './NowConstants';


    import NowLocalStorage from './NowLocalStorage';


    import NowLogic from './NowLogic';


    import NowRender from './NowRender';


    View Slide

  46. 오래된 개발환경
    ->
    기능 단위 모듈 구조 도입
    페이지 단위 JS 신규 디렉토리 구조

    View Slide

  47. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  48. 구조화 되지않은 코드
    ->
    page class 컨벤션
    Logic
    Page Render
    페이지의 상태 /DOM 이벤트 순수한 로직 순수한 렌더링 기능 구현

    View Slide

  49. // velocity ղࠗ ࢶ঱ ߂ ୡӝച


    #loadWebpackJs("now.min.js")


    <br/><br/><br/>try {<br/><br/><br/>InitApp();<br/><br/><br/>} catch(e) {<br/><br/><br/>console.log(e);<br/><br/><br/>Sentry.setTag('InitFail', 'Now');<br/><br/><br/>Sentry.captureMessage('[BRUNCH] InitFail');<br/><br/><br/>}<br/><br/><br/>


    구조화 되지않은 코드
    ->
    page class 컨벤션
    // Page Class


    export default class NowPage {


    init () {...}


    initEvent () {...}


    }


    // Logic Class


    export default class NowLogic {


    static transferToNowList = (data) => {...}


    }


    // Render Class


    export default class NowRender {


    static renderList = (list) => {...}


    };


    // ୡӝച ࢶ঱


    (() => {


    window.InitApp = () => {


    const Page = new NowPage();


    Page.init();


    };


    });


    View Slide

  50. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제
    심폐 소생술 결과
    구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  51. ES6
    Webpack
    Modern 개발 환경 구성 모듈화
    Convention
    구조화
    심폐 소생술 결과

    View Slide

  52. 심폐 소생술 결과
    Before After
    모듈화 수준 낮음 (페이지 단위 ) 높음 (기능 단위)
    구조화 수준 낮음 (전역객체 활용) 높음 (Class 기반 모듈)
    빌드시스템 Grunt Webpack

    View Slide

  53. 신입 개발자가 119 부른 썰


    심폐소생술 시행


    차근 차근 재활치료


    세션 마무리

    View Slide

  54. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  55. Side Effect 발생
    사내모니터링 툴
    ->

    ‘B’ 이(가) 정의 되지 않았습니다.


    Cannot read properties of unde
    fi
    ned (reading ‘init')


    제보
    ->


    에디터에서 글 작성 시 이상이 있어요.


    댓글 작성시 멘션 동작이 이상해요.


    View Slide

  56. Side Effect 발생
    ->
    Cypress / Jest 도입
    Cypress Jest

    View Slide

  57. Logic
    Page Render
    Cypress E2E Test Jest Unit Test Jest Snapshot Test
    Side Effect 발생
    ->
    Cypress / Jest 도입

    View Slide

  58. Side Effect 발생
    ->
    모니터링 툴 개선
    카카오 사내 모니터링 툴 사용


    ->
    설치만 되어 있고 실제 유의미한 데이터를 찾을 수
    없는 상황


    ->
    알림 조건 , 알림 전송 시스템 X


    ->
    데이터 필터링 & 자주 발생 하는 오류에 대한 대응 작업


    ->
    메시지 별 알림 조건 추가 , 알림 전송 시스템, 알림 대응
    프로세스 정립


    ->
    주기적인 모니터링으로 에디터 / 댓글 페이지 등에서
    발견되는 사용자 오류 모니터링


    View Slide

  59. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  60. 코드 컨벤션 토론
    ->
    Brunch Javascript Style Guide
    카카오 사내 스타일 가이드 기반 브런치 FE 코딩 컨벤션 수립
    files: [


    '**/modernJs/**/*.js',


    '**/test/**/*.js',


    '**/webpack/*.js',


    '.eslintrc.js',


    '*.config.js',


    ],


    env: {


    es6: true,


    },


    extends: [


    '@kos/styleguide/comment',


    '@kos/styleguide/es3',


    '@kos/styleguide/es2015',


    ],


    …commonRule,


    semi: ['error', 'always'],


    'no-multi-assign': 'error',


    'one-var': ['error', 'never'],


    'block-spacing': ['error',
    'always'],


    'comma-spacing': [


    'error', {


    before: false,


    after: true,


    },


    ],


    'eol-last': ['error',
    'always'],


    'func-call-spacing':


    ['error', 'never'],


    'key-spacing': [


    'error', {


    beforeColon: false,


    afterColon: true,


    },


    ],


    View Slide

  61. == 연산자 === 연산자로 변환
    레거시 코드에 Eslint 적용 사이드 이펙트 사례

    View Slide

  62. 기존 코드 변경된 코드
    레거시 코드에 Eslint 적용 사이드 이펙트 사례
    null == unde
    fi
    ned null !== unde
    fi
    ned
    result != null result !== null

    View Slide

  63. Eslint 분기 적용
    기존 코드 신규 코드
    files: [


    'src/main/webapp/WEB-INF/static/**/
    *.js',


    ],


    excludedFiles: [


    '**/modernJs/**/*.js',


    '**/test/**/*.js',


    '**/*.min.js',


    '**/production/**/*.js',


    ],


    rules: {…}
    files: [


    '**/modernJs/**/*.js',


    '**/test/**/*.js',


    '**/webpack/*.js',


    '.eslintrc.js',


    '*.config.js',


    ],


    env: {


    es6: true,


    },


    rules: {…}


    View Slide

  64. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제 구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  65. 코드의 히스토리 부재
    ->
    히스토리 남기기
    작업 내용 문서화

    View Slide

  66. 코드의 히스토리 부재
    ->
    히스토리 남기기
    의미 있는 코드 작성하기
    /* ਊয ੿ܻ */


    // more: ੉࢚


    // less: ੉ೞ


    // greater: ୡҗ


    // under: ޷݅
    function isRemainGuideLine () {


    return Boolean(...)


    }
    var originalUrl // Bad


    var originalUrlWithoutScheme // Good

    View Slide

  67. 오래된 개발환경
    코드 히스토리 부재
    빌드 시스템 문제
    재활치료 결과
    구조화 되지 않은 코드
    Side Effect 코드 컨벤션

    View Slide

  68. Lint
    Test Code
    E2E, Unit, Snapshot 카카오 + 브런치 룰
    History
    코드의 의미 기록
    재활치료 결과

    View Slide

  69. 재활치료 결과
    Before After
    코드 히스토리 적음 많음
    코드컨벤션 InteillJ 자체 설정 Eslint
    Test 코드 Qunit Cypress, Jest , Jest snapshot
    모니터링 활용 X O

    View Slide

  70. 신입 개발자가 119 부른 썰


    심폐소생술 시행


    차근 차근 재활치료


    세션 마무리

    View Slide

  71. Before / After
    Before After
    코드 히스토리 적음 많음
    모듈화 수준 낮음 (페이지 단위 ) 높음 (기능 단위)
    구조화 수준 낮음 (전역객체 활용) 높음 (Class 기반 모듈)
    빌드시스템 Grunt Webpack
    코드컨벤션 InteillJ 자체 설정 Eslint
    Test 코드 Qunit Cypress, Jest , Jest snapshot
    모니터링 활용 X O

    View Slide

  72. 디자인패턴


    - MVC , MVI 등의 도입을 검토를 위한 프로토타이핑


    상태관리


    - 기존의 B.x 전역객체의 정보를 관리 하기 위한 vanillaJs 상태 관리


    점진적 리팩토링


    - 신규 프로젝트 / 개편 페이지 대상으로 점진적 리팩토링 진행 중
    브런치FE의 Next Item

    View Slide

  73. 주기적 테스트 실행을 통한 안정성 향상


    - Jenkins , Docker를 활용한 전체 테스트 자동 실행 및 리포팅 기능 개발 중
    테스트 자동화

    View Slide

  74. E.O.D

    View Slide