Bower
Bower 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.
The end result of running Bower is a
bower_components directory which can be included
in the web app's build process.
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.
bower2nix usage
Suppose you have a bower.json with the following contents:
bower.json
Running bower2nix will produce something like the
following output:
Using the bower2nix command line arguments, the
output can be redirected to a file. A name like
bower-packages.nix would be fine.
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.
buildBowerComponents function
The function is implemented in
pkgs/development/bower-modules/generic/default.nix.
Example usage:
buildBowerComponents
bowerComponents = buildBowerComponents {
name = "my-web-app";
generated = ./bower-packages.nix;
src = myWebApp;
};
In , the following arguments
are of special significance to the function:
generated specifies the file which was created by bower2nix.
src is your project's sources. It needs to
contain a bower.json file.
buildBowerComponents will run Bower to link
together the output of bower2nix, resulting in a
bower_components directory which can be used.
Here is an example of a web frontend build process using
gulp. You might use grunt, or
anything else.
Example build script (gulpfile.js)Full example — default.nix
{ myWebApp ? { outPath = ./.; name = "myWebApp"; }
, pkgs ? import <nixpkgs> {}
}:
pkgs.stdenv.mkDerivation {
name = "my-web-app-frontend";
src = myWebApp;
buildInputs = [ pkgs.nodePackages.gulp ];
bowerComponents = pkgs.buildBowerComponents {
name = "my-web-app";
generated = ./bower-packages.nix;
src = myWebApp;
};
buildPhase = ''
cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components .
export HOME=$PWD
${pkgs.nodePackages.gulp}/bin/gulp build
'';
installPhase = "mv gulpdist $out";
}
A few notes about :
The result of buildBowerComponents is an
input to the frontend build.
Whether to symlink or copy the
bower_components directory depends on the
build tool in use. In this case a copy is used to avoid
gulp silliness with permissions.
gulp requires HOME to
refer to a writeable directory.
The actual build command. Other tools could be used.
TroubleshootingENOCACHE errors from
buildBowerComponents
This means that Bower was looking for a package version which
doesn't exist in the generated
bower-packages.nix.
If bower.json has been updated, then run
bower2nix again.
It could also be a bug in bower2nix or
fetchbower. If possible, try reformulating
the version specification in bower.json.