Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
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`.