ezinc 가이드 문서
Search posts...
  • Home

Categories

  • All Posts13
  • 클립리포트5
  • Ezworks3
  • Git2
  • 문서 작성 가이드3
Ezworks•2026년 4월 28일

팀 코딩 규칙

서론

이 문서는 팀의 코딩 규칙을 담고 있습니다.

규칙을 수정하시고자 할 경우 팀과 의논 후 수정합시다.

1. 명명 규칙 (Naming Conventions)

1.1. 변수 명명 (Variable Naming)

  • CamelCase 사용: 모든 변수명은 소문자로 시작하는 camelCase 형식을 원칙으로 합니다.

    • (O) userName, orderCount
    • (X) user_name (snake_case), UserName (PascalCase)
  • 헝가리안 표기법 금지: 변수명에 자료형을 접두어로 붙이는 방식을 사용하지 않습니다.

    • (O) name, age, isAvailable
    • (X) strName, nAge, bAvailable
  • 의미 있는 이름 부여: 변수의 역할과 용도가 명확히 드러나도록 명명합니다. a, b, temp 등 의미 없는 단어는 지양합니다.

    • (O) userList, totalPrice, expiredDate
    • (X) list, val, temp, data1

    TIP

    반복문 내 인덱스(i, j, k)는 예외적으로 허용합니다.

  • 불리언(Boolean) 변수 접두사: 참/거짓을 나타내는 변수는 상태를 직관적으로 알 수 있는 접두사를 사용합니다.

    • (O) isLoggedIn, hasError, canExecute
    • (X) loginCheck, errorStatus, successFlag
  • 매개변수 명명 (SNAKE_CASE): 메뉴 매개변수, 팝업 매개변수 등은 대문자 SNAKE_CASE를 사용합니다.

    • (O) MENU_ID, POPUP_PARAM_NAME
    • (X) menuId, popupParamName

1.2. 함수/메소드 명명 (Function/Method Naming)

  • fn_ 접두사 사용: 일반적인 함수 및 메소드는 fn_ 접두사로 시작하여 일반 변수와 명확히 구분합니다.

    • (O) fn_search(), fn_saveData()
    • (X) search(), save_data()
  • CamelCase 사용: fn_ 접두사 이후의 명칭은 소문자로 시작하는 camelCase 형식을 사용합니다.

    • (O) fn_getUserInfo(), fn_calculateTotal()
    • (X) fn_GetUserInfo(), fn_calculate_total()
  • 이벤트 핸들러 규칙:

    • 자동 생성 명칭 유지: 넥사크로 프레임워크에서 자동 생성되는 이벤트 함수명은 임의로 수정하지 않고 그대로 사용합니다.
      • (O) btn_search_onclick, ds_list_oncolumnchanged

    NOTE

    화면 로드 시 발생하는 이벤트는 예외적으로 form_onload 명칭을 사용합니다.

  • 동사 위주의 명명: 함수의 기능을 직관적으로 알 수 있도록 get, set, is, chk(또는 check) 등의 동사를 조합하여 명명합니다.

    • (O) fn_isExist(), fn_getParam()

1.3. 파일 및 디렉터리 명명 (File & Directory Naming)

  • 표준 가이드 준수: 프로젝트에서 정의된 '개발 표준 문서’의 파일, 디렉터리 및 컴포넌트(Component) 명명 규칙을 최우선적으로 따릅니다.

1.4. 상수 명명 (Constant Naming)

  • UPPER_SNAKE_CASE 사용: 모든 전역 상수는 대문자와 언더바(_)를 사용하는 SNAKE_CASE 형식을 사용합니다.
    • (O) MAX_COUNT, API_URL, DEFAULT_PAGE_SIZE
    • (X) maxCount, api_url, Max_Count

2. 코드 스타일 및 포맷팅 (Code Style & Formatting)

2.1. 들여쓰기 및 공백

  • 탭(Tab) 사용: 코드 들여쓰기는 탭(Tab) 사용을 원칙으로 합니다.

    NOTE

    넥사크로 스튜디오(Nexacro Studio) 환경에서 스페이스(Space)를 통한 들여쓰기 관리가 불편한 점을 고려한 규칙입니다.

