viewimage.php?id=2ab4c42ef0d0&no=24b0d769e1d32ca73ced82fa11d02831fe384ecd5bf5471a0304a0eb0c9b1586464ec094af816bc99167b7d84097cfd77e314ca790aeb03ba31da4221d843e2709b0

원글


내겐 위 두 답글이 왜 stack을 npm마냥 쓰지 못하냐는 말로 들렸음. 해서 스냅샷을 설명해주고 싶었음.

일단 첫 답글을 좀 더 길게 설명하자면 stack에서 install 커맨드는 해당 패키지가 실행파일을 포함하고 있으면 그걸 PATH로 쓸만한 디렉터리에 복사해달라는 명령어임. uninstall 서브 커맨드가 추가된다면 그 바이너리를 삭제해주는 커맨드가 되어야겠지. 그냥 지워주면 될 것 같은데 해결되지 않은 나름의 이유가 있음. 그게 스냅샷 특성이고.


Semantic Versioning Sucks! Long Live Semantic Versioning

위 글을 보면 npm이 빌드가 뜬금없이 깨지는 경우를 설명하고 있음. 근본 원인은 의존성을 범위 단위로 지정해서 그렇단 거지. JS는 문제 부분을 실행하기 전까진 괜찮지만 하스켈이나 자바처럼 타입 체킹을 하는 언어로 가면 달라짐. 빌드가 안 될 테니까. 그래서 gradle이나 cabal이나 의존성을 구체적으로 잡아주지. 이러면 새 버전이 나와도 빌드가 깨질 일은 없어짐. (npm처럼 다른 버전을 허용하면 되지 않냐고 하면 같은 타입을 다르게 처리하는 문제가 생김. peerdependencies라는 골칫덩이 ^오^)


이렇게 구체적으로 의존성이 명시됐을 때 버전만 다른 같은 패키지를 쓰게 되는 경우 문제가 생기지. 이 경우 gradle은 한쪽 의존성을 씹어버리고 cabal은 그냥 빌드를 실패해버림. 이게 하스켈에서 cabal hell이라고 부르는 현상임.


여기서 stack이 들어옴. snapshot이라는 서로 문제가 없는 패키지 집합을 만들고 그 안에서만 패키지를 쓰는 거임. 이 의존성 해결 연산이 비싼데 그걸 stackage서버가 해주고 있는 거고.


소소하게 장점이라면 node_modules처럼 프로젝트마다 사이즈가 확확 늘어나진 않는다는 점이고 단점은… 뭐 이미 위에서 지적한 것처럼 npm update 방식으로 쓰기 어렵단 거임. global-project/stack.yaml이 있는데 이걸 매번 수작업으로 바꿔야 하니. stack bump같이 이 수작업을 자동화하는 명령어만 추가하면 될 것 같은데 어쨌든 없지.

이전 패키지 정리도 마찬가지임. 못할 이유는 없는데 어쨌든 기능은 없는 거임. 근데 이건 다른 프로젝트에서 쓰는 패키지인지 알 수 없으니까 약간은 이해가 가는 바임.


결론은 방식은 나쁜 거 없음. 왜 구현은 이러냔 거지. 괜히 툴링이 문제가 아님.