약 일주일의 기간안에 개발환경 구축부터 순수 js를 사용하여 개발하는 프로젝트가 있었다. 그 당시에는 웹팩을 사용하여 개발환경을 구축하는 방식도 잘 몰랐고 react만 사용하다보니 js로만 개발한다는 것이 막막했었다.
다행히도 개발환경 구축은 이전에 공부를 해둔 덕분에 수월하게 할 수 있었지만 프론트엔드 프로젝트 설계에는 많은 시간이 걸렸었다.
팀원들과 이야기하면서 동일한점이 있었다면 대부분 react 라이브러리를 사용해봤다는 점이였다. 그래서 react와 비슷한 방식으로 컴포넌트 단위의 개발을 해보자는 이야기가 나왔고 그렇게 컴포넌트 단위로 개발을 해보게 되었다. 물론 가상돔과 JSX같이 효율적인 방식을 가져오지는 못했지만 어느정도 통일된 코드와 이후에 react를 공부하면서 이해하기 수월했고 무엇보다 react의 장점을 직접적으로 느낄 수 있었던 계기였었다.
그리고 최근에는 조금이라도 프로젝트를 개선해보고자 다시 서로가 모여 코드를 수정해보고 있는데 기존의 core역할을 하는 컴포넌트를 수정해보면 좋겠다는 의견이 있어 개선을 어떻게 하면 좋을지에 대해 고민을 하게 되었다.
현재 방식은 부모역할을 하는 컴포넌트 (네비게이션 또는 각 페이지)에서만 append 방식을 사용하여 건네받은 dom element에 붙이고 나머지 자식 컴포넌트에는 element를 생성하고 부모 컴포넌트에서 붙이는 방식을 사용하고 있다. 그리고 각자 조금씩 다른 명칭을 사용하고 있다.
// Navigation.js (부모역할하는 컴포넌트)
import NavItem from './NavItem';
export default class Navigation extends Component{
// 생략...
didMount() {
const fragment = new DocumentFragment();
navItems.forEach(li => {
const list = new NavItem(li);
if (list.$dom) {
fragment.appendChild(list.$dom);
}
});
navList.appendChild(fragment);
}
}
그래서 사소한거지만 이런 element를 붙이는 방식을 통일하고 싶은 생각이 있다.
프로젝트의 core를 담당하는 컴포넌트는 아래와 같은 모양이다.
여기서 메서드로 사용되는 createDom, replaceElement, appendRoot의 경우에는 컴포넌트 내부에서 굳이 구현하지 않고 유틸함수로 빼도 좋을 것 같아서 빼고 싶은 생각이 있다.
그리고 element를 붙이는 방식이 통일할수있다면 render 메서드에서 상위 요소에 붙이는 방식에 대한 코드를 작성하여 어느정도 강제하고 싶다.
class Component {
$dom;
props;
state;
constructor(props) {
this.props = props;
}
setState = nextState => {
this.state = nextState;
this.render();
};
createDom = (tagName, attrs) => {
const $dom = document.createElement(tagName);
for (const [key, value] of Object.entries(attrs)) {
$dom[key] = value;
}
return $dom;
};
replaceElement = ($old, $new) => {
$old.parentElement.replaceChild($new, $old);
};
appendRoot = ($root, $new, isNav = false) => {
if (isNav) {
if ($root.childNodes[0]) $root.replaceChild($new, $root.childNodes[0]);
else $root.appendChild($new);
return;
}
if ($root.childNodes[1]) $root.replaceChild($new, $root.childNodes[1]);
else $root.appendChild($new);
};
addEvent = () => {};
render = () => {};
}