2.2. 문장 끝 세미콜론

  • 세미콜론(;) 필수 사용: 모든 문장의 끝에는 세미콜론을 반드시 작성합니다.

    IMPORTANT

    이는 코드의 명확성을 높이고 자바스크립트의 자동 세미콜론 삽입(ASI)으로 인한 예기치 않은 오류를 방지하기 위함입니다.

2.3. 괄호 스타일

  • K&R 스타일 (Same Line Open): 중괄호({)는 함수 선언이나 제어문 키워드와 동일한 줄에서 시작하고, 닫는 중괄호(})는 새로운 줄에 작성합니다.
    • 함수 예시:
      // 일반 함수
      this.fn_search = function() {
          // 코드 작성
      };
      
      // 화살표 함수
      const fn_update = () => {
          // 코드 작성
      };
      
    • 제어문 예시:
      if (condition) {
          // 코드 작성
      } else {
          // 코드 작성
      }
      

2.4. 최대 줄 길이

  • 100자 제한: 한 줄의 최대 길이는 공백을 포함하여 100자 이내로 제한합니다.

    TIP

    가독성을 위해 100자가 넘어가는 코드는 적절히 개행하여 작성하는 것을 권장합니다.

2.5. 에디터 글꼴 설정

  • D2Coding 사용: 팀 내 코드 리뷰 및 화면 공유 시 가독성 통일을 위해 에디터 글꼴은 D2Coding 사용을 원칙으로 합니다.
    • 다운로드: naver/d2codingfont (GitHub)

2.6. 연산자 주변 공백 사용

  • 공백 필수 사용: 코드의 가독성을 높이기 위해 모든 연산자(산술, 비교, 논리, 대입 등)의 양쪽에는 반드시 공백을 추가합니다.
    • (O) const total = price + tax;, if (count > 0 && isValid) { ... }
    • (X) const total=price+tax;, if(count>0&&isValid){ ... }

