bower
bower를 처음 봤을 때의 시기나 지금이나 웹 프로젝트를 할 때마다 반복적으로 해야하는 jQuery를 다운받고 Bootstrap을 다운받는 등의 일을 어떻게 줄일까 고민하고 있고 일부는 grunt-init을 사용해서 해결하고 있다. bower를 처음 봤을 때 '오오~ 이거야~'라는 생각을 했음에도 불구하고 사용하지 않았던 것은 실제 필요에 비해서 좀 거추장스럽게 느껴진다는 점과(지금도 좀 그렇게 느낀다.) 그 이전에는 사용해 보지 않았던 components라는 어색한 이름때문이었다. 이런 부분이 크게 달라지진 않았지만 프론트앤드쪽도 이젠 의존성 관리가 거추장스러워져서 쓰기 시작했다.
bower는 기존에는 저장소는 twitter하단에서 사용했지만 프로젝트가 커져서 그런지 이제는 bower라는 계정으로 분리되었다. 그래서 검색으로 찾을 경우 일부 검색결과는 현재 깨지고 있다.
npm install -g bower
bower는 node.js로 만들어진 도구 이므로 npm을 이용해서 설치하고 커맨드라인 명령어로 사용하기 때문에 글로벌로 설치한다. 정상적으로 설치가 되면 bower -v로 버전정보를 확인할 수 있다.
bower 사용
bower는 npm과 매우 유사하므로 npm에 익숙하다면 bower도 쉽게 사용할 수 있다.
$ bower install jquery
위와 같이 실행하면 jquery를 다운받는다. bower는 기본적으로 components라는 폴더를 사용하므로 현재 위치에 components 폴더가 생성되고(npm 처럼 하위폴더에서 실행하더라도 상위의 bower 컴포넌트 위치를 찾아서 설치하는 기능은 없어보인다.)그 아래 jquery 폴더가 생성되고 이 아래 jquery관련 파일들을 다운받는다. 최초 다운로드시에는 시간이 걸리지만 로컬에 캐싱하므로(~/.bower) 이후부터는 빨라진다. 한번에 여러 컴포넌트를 설치하고 싶다면 bower install jquery bootstrap과 같이 사용하면 된다.(여전히 컴포넌트라는 이름이 어색하기는 하지만 자바스크립트와 CSS등을 한꺼번에 다루기 때문에 이런 이름을 정한 것으로 생각된다.) 다만 이때 설치는 해당 파일 하나만(jquery.js나 jquery.min.js 등) 받아오는 것이 아닌 bower 저장소에 패키징되서 저장된 내용을 모두 내려받는다. 설치한 bootstrap의 폴더 내용을 보면 다음과 같다.
$ ll components/bootstrap/
total 168
drwxr-xr-x 16 outsider staff 544 4 29 19:57 .
drwxr-xr-x 4 outsider staff 136 4 29 19:57 ..
-rw-r--r-- 1 outsider staff 344 4 28 20:25 .gitignore
-rw-r--r-- 1 outsider staff 34 4 28 20:25 .travis.yml
-rw-r--r-- 1 outsider staff 25120 4 28 20:25 CHANGELOG.md
-rw-r--r-- 1 outsider staff 3488 4 29 19:56 CONTRIBUTING.md
-rw-r--r-- 1 outsider staff 10172 4 28 20:25 LICENSE
-rw-r--r-- 1 outsider staff 4561 4 28 20:25 Makefile
-rw-r--r-- 1 outsider staff 4599 4 28 20:25 README.md
-rw-r--r-- 1 outsider staff 5308 4 29 19:57 component.json
-rw-r--r-- 1 outsider staff 297 4 28 20:25 composer.json
drwxr-xr-x 14 outsider staff 476 4 28 20:25 docs
drwxr-xr-x 4 outsider staff 136 4 28 20:25 img
drwxr-xr-x 17 outsider staff 578 4 28 20:25 js
drwxr-xr-x 44 outsider staff 1496 4 28 20:25 less
-rw-r--r-- 1 outsider staff 700 4 28 20:25 package.json
그래서 html페이지에서 참조할 때도 components/bootstrap/docs/assets/css/bootstrap.css나(bootstrap은 빌드된 파일이 좀 특이한 위치에 있다.) components/jquery/jquery.js로 참조해야 한다. 이는 일반적으로 정적파일 폴더 아래 js, css, images 등으로 구분해 놓고 사용하던 관례에 맞지 않고 경로도 상당히 복잡해 지지만(components 하위의 경로는 바꿀 수 없다.) bower를 쓰려면 어쩔 수 없어 보인다. bower는 단순 팩키지 매니저일 뿐이므로 배포시에 이런 파일들이 함께 배포되는 것이 싫다면 별도로 배포과정에서 처리를 해주어야 할 것 같다.
$ bower install jquery#1.9.1
버전을 지정해서 설치하고 싶다면 뒤에 #과 함께 버전번호를 붙혀준다.
$ bower uninstall jquery
설치한 컴포넌트를 제거하고 싶다면 uninstall 명령어를 사용한다. 사실 이는 그냥 components 폴더 아래 해당 폴더를 삭제해 준 것과 동일하다.
$ bower list
bower discover Please wait while newer package versions are being discovered
example
├─┬ bootstrap#2.3.1
│ └── jquery#1.8.3 (2.0.0 now available)
└── jquery#1.8.3 (2.0.0 now available)
bower list 혹은 bower ls로 현재 폴더 하위에 설치된 컴포넌트들의 목록을 확인할 수 있고 최신버전이 아닌 경우 옆에 최신버전이 표시된다. 계층 구조라서 보기는 쉽지만 여기서 약간 조심해야 할 점이 있는데(npm에 익숙하다면 특히) 위와 같이 계층 구조로 나오기는 하지만 최상위의 jquery와 bootstrap하위의 jquery는 사실 같은 폴더이다. 그러므로 jquery의 버전을 올리면 양쪽이 모두 올라가게 된다. 저렇게 계층으로 표시되는 이유는 bootstrap안에서 jquery에 대한 의존성이 표시되어 있기 때문인데 실제로 node.js 처럼 폴더의 계층으로 의존성을 갖지 않으므로 두 jQuery는 사실상 같다. 이는 프론트앤드에서는 각 파일이 자신만의 의존성을 갖는것이 아니라 html에서 제어를 하게 되므로 당연한 선택으로 생각된다.
$ bower search d3
Search results:
d3 git://github.com/mbostock/d3.git
nvd3 git://github.com/novus/nvd3
d3-plugins git://github.com/d3/d3-plugins.git
github-d3 git://github.com/github/d3.git
d3cloud git://github.com/rajenms/d3-cloud.git
d3-tip git://github.com/Caged/d3-tip.git
d3-treelayout git://github.com/MfgLabs/d3-treelayout.git
원하는 컴포넌트가 존재하는지 찾고 싶다면 search 명령어를 사용하면 된다. 패키지명에 검색어가 들어간 패키지를 모두 찾아준고 검색어를 생략하면 모든 패키지가 다 출력된다.
$ bower lookup d3
d3 git://github.com/mbostock/d3.git
패키지명으로 검색하고 싶다면 lookup 명령어를 사용하고 이는 일치하는 패키지명만 출력된다. 일치하는 이름이 없는 경우에는 비슷한 패키지를 추천해준다.
$ bower info jquery
jquery
Versions:
- 2.0.0
- 1.9.1
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.2
- 1.3.1
- 1.3.0
- 1.2.6
- 1.2.3
패키지의 버전 정보를 알고 싶다면 info 명령어를 사용한다. npm과는 달리 간단히 버전 정보의 목록만 나타난다.
bower.json
보통 프로젝트의 의존성은 동일하게 가져가므로 설치한 패키지에 대한 정보를 명시해야 하는데 npm에서는 package.json에 명시하고 Maven에서는 pom.xml에 명시한다. bower에서는 bower.json을 사용하는데 이전 버전에서는 component.json을 사용하다가 0.9.0 버전부터는 bower.json을 사용하고 있다.
$ bower init
name: [example]
version: [0.0.0] 0.1.0
main file: []
add commonly ignored files to ignore list? (y/n): [y] y
bower init을 사용하면 다음과 같은 bower.json을 생성할 수 있다
{
"name": "example",
"version": "0.1.0",
"ignore": [
"**/.*",
"node_modules",
"components"
]
}
bower.json에서 각 값의 의미는 아래와 같다.
- name: (필수값) 팩키지명
- version: 버전 정보
- main: 패키지의 엔드포인트
- ignore: 패키지를 설치할 때 bower가 무시할 파일 목록
- dependencies : 프로덕션에서 사용할 패키지 의존성 정보
- devDependencies : 개발용 패키지 의존성 정보
작성한 프로젝트를 bower에 배포할 것이 아니라면 dependencies와 devDependencies외이는 큰 의미는 없다.
{
"dependencies": {
"jquery": "~2.0.0"
},
"devDependencies": {
"qunit": "~1.11.0"
}
}
의존성은 위와 같이 작성하면 되고 버전 표기 방식은 npm과 동일해 보인다("package.json으로 npm 의존성 모듈 관리하기" 참고) bower.json에 의존성이 명시되어 있다면 bower install 만 실행하면 자동으로 bower.json에 명시된 컴포넌트들을 다운받아서 설치한다. 참고로 bower update 명령어도 있는데 예상과 달리 새로운 버전이 있어도 update 명령어로는 새로운 버전을 설치하지 않는다.(명령어가 좀...) 좀 테스트를 해봤는데 잘 모르겠다...(이건 나중에..)
$ bower install jquery --save
$ bower install qunit --save-dev
bower.json에 일일이 버전을 표기하는 것이 귀찮다면 --save나 --save-dev 옵션을 사용하면 설치하면서 자동으로 bower.json 파일의 의존성 부분에 설치버전으로 추가를 해준다.
.bowerrc
bower에 전체적으로 적용할 설정을 사용자의 홈디렉토리에 .bowerrc 파일을 만들어서 지정할 수 있다. .bowerrc파일은 다음과 같은 JSON 형식이다.
{
"directory": "bower_components",
"endpoint": "https://bower.mycompany.com",
"json": "bower.json",
"searchpath": [
"https://bower.herokuapp.com"
],
"shorthand_resolver": "git://example.com/{{{ organization }}}/{{{ package }}}.git"
}
- directory : 컴포넌트를 설치할 기본 디렉토리
- endpoint: 커스텀 등록 엔드포인트
- json: 의존성을 처리할 때 사용할 기본 JSON 파일
- searchpath: 추가적으로 검색할 읽기전용 Bower 저장소
- shorthand_resolver: 간단하게 지정할 패키지명의 템플릿
bower의 장점
초반에 bower를 접했을 때 느꼈던 것처럼 약간 거추장스럽게 느껴질 수도 있다.
하지만..
- 프론트앤드쪽 라이브러리도 많이 복잡해 졌기 때문에 의존성 관리가 필요하다. 경로가 좀 복잡해 지지만 부트스트랩같은 경우 안에 css, js, img등이 있으므로 일일이 나눠서 복사해주거나 어차피 전체를 하나의 폴더안에 넣어야 한다.)
- 변경사항을 추적할 필요가 없는 의존성 라이브러리를 저장소에 추가하는 것은 낭비다.(프론트앤드라서 익숙치 않아서 그렇지 개념은 서버와 동일하다. 물론 서버는 보통 바이너리라는 차이가 있지만)
- json 파일만 공유하고 의존성 라이브러리는 각자 설치해서 사용하는 것이 더 좋은 접근으로 보인다.(물론 프론트앤드에서는 아직 익숙치 않으므로 불필요한 과정이 늘어난 것으로 보일수도 있다.)
좋은 게시물 잘 봤습니다.
저는 npm이 /usr/local/ 밑에 생성되듯이 특정 영역에 저장되는 줄 알았는데, 그게 아니었군요.
수고하세요.
bower로 설치하는 라이브러리를 얘기하시는 거라면 프로젝트 내에 설치가 됩니다.
설명을 너무 잘하십니다. 많은 도움이 되었습니다~^^
감사합니다.