
브라우저에서 서버랙을 3D로 조립하기 — 빌드 없는 Three.js
알루미늄 프로파일로 서버랙을 짜기 전에 웹에서 미리 조립해보는 도구를 만들었다. 빌드 도구 없이 CDN만 쓰고, 정적 서버가 공개할 파일을 화이트리스트로 제한한 이야기.
알루미늄 V-slot 프로파일로 서버랙을 짜려고 했다. 2020, 2040, 4040 규격을 조합해서 원하는 크기로 만드는 방식이다.
문제는 사기 전에 맞는지 알 수 없다는 것이다. 프로파일은 길이별로 잘라서 주문한다. 잘못 계산하면 남거나 모자란다. 종이에 그려봤는데 3차원 구조라 감이 안 왔다.
그래서 브라우저에서 3D로 조립해보는 도구를 만들었다.
빌드 도구를 쓰지 않았다
Three.js를 쓰는데 번들러를 쓰지 않았다. import map으로 CDN에서 직접 로드한다.
<script type="importmap">
{ "imports": { "three": "https://.../three.module.js" } }
</script>
이유는 이 프로젝트의 성격 때문이다. HTML 하나, CSS 몇 개, JS 몇 개짜리 도구다. 여기에 npm 의존성과 빌드 단계를 붙이면 코드를 고치고 확인하는 데 빌드가 끼어든다.
파일을 저장하고 새로고침하면 바로 보이는 게 이런 도구에는 훨씬 낫다. node_modules도 없고 package.json도 없다.
대가는 있다. 네트워크가 필요하다. CDN이 죽으면 도구가 안 뜬다. 오프라인에서 못 쓴다. 개인용 도구라 감수했지만, 남에게 배포할 거였으면 다른 선택을 했을 것이다.
정적 서버가 공개할 파일을 화이트리스트로
서버는 파이썬 표준 라이브러리로 만들었다. 정적 파일만 서빙하면 되니 별도 프레임워크가 필요 없었다.
여기서 신경 쓴 부분이 있다. 공개할 파일을 명시적으로 제한했다.
공개: index.html, css/*.css, src/*.js
비공개: 그 외 전부 (운영 문서, 스크립트, .env)
일반적인 정적 서버는 디렉토리 전체를 공개한다. 그러면 프로젝트 루트에 있는 run.sh, docs/, .env가 전부 노출된다. 이 도구는 다른 기기에서도 열어보는데, 실수로 .env가 열리면 곤란하다.
“공개할 것을 나열”하는 방식이 “숨길 것을 나열”하는 방식보다 안전하다. 파일을 새로 추가했을 때 기본값이 비공개가 되기 때문이다.
조작 방식을 두 층으로 나눴다
CAD 도구에서 가장 어려운 건 3D 공간에서 물체를 옮기는 조작이다. 마우스는 2차원인데 공간은 3차원이다.
일반적인 CAD는 기즈모(축 화살표)를 쓴다. 정확하지만 처음 쓰는 사람에게는 어렵다. 축을 잘못 잡으면 엉뚱한 방향으로 간다.
그래서 두 층으로 나눴다.
쉬운 층 — 부품 몸체를 그냥 잡고 끌면 바닥면(X/Z)을 따라 움직인다. 높이는 무시된다. 대부분의 배치 작업은 이걸로 끝난다.
정밀한 층 — 부품을 선택하면 기즈모가 나온다. 축별 이동(G), 회전(R), 크기조절(S)을 정확히 할 수 있다.
여기에 키보드도 붙였다. 방향키로 X/Z 미세 이동, PageUp/PageDown으로 높이, Shift를 누르면 5배. 마우스로 대충 놓고 키보드로 맞추는 흐름이 실제로 가장 빨랐다.
빈 공간 드래그는 시점 회전으로 뒀다. 부품을 잡으면 부품이 움직이고, 빈 곳을 잡으면 카메라가 돈다. 모드 전환 없이 구분된다.
스냅을 토글로 둔 이유
그리드 스냅(이동 1mm, 회전 1°)을 넣었는데, 끌 수 있게 했다.
프로파일 조립은 대부분 규격 단위로 딱 맞아야 해서 스냅이 켜져 있는 게 맞다. 그런데 가끔 “일단 대충 놓고 나중에 맞추자” 하고 싶을 때가 있다. 그때 스냅이 강제되면 답답하다.
제약은 기본값으로 두되 끌 수 있게 한다. 이건 도구 전반에 해당하는 것 같다.
로그에서 query string 을 제외했다
작은 부분인데 적어둔다. 요청 로그를 남기는데 query string은 기록하지 않는다.
정적 서버라 query에 민감한 값이 들어올 일이 없어 보이지만, 나중에 기능이 늘면서 파라미터로 뭔가 넘기게 될 수 있다. 그때 로그를 고치는 걸 기억할 자신이 없었다.
로그는 한번 쌓이기 시작하면 계속 쌓인다. 나중에 지우는 것보다 처음부터 안 남기는 게 낫다.
실제로 도움이 됐나
됐다. 3D로 조립해보니 세로 기둥 길이를 잘못 계산하고 있었다는 걸 발견했다. 주문 전에 알았으니 프로파일 두 개 값을 아꼈다.
더 유용했던 건 비율 감각이었다. 도면상 숫자로는 감이 안 오던 게, 3D로 돌려보니 “생각보다 낮네” 하는 판단이 됐다. 결국 설계를 바꿨다.
정리
- 작은 도구에 빌드 단계를 붙이면 고치고 확인하는 흐름이 느려진다. CDN + import map 으로 충분할 때가 있다
- 대가는 네트워크 의존이다. 배포 대상이 넓으면 다른 선택을 해야 한다
- 정적 서버는 공개할 파일을 나열한다. 숨길 것을 나열하면 새 파일이 기본 공개가 된다
- 3D 조작은 쉬운 층(바닥면 드래그)과 정밀한 층(기즈모)으로 나눈다
- 제약(스냅)은 기본값으로 두되 끌 수 있게 한다
- 로그에 남기지 않을 것은 처음부터 제외한다. 나중에 지우는 건 잘 안 하게 된다