2.7. 문자열 표기 (String Literals)

  • 쌍따옴표(“”) 사용: 코드 내 문자열은 쌍따옴표(") 사용을 원칙으로 합니다.
    • (O) const mode = "SEARCH";
    • (X) const mode = 'SEARCH';

    NOTE

    단, 문자열 내부에 쌍따옴표가 포함되어야 하거나 MyBatis XML의 test 속성 등 특수한 상황에서는 홑따옴표(')를 사용할 수 있습니다.

3. 주석 및 문서화 (Comments & Documentation)

3.1. 주석 작성 가이드

  • 단일행 주석 (//): 코드 한 줄에 대한 설명이나 간단한 코멘트를 작성할 때 사용합니다.
    // 사용자 이름 설정
    const userName = "HongGilDong";
    
  • 다중행 주석 (/* ... */): 여러 줄에 걸친 상세 설명이나 함수/클래스에 대한 설명을 작성할 때 사용합니다.
    /*
     * 공통 조회 함수
     * @param {String} svcId 서비스 ID
     * @param {String} url 요청 URL
     */
    this.fn_search = function(svcId, url) {
        // ... 코드 생략
    };
    
  • 공통코드 및 상태값 명시: 공통코드나 상태값 등 코드값만으로는 그 의미를 즉시 파악하기 어려운 경우, 주석으로 명칭(의미)을 명시합니다.
    this.fn_initCombo = () => {
        return this.combo.setCombo({
            action: "basic",
            svcId: "combo",
            comps: [
                {
                    comp: this.div_search.form.cmb_grde,
                    sqlId: "@comcd.s01",
                    mode: "a",
                    param: "CLA_CD=1020", // 학년
                    mapping: { code: "CD", data: "CD_NM" },
                },
                {
                    comp: this.div_search.form.cmb_facDvcd,
                    sqlId: "@comcd.s01",
                    mode: "a",
                    param: "CLA_CD=1654", // 이수구분
                    mapping: { code: "CD", data: "CD_NM" },
                },
            ],
        });
    };
    
  • 주석 처리된 코드 금지: 비활성화된 코드(Commented-out code)를 파일 내에 방치하지 않습니다.

    WARNING

    불필요한 코드는 즉시 삭제하세요. 과거 이력이 필요하다면 형상 관리 도구(Git)를 활용해야 합니다.

    • (X) // const oldData = "test";

4. 프로그래밍 권장 사항 (Programming Best Practices)

4.1. 변수 선언 및 유효범위 (Variable Declaration & Scope)

  • const[1]와 let[2] 사용: 변수 선언 시 const를 우선적으로 사용하며, 재할당이 필요한 경우에만 let을 사용합니다.

    IMPORTANT

    var 키워드는 절대 사용하지 않습니다.

    • (O) const MAX_TIMEOUT = 5000;, let currentStep = 0;
    • (X) var name = "admin";

4.2. 함수 설계 (Function Design)

  • async-await[3] 사용: 비동기 처리 시 callback이나 .then() 방식의 promise를 지양하고, 가독성이 높은 async-await 문법을 사용합니다.

    • (O)
      this.fn_save = async function() {
          try {
              const result = await this.fn_callApi();
              // 성공 처리
          } catch (e) {
              // 에러 처리
          }
      };
      
    • (X)
      this.fn_save = function() {
          this.fn_callApi().then(function(result) {
              // 성공 처리
          }).catch(function(e) {
              // 에러 처리
          });
      };
      
  • 얼리 리턴(Early Return) 권장: 조건문이 중첩되어 코드의 깊이(Depth)가 깊어지는 것을 방지하기 위해, 예외 상황을 먼저 처리하고 함수를 일찍 반환(Return)합니다.

    • (O)
      this.fn_process = function(data) {
          if (!data) return; // 예외 우선 처리
          
          if (data.status !== "OK") return;
          
          // 핵심 로직 수행 (들여쓰기 최소화)
          this.fn_execute(data);
      };
      
    • (X)
      this.fn_process = function(data) {
          if (data) {
              if (data.status === "OK") {
                  // 핵심 로직이 깊은 Depth에 위치함
                  this.fn_execute(data);
              }
          }
      };
      

    4.3. 제어문 중괄호({}) 필수 사용

    • 중괄호 생략 금지: if, for, while 등 제어문 사용 시, 실행되는 문장이 한 줄이라도 중괄호를 반드시 사용합니다. 이는 코드의 가독성을 높이고 향후 코드 추가 시 발생할 수 있는 논리적 오류를 방지하기 위함입니다.
    • (O)
      if (condition) {
          this.fn_execute();
      }
      
    • (X)
      if (condition) this.fn_execute();
      

    4.4. 삼항 연산자 중첩 금지

    • 가독성 우선: 삼항 연산자는 간단한 조건 할당에만 사용하며, 두 번 이상 중첩하여 사용하지 않습니다. 복잡한 조건은 if-else문을 사용하거나 변수로 분리하여 가독성을 확보합니다.
    • (O)
      const statusLabel = (status === "01") ? "성공" : "실패";
      
    • (X)
      const label = isMember ? (isValid ? "정상" : "만료") : "비회원";
      

    5. SQL 작성 규칙 (SQL Writing Rules)

    5.1. SQL 포맷팅 및 스타일

    • 대문자 사용: SQL 예약어(Keywords)와 컬럼명(Columns)은 모두 대문자 작성을 원칙으로 합니다.

    • 들여쓰기 및 정렬:

      • SELECT, FROM, WHERE, GROUP BY 등의 주요 키워드는 우측 정렬 형태로 배치하여 코드의 가독성을 높입니다.
      • 컬럼이나 정렬 대상 나열 시 앞 콤마(Leading Comma) 방식을 사용합니다.
    • ANSI Join 필수 사용: 모든 조인 문법은 INNER JOIN, LEFT OUTER JOIN 등 ANSI Join 문법을 반드시 사용합니다.

      IMPORTANT

      Oracle 방식의 콤마 조인이나 (+) 연산자를 사용한 아우터 조인 작성을 금지합니다.

    • 작업 예시:

      SELECT A.YY AS YY
           , A.ORG_CD AS ORG_CD
           , B.UNIV_CD AS UNIV_CD
        FROM HSG0010 A
       INNER JOIN PKG_CSB_ORG B
          ON A.ORG_CD = B.ORG_CD
       WHERE A.YY = #{YY}
         AND B.UNIV_CD = #{UNIV_CD}
       ORDER BY B.ORD
              , A.YY
      
    • MyBatis <where> 사용 금지: 동적 쿼리 작성 시 MyBatis에서 제공하는 <where> 태그 사용을 금지합니다. 대신 WHERE 1=1 형식을 사용하여 들여쓰기와 가독성을 유지합니다.

    • 연산자 주변 공백 사용: SQL 내의 모든 연산자(비교, 산술, 대입 등)의 양쪽에는 반드시 공백을 추가합니다.

      • (O)
        SELECT A.POINT + 1 AS NEXT_POINT
          FROM HSG0010 A
         WHERE A.YY = #{YY}
           AND A.ORG_CD != '0000'
        
      • (X)
        SELECT A.POINT+1 AS NEXT_POINT
          FROM HSG0010 A
         WHERE A.YY=#{YY}
           AND A.ORG_CD!='0000'
        
    • 작업 예시:

      SELECT A.USER_ID AS USER_ID
           , A.USER_NM AS USER_NM
        FROM CSB0101 A
       WHERE 1 = 1
         <if test="USER_ID != null and USER_ID != ''">
         AND A.USER_ID = #{USER_ID}
         </if>
      
    • MyBatis OGNL 단일 문자 비교 주의: ‘1’, ‘0’, ‘Y’, ‘N’ 등 한 글자 값을 비교할 때 OGNL 표현식에서 char 타입으로 오인되는 문제를 방지하기 위해, XML 속성(test)은 **홑따옴표(')**로 감싸고 내부 문자열 값은 **쌍따옴표(")**를 사용합니다.

    • 작업 예시:

      <!-- (O) XML 속성을 홑따옴표로, 내부 값을 쌍따옴표로 사용 -->
      <if test='USE_YN == "Y"'>
          AND A.USE_YN = #{USE_YN}
      </if>
      
      <!-- (X) 한 글자를 홑따옴표로 감싸면 char 타입으로 식별되어 비교 실패 가능성 있음 -->
      <if test="USE_YN == 'Y'"> ... </if>
      
    • 필수 조건 동적 쿼리 처리 금지: SQL 작성 시 필수 조건(연도, 학기 등)에 대해서는 MyBatis의 <if> 등 동적 쿼리 태그를 사용하지 않습니다. 이는 필수 파라미터 누락 시 의도치 않은 대량의 데이터 조회나 잘못된 결과가 반환되는 것을 방지하기 위함입니다.

    • 작업 예시:

      <!-- (O) 필수 조건인 YY, SMT는 <if> 태그 없이 직접 작성 -->
      WHERE 1 = 1
        AND A.YY = #{YY}
        AND A.SMT = #{SMT}
        <if test='USER_ID != null and USER_ID != ""'>
        AND A.USER_ID = #{USER_ID}
        </if>
      
      <!-- (X) 필수 조건을 <if> 태그로 감싸면 파라미터 누락 시 전체 데이터가 조회될 수 있음 -->
      WHERE 1 = 1
        <if test='YY != null and YY != ""'>
        AND A.YY = #{YY}
        </if>
      

5.2. SQL 명명 규칙

  • 별칭(Alias) 필수 사용: 모든 테이블과 조회 컬럼에는 별칭을 반드시 부여합니다.
    • 테이블 별칭: A, B, C 순으로 부여하거나 의미 있는 약어를 사용합니다.
    • 컬럼 별칭: 조회 결과의 가독성과 명확한 데이터 매핑을 위해 컬럼 별칭(AS ...) 작성을 원칙으로 합니다.
  • 변수 사용: 마이바티스(MyBatis) 바인드 변수(#{...}) 사용 시 변수명은 모두 대문자 SNAKE_CASE를 사용합니다.
    • (O) #{USER_ID}, #{MENU_ID}
    • (X) #{userId}, #{menuId}

5.3. 성능 및 보안 고려 사항

  • SELECT * 사용 금지: 필요한 컬럼만 명시적으로 작성하여 불필요한 데이터 전송을 방지합니다.
  • 바인드 변수 사용: SQL Injection 방지를 위해 리터럴 상수 대신 바인드 변수(#{...}) 사용을 원칙으로 합니다.

6. 업무 개발 규칙 (Business Development Rules)

6.1. 메뉴 및 팝업 매개변수 처리

  • 구조 분해 할당 사용: 메뉴 매개변수나 팝업 매개변수를 가져올 때는 $comp.getParam(this) 메소드를 사용하며, 가독성과 기본값 설정을 위해 구조 분해 할당(Destructuring Assignment)[4] 방식으로 선언합니다.
  • 선언 위치: 매개변수 선언은 폼 상단의 전역 변수 선언 영역([ PART 1 ])에 작성합니다.
    • 작업 예시:
      //_________________________________________________________________________________________________
      //
      //      [ PART 1 ]
      //      form 전역변수 선언
      //_________________________________________________________________________________________________
      const { ATLEC_GBN = "XXX", MENU_ID } = $comp.getParam(this);
      

6.2. 자동 조회 지양

  • 서버 부하 및 속도 개선: 프로그램 오픈 시 대량의 데이터를 자동으로 조회하는 행위는 지양합니다. 불필요한 서버 부하를 줄이고 초기 로딩 속도를 높이기 위해, 사용자가 직접 조회 버튼을 클릭하거나 필수 검색 조건을 입력한 후 조회가 이루어지도록 설계합니다.

6.3. EzTitlebar SQL 처리 방식

  • 스크립트 기반 요청 사용: EzTitlebar 컴포넌트 속성(예: selectSqlId, insertSqlId 등)에 SQL ID를 직접 등록하지 않습니다. 대신 스크립트에서 별도의 트랜잭션 함수를 작성하고, Titlebar의 핸들러 함수를 오버라이드하여 연결합니다.

    TIP

    이 방식은 복잡한 파라미터 처리나 트랜잭션 전/후 로직을 더 유연하게 관리할 수 있게 해줍니다.

  • 작업 예시:

    // [ PART 4 ] 사용자 TitleBar 버튼 함수, 이벤트
    this.tit_main_onload = function(obj:nexacro.EzTitlebar, e:nexacro.EzTitlebarEventInfo) {
        obj.onsearch = this.fn_searchMain; // 조회 핸들러 연결
        obj.onsave = this.fn_saveMain;     // 저장 핸들러 연결
    };
    
    // [ PART 5 ] Transaction 함수
    this.fn_searchMain = function() {
        return this.tx.search({
            action: "basic",
            svcId: "searchMain",
            sqlId: "sample_01.s01",
            outDs: "ds_main",
            param: $f.mkArg({ 
                YY: this.div_search.form.spn_yy,
                // ... 기타 파라미터
            }),
        });
    };
    

6.4. 엔터(Enter) 키 조회 기능 구현

  • 사용자 편의성 제고: 성명, 사번, 키워드 등 텍스트 방식으로 검색하는 조회 조건이 포함된 경우, 사용자가 텍스트 입력 후 즉시 조회를 수행할 수 있도록 Enter 키 입력 시 조회 함수가 호출되도록 구현합니다.

  • 구현 방법: 컴포넌트의 onkeydown 이벤트 등에서 입력된 키가 Enter(13)인 경우 조회 버튼의 클릭 이벤트나 조회 함수(fn_search)를 호출합니다.

  • 작업 예시:

    this.div_search_edt_name_onkeydown = function(obj:nexacro.Edit, e:nexacro.KeyEventInfo) {
        // 엔터 키 입력 시 조회 함수 호출
        if (e.keycode === 13) {
            this.fn_search();
        }
    };
    

6.5. 최대 입력 길이(maxlength) 설정

  • 데이터 정합성 및 오류 방지: 사용자로부터 입력을 받는 컴포넌트(Edit, MaskEdit, TextArea 등)는 해당 데이터가 저장될 DB 컬럼의 길이를 고려하여 최대 입력 길이(maxlength)를 반드시 설정합니다.
  • 사용자 경험(UX) 개선: 입력 단계에서 길이를 제한함으로써 저장 시 발생하는 길이 초과 에러(Data too long)를 사전에 방지하고 데이터의 정합성을 확보합니다.

6.6. 입력 문자 제한 및 타입 설정

  • 유효 데이터 입력 유도: 학번, 사번, 연락처 등 입력받을 문자의 범위가 정해져 있는 경우, 사용자가 의도하지 않은 문자를 입력하지 못하도록 명확한 타입을 설정합니다.
  • 설정 방법:
    • 일반 컴포넌트: inputtype 속성을 설정합니다. (예: 숫자만 입력 시 number 또는 digit)
    • 그리드(Grid): 컬럼의 edittype 설정에 따라 다음 속성을 연결하여 설정합니다.
      • edittype="text"인 경우: editinputtype 속성 설정
      • edittype="textarea"인 경우: textareainputtype 속성 설정

6.7. 자동 선택(autoselect) 기능 활용

  • 편집 편의성 제공: 정렬 순서, 수량 등 기존 입력된 텍스트 전체를 한꺼번에 변경하는 것이 빈번할 것으로 예상되는 경우, 컴포넌트 진입 시 내용이 즉시 드래그(선택)된 상태가 되어 바로 수정할 수 있도록 설정합니다.
  • 설정 방법:
  • 일반 컴포넌트: autoselect 속성을 활용합니다.
  • 그리드(Grid): 컬럼의 edittype 설정에 따라 다음 속성을 활용합니다.
    • edittype="text"인 경우: editautoselect 속성 설정
    • edittype="textarea"인 경우: textareaautoselect 속성 설정

7. 형상 관리 및 커밋 규칙 (Version Control & Commit Rules)

7.1. 커밋 규칙 (Commit Rules)

  • 작업 단위별 커밋: 한 번에 너무 많은 변경 사항을 커밋하지 않고, 논리적인 수정 작업 단위(기능 추가, 버그 수정 등)로 나누어 커밋합니다.
  • 간결하고 명확한 메시지: 커밋 메시지에는 작업 내용을 타인이 쉽게 이해할 수 있도록 간략하고 명확하게 작성합니다.

7.2. 브랜치 전략 (Branch Strategy)

  • 개인 브랜치 활용: 모든 작업은 개인별로 생성한 브랜치에서 진행하며, 작업 완료 후 원격 저장소에 Push합니다.
  • 병합 절차: 개인 브랜치 작업이 완료되면 Pull Request(PR) 또는 Merge Request(MR)를 생성하여 주 브랜치(main)에 병합하는 것을 원칙으로 합니다.

    IMPORTANT

    main 브랜치에 직접 Push하는 행위는 금지됩니다.

7.3. 파일 점유 및 병합 주의사항

  • 파일 점유 해제 후 Git 작업 수행: 넥사크로 스튜디오(Nexacro Studio) 및 클립리포트 디자이너(ClipReport Designer) 등의 툴은 작업 중인 파일을 쓰기 상태로 점유합니다.

    WARNING

    git pull이나 merge 수행 시 파일 점유로 인해 오류가 발생할 수 있습니다. 툴 전체를 종료할 필요는 없으나, 반드시 수정 중인 파일의 탭을 닫아 점유를 해제한 후 작업을 진행하시기 바랍니다.

7.4. 대용량 바이너리 파일 커밋 금지

  • 저장소 최적화: 설치 파일(.exe, .msi), 대용량 라이브러리, 빌드 결과물 등 큰 용량의 바이너리 파일은 Git 저장소에 커밋하지 않습니다.

    IMPORTANT

    이러한 파일들은 저장소의 크기를 불필요하게 키우고 성능을 저하시키므로, 프로젝트 파일 서버 등 별도의 공유 공간을 활용하시기 바랍니다.


  1. MDN - const ↩︎

  2. MDN - let ↩︎

  3. MDN - async function ↩︎

  4. MDN - 구조 분해 할당 (Destructuring assignment) ↩︎

← Back to all posts