Coding Convention

Frontend Coding Convention

프론트엔드 코딩 컨벤션에 대한 문서입니다. Console, Design System, Core Lib

Javascript - ECMAScript 2018(ES9)

ItemCategoryRuleExample
ClassPascalCaseclass myClass {}
FunctioncamelCaseconst myFunction = () => {}
VariableReadonly const
Enum
SCREAMING_SNAKE_CASEconst READONLY_CONST <br /> MY_ENUM {}
OtherscamelCasemyVariable

Typescript

ItemCategoryRuleExample
TypePascalCasetype MyType = type;
InterfacePascalCaseinterface MyInterface {}

File / Directory / URL

ItemRepoCategoryRuleExample
FilesConsoleVue ComponentsPascalCaseMyComponent.vue
PagesPascalCase
with suffix 'Page'
MyConsolePage.vue
Design SystemComponents
Related Files
PascalCase
with prefix 'P' (means 'Prime')
with its component name
PMyDSComponent.vue
PMyDSComponent.mdx
PMyDSComponent.stories
PMyDSComponent.scss
PMyDSComponent.pcss
Type Related Fileskebab-case
with suffix '-type'
type.ts
schema-type.ts
Other FilesCommonkebeb-casemy-config.ts
Directory
URL
Commonkebab-case/my-directory
/my-url/

Code

ItemRepoCategoryRuleExample
EventCommonNameVerb Root
If duplicated or needed -ed / -ing is allowed
update
update, updated
Two-way BindingIf the event needs two-way biding, emit 'update:xxx'$emit('update:code', code)
Arguments$event as the last argument$emit(foo, bar, $event)
CodeCommonHandler NameClear word with prefix 'handle'const handleOnClick = () => {}
Component NamePascalCase at script files
kebab-case at template
<my-component />
import MyComponent from @
Composition API1. Do not declare objects,variables inside return
2. The name of reactive variable should be state or xxxState (if needed)
3. Using variable inside setup() is recommended as reactive
1. const a = 1; return { a }
2,3. const state = reactive({})
ConsolePage script, style1. <script> lang should be 'ts'
2. <style> lang should be 'postcss' and 'scoped'
1. <script lang="ts">
2. <style lang="postcss" scoped>
Design SystemPage script, style1. <script> lang should be 'ts'
2. <style> lang should be 'postcss' BUT NO 'scoped'
1. <script lang="ts">
<style lang="postcss">
Storybook TitleDirectories + component name(PascalCase) with dash{ title: 'atoms/buttons/MyButton' ... }
Root Class NameComponent name should be written on root element's class with kebab-case<fragment class="p-my-button">
Core LibDescriptionDescription of each function should be written, by JS Doc/** @@function @name @description *@param descriptions **/

Additional Rules

  1. Array 에서 변수명 지정은 복수형보다 List 접미사를 지향합니다.
const policies: Array<string>; (X)
const plicyList: Array<string>; (O)
  1. enum 혹은 Object.freeze() 대신 as const 를 사용합니다.
const NOTIFICATION_UNIT = {
  PERCENT: 'PERCENT',
  ACTUAL_COST: 'ACTUAL_COST',
} as const;
  1. API 응답 결과값에 대한 interface 명은 xxxModel 이라고 명명합니다.
interface CostQuerySetModel {};
  1. init 할 때 실행할 함수는 setup 함수 최하단에 위치시키는 것을 지향합니다.

    async 인 경우에는 즉시실행함수로 작성합니다.

(async () => {
	await listCostQuerySet();
})();

return { ...toRefs(), ... }

Test Code

console과 Design System 에서는 공통적으로 vue test utils 를 사용합니다.

파일명: __test__/<대상 파일 명>.test.ts

테스트코드 템플릿

import { mount, createLocalVue } from '@vue/test-utils';
import CompositionApi, { defineComponent } from '@vue/composition-api';

const localVue = createLocalVue();
localVue.use(CompositionApi);

describe('', () => {
    const mockComponent = defineComponent({
        template: `
            <div>
            </div>
        `,
        setup() {
            return {};
        },

    });

    const wrapper = mount(mockComponent, { localVue });

    it('', () => {
        expect(wrapper.exists()).toBe(true);
    });
});

Lint

References