1# Bower {#sec-bower}
2
3[Bower](https://bower.io) is a package manager for web site front-end components. Bower packages (comprising of build artifacts and sometimes sources) are stored in `git` repositories, typically on Github. The package registry is run by the Bower team with package metadata coming from the `bower.json` file within each package.
4
5The end result of running Bower is a `bower_components` directory which can be included in the web app's build process.
6
7Bower can be run interactively, by installing `nodePackages.bower`. More interestingly, the Bower components can be declared in a Nix derivation, with the help of `bower2nix`.
8
9## bower2nix usage {#ssec-bower2nix-usage}
10
11Suppose you have a `bower.json` with the following contents:
12
13### Example bower.json {#ex-bowerJson}
14
15```json
16 "name": "my-web-app",
17 "dependencies": {
18 "angular": "~1.5.0",
19 "bootstrap": "~3.3.6"
20 }
21```
22
23Running `bower2nix` will produce something like the following output:
24
25```nix
26{ fetchbower, buildEnv }:
27buildEnv {
28 name = "bower-env";
29 ignoreCollisions = true;
30 paths = [
31 (fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
32 (fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
33 (fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
34 ];
35}
36```
37
38Using the `bower2nix` command line arguments, the output can be redirected to a file. A name like `bower-packages.nix` would be fine.
39
40The resulting derivation is a union of all the downloaded Bower packages (and their dependencies). To use it, they still need to be linked together by Bower, which is where `buildBowerComponents` is useful.
41
42## buildBowerComponents function {#ssec-build-bower-components}
43
44The function is implemented in [pkgs/development/bower-modules/generic/default.nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/bower-modules/generic/default.nix).
45
46### Example buildBowerComponents {#ex-buildBowerComponents}
47
48```nix
49{
50 bowerComponents = buildBowerComponents {
51 name = "my-web-app";
52 generated = ./bower-packages.nix; # note 1
53 src = myWebApp; # note 2
54 };
55}
56```
57
58In ["buildBowerComponents" example](#ex-buildBowerComponents) the following arguments are of special significance to the function:
59
601. `generated` specifies the file which was created by {command}`bower2nix`.
612. `src` is your project's sources. It needs to contain a {file}`bower.json` file.
62
63`buildBowerComponents` will run Bower to link together the output of `bower2nix`, resulting in a `bower_components` directory which can be used.
64
65Here is an example of a web frontend build process using `gulp`. You might use `grunt`, or anything else.
66
67### Example build script (gulpfile.js) {#ex-bowerGulpFile}
68
69```javascript
70var gulp = require('gulp');
71
72gulp.task('default', [], function () {
73 gulp.start('build');
74});
75
76gulp.task('build', [], function () {
77 console.log("Just a dummy gulp build");
78 gulp
79 .src(["./bower_components/**/*"])
80 .pipe(gulp.dest("./gulpdist/"));
81});
82```
83
84### Example Full example — default.nix {#ex-buildBowerComponentsDefaultNix}
85
86```nix
87{
88 myWebApp ? {
89 outPath = ./.;
90 name = "myWebApp";
91 },
92 pkgs ? import <nixpkgs> { },
93}:
94
95pkgs.stdenv.mkDerivation {
96 name = "my-web-app-frontend";
97 src = myWebApp;
98
99 buildInputs = [ pkgs.nodePackages.gulp ];
100
101 bowerComponents = pkgs.buildBowerComponents {
102 # note 1
103 name = "my-web-app";
104 generated = ./bower-packages.nix;
105 src = myWebApp;
106 };
107
108 nativeBuildInputs = [
109 writableTmpDirAsHomeHook # note 3
110 ];
111
112 buildPhase = ''
113 runHook preBuild
114
115 cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . # note 2
116 ${pkgs.nodePackages.gulp}/bin/gulp build # note 4
117
118 runHook postBuild
119 '';
120
121 installPhase = ''
122 runHook preInstall
123
124 mv gulpdist $out
125
126 runHook postInstall
127 '';
128}
129```
130
131A few notes about [Full example — `default.nix`](#ex-buildBowerComponentsDefaultNix):
132
1331. The result of `buildBowerComponents` is an input to the frontend build.
1342. Whether to symlink or copy the {file}`bower_components` directory depends on the build tool in use.
135 In this case a copy is used to avoid {command}`gulp` silliness with permissions.
1363. {command}`gulp` requires `HOME` to refer to a writeable directory.
1374. The actual build command in this example is {command}`gulp`. Other tools could be used instead.
138
139## Troubleshooting {#ssec-bower2nix-troubleshooting}
140
141### ENOCACHE errors from buildBowerComponents {#enocache-errors-from-buildbowercomponents}
142
143This means that Bower was looking for a package version which doesn't exist in the generated `bower-packages.nix`.
144
145If `bower.json` has been updated, then run `bower2nix` again.
146
147It could also be a bug in `bower2nix` or `fetchbower`. If possible, try reformulating the version specification in `bower.json`.