ansible-later: 2.0.22 -> 2.0.23
[NixPkgs.git] / doc / languages-frameworks / bower.section.md
blob6226dc0702d70067843bdccaed63ef4427656c30
1 # Bower {#sec-bower}
3 [Bower](https://bower.io) is a package manager for web site front-end components. Bower packages (comprising of build artefacts 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.
5 The end result of running Bower is a `bower_components` directory which can be included in the web app's build process.
7 Bower can be run interactively, by installing `nodePackages.bower`. More interestingly, the Bower components can be declared in a Nix derivation, with the help of `nodePackages.bower2nix`.
9 ## bower2nix usage {#ssec-bower2nix-usage}
11 Suppose you have a `bower.json` with the following contents:
13 ### Example bower.json {#ex-bowerJson}
15 ```json
16   "name": "my-web-app",
17   "dependencies": {
18     "angular": "~1.5.0",
19     "bootstrap": "~3.3.6"
20   }
21 ```
23 Running `bower2nix` will produce something like the following output:
25 ```nix
26 { fetchbower, buildEnv }:
27 buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
28   (fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
29   (fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
30   (fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
32 ```
34 Using the `bower2nix` command line arguments, the output can be redirected to a file. A name like `bower-packages.nix` would be fine.
36 The 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.
38 ## buildBowerComponents function {#ssec-build-bower-components}
40 The 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).
42 ### Example buildBowerComponents {#ex-buildBowerComponents}
44 ```{=docbook}
45 <programlisting language="nix">
46 bowerComponents = buildBowerComponents {
47   name = "my-web-app";
48   generated = ./bower-packages.nix; <co xml:id="ex-buildBowerComponents-1" />
49   src = myWebApp; <co xml:id="ex-buildBowerComponents-2" />
51 </programlisting>
52 ```
54 In ["buildBowerComponents" example](#ex-buildBowerComponents) the following arguments are of special significance to the function:
56 ```{=docbook}
57 <calloutlist>
58   <callout arearefs="ex-buildBowerComponents-1">
59     <para>
60       <varname>generated</varname> specifies the file which was created by <command>bower2nix</command>.
61     </para>
62     </callout>
63       <callout arearefs="ex-buildBowerComponents-2">
64     <para>
65       <varname>src</varname> is your project's sources. It needs to contain a <filename>bower.json</filename> file.
66     </para>
67   </callout>
68 </calloutlist>
69 ```
71 `buildBowerComponents` will run Bower to link together the output of `bower2nix`, resulting in a `bower_components` directory which can be used.
73 Here is an example of a web frontend build process using `gulp`. You might use `grunt`, or anything else.
75 ### Example build script (gulpfile.js) {#ex-bowerGulpFile}
77 ```javascript
78 var gulp = require('gulp');
80 gulp.task('default', [], function () {
81   gulp.start('build');
82 });
84 gulp.task('build', [], function () {
85   console.log("Just a dummy gulp build");
86   gulp
87     .src(["./bower_components/**/*"])
88     .pipe(gulp.dest("./gulpdist/"));
89 });
90 ```
92 ### Example Full example — default.nix {#ex-buildBowerComponentsDefaultNix}
94 ```{=docbook}
95 <programlisting language="nix">
96 { myWebApp ? { outPath = ./.; name = "myWebApp"; }
97 , pkgs ? import &lt;nixpkgs&gt; {}
100 pkgs.stdenv.mkDerivation {
101   name = "my-web-app-frontend";
102   src = myWebApp;
104   buildInputs = [ pkgs.nodePackages.gulp ];
106   bowerComponents = pkgs.buildBowerComponents { <co xml:id="ex-buildBowerComponentsDefault-1" />
107     name = "my-web-app";
108     generated = ./bower-packages.nix;
109     src = myWebApp;
110   };
112   buildPhase = ''
113     cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . <co xml:id="ex-buildBowerComponentsDefault-2" />
114     export HOME=$PWD <co xml:id="ex-buildBowerComponentsDefault-3" />
115     ${pkgs.nodePackages.gulp}/bin/gulp build <co xml:id="ex-buildBowerComponentsDefault-4" />
116   '';
118   installPhase = "mv gulpdist $out";
120 </programlisting>
123 A few notes about [Full example — `default.nix`](#ex-buildBowerComponentsDefaultNix):
125 ```{=docbook}
126 <calloutlist>
127   <callout arearefs="ex-buildBowerComponentsDefault-1">
128     <para>
129       The result of <varname>buildBowerComponents</varname> is an input to the frontend build.
130     </para>
131   </callout>
132   <callout arearefs="ex-buildBowerComponentsDefault-2">
133     <para>
134       Whether to symlink or copy the <filename>bower_components</filename> directory depends on the build tool in use. In this case a copy is used to avoid <command>gulp</command> silliness with permissions.
135     </para>
136   </callout>
137   <callout arearefs="ex-buildBowerComponentsDefault-3">
138     <para>
139       <command>gulp</command> requires <varname>HOME</varname> to refer to a writeable directory.
140     </para>
141   </callout>
142   <callout arearefs="ex-buildBowerComponentsDefault-4">
143     <para>
144       The actual build command. Other tools could be used.
145     </para>
146   </callout>
147 </calloutlist>
150 ## Troubleshooting {#ssec-bower2nix-troubleshooting}
152 ### ENOCACHE errors from buildBowerComponents {#enocache-errors-from-buildbowercomponents}
154 This means that Bower was looking for a package version which doesn't exist in the generated `bower-packages.nix`.
156 If `bower.json` has been updated, then run `bower2nix` again.
158 It could also be a bug in `bower2nix` or `fetchbower`. If possible, try reformulating the version specification in `bower.json`.