2016-03-26 16:50:45 +00:00
|
|
|
<section xmlns="http://docbook.org/ns/docbook"
|
|
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
|
|
xml:id="sec-bower">
|
2018-05-01 23:54:21 +00:00
|
|
|
<title>Bower</title>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
<link xlink:href="http://bower.io">Bower</link> is a package manager for web
|
|
|
|
site front-end components. Bower packages (comprising of build artefacts and
|
|
|
|
sometimes sources) are stored in <command>git</command> repositories,
|
|
|
|
typically on Github. The package registry is run by the Bower team with
|
|
|
|
package metadata coming from the <filename>bower.json</filename> file within
|
|
|
|
each package.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
The end result of running Bower is a <filename>bower_components</filename>
|
|
|
|
directory which can be included in the web app's build process.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
2016-03-26 16:50:45 +00:00
|
|
|
Bower can be run interactively, by installing
|
|
|
|
<varname>nodePackages.bower</varname>. More interestingly, the Bower
|
|
|
|
components can be declared in a Nix derivation, with the help of
|
|
|
|
<varname>nodePackages.bower2nix</varname>.
|
2018-05-01 23:54:21 +00:00
|
|
|
</para>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<section xml:id="ssec-bower2nix-usage">
|
2016-03-26 16:50:45 +00:00
|
|
|
<title><command>bower2nix</command> usage</title>
|
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
Suppose you have a <filename>bower.json</filename> with the following
|
|
|
|
contents:
|
|
|
|
<example xml:id="ex-bowerJson">
|
|
|
|
<title><filename>bower.json</filename></title>
|
2016-03-26 16:50:45 +00:00
|
|
|
<programlisting language="json">
|
|
|
|
<![CDATA[{
|
|
|
|
"name": "my-web-app",
|
|
|
|
"dependencies": {
|
|
|
|
"angular": "~1.5.0",
|
|
|
|
"bootstrap": "~3.3.6"
|
|
|
|
}
|
|
|
|
}]]>
|
|
|
|
</programlisting>
|
2018-05-01 23:54:21 +00:00
|
|
|
</example>
|
|
|
|
</para>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
Running <command>bower2nix</command> will produce something like the
|
|
|
|
following output:
|
2016-03-26 16:50:45 +00:00
|
|
|
<programlisting language="nix">
|
|
|
|
<![CDATA[{ fetchbower, buildEnv }:
|
|
|
|
buildEnv { name = "bower-env"; ignoreCollisions = true; paths = [
|
|
|
|
(fetchbower "angular" "1.5.3" "~1.5.0" "1749xb0firxdra4rzadm4q9x90v6pzkbd7xmcyjk6qfza09ykk9y")
|
|
|
|
(fetchbower "bootstrap" "3.3.6" "~3.3.6" "1vvqlpbfcy0k5pncfjaiskj3y6scwifxygfqnw393sjfxiviwmbv")
|
|
|
|
(fetchbower "jquery" "2.2.2" "1.9.1 - 2" "10sp5h98sqwk90y4k6hbdviwqzvzwqf47r3r51pakch5ii2y7js1")
|
|
|
|
]; }]]>
|
|
|
|
</programlisting>
|
2018-05-01 23:54:21 +00:00
|
|
|
</para>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
Using the <command>bower2nix</command> command line arguments, the output
|
|
|
|
can be redirected to a file. A name like
|
|
|
|
<filename>bower-packages.nix</filename> would be fine.
|
|
|
|
</para>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
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 <varname>buildBowerComponents</varname> is useful.
|
|
|
|
</para>
|
|
|
|
</section>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<section xml:id="ssec-build-bower-components">
|
|
|
|
<title><varname>buildBowerComponents</varname> function</title>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
|
|
|
<para>
|
2018-05-01 23:54:21 +00:00
|
|
|
The function is implemented in
|
|
|
|
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/bower-modules/generic/default.nix">
|
|
|
|
<filename>pkgs/development/bower-modules/generic/default.nix</filename></link>.
|
|
|
|
Example usage:
|
|
|
|
<example xml:id="ex-buildBowerComponents">
|
|
|
|
<title>buildBowerComponents</title>
|
2016-03-26 16:50:45 +00:00
|
|
|
<programlisting language="nix">
|
|
|
|
bowerComponents = buildBowerComponents {
|
|
|
|
name = "my-web-app";
|
|
|
|
generated = ./bower-packages.nix; <co xml:id="ex-buildBowerComponents-1" />
|
|
|
|
src = myWebApp; <co xml:id="ex-buildBowerComponents-2" />
|
|
|
|
};
|
|
|
|
</programlisting>
|
2018-05-01 23:54:21 +00:00
|
|
|
</example>
|
2016-03-26 16:50:45 +00:00
|
|
|
</para>
|
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
In <xref linkend="ex-buildBowerComponents" />, the following arguments are
|
|
|
|
of special significance to the function:
|
|
|
|
<calloutlist>
|
|
|
|
<callout arearefs="ex-buildBowerComponents-1">
|
|
|
|
<para>
|
|
|
|
<varname>generated</varname> specifies the file which was created by
|
|
|
|
<command>bower2nix</command>.
|
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
<callout arearefs="ex-buildBowerComponents-2">
|
|
|
|
<para>
|
|
|
|
<varname>src</varname> is your project's sources. It needs to contain a
|
|
|
|
<filename>bower.json</filename> file.
|
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
</calloutlist>
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
<varname>buildBowerComponents</varname> will run Bower to link together the
|
|
|
|
output of <command>bower2nix</command>, resulting in a
|
|
|
|
<filename>bower_components</filename> directory which can be used.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
Here is an example of a web frontend build process using
|
|
|
|
<command>gulp</command>. You might use <command>grunt</command>, or anything
|
|
|
|
else.
|
|
|
|
</para>
|
|
|
|
|
|
|
|
<example xml:id="ex-bowerGulpFile">
|
|
|
|
<title>Example build script (<filename>gulpfile.js</filename>)</title>
|
2016-03-26 16:50:45 +00:00
|
|
|
<programlisting language="javascript">
|
|
|
|
<![CDATA[var gulp = require('gulp');
|
|
|
|
|
|
|
|
gulp.task('default', [], function () {
|
|
|
|
gulp.start('build');
|
|
|
|
});
|
|
|
|
|
|
|
|
gulp.task('build', [], function () {
|
|
|
|
console.log("Just a dummy gulp build");
|
|
|
|
gulp
|
|
|
|
.src(["./bower_components/**/*"])
|
|
|
|
.pipe(gulp.dest("./gulpdist/"));
|
|
|
|
});]]>
|
|
|
|
</programlisting>
|
2018-05-01 23:54:21 +00:00
|
|
|
</example>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<example xml:id="ex-buildBowerComponentsDefaultNix">
|
|
|
|
<title>Full example — <filename>default.nix</filename></title>
|
2016-03-26 16:50:45 +00:00
|
|
|
<programlisting language="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 { <co xml:id="ex-buildBowerComponentsDefault-1" />
|
|
|
|
name = "my-web-app";
|
|
|
|
generated = ./bower-packages.nix;
|
|
|
|
src = myWebApp;
|
|
|
|
};
|
|
|
|
|
|
|
|
buildPhase = ''
|
|
|
|
cp --reflink=auto --no-preserve=mode -R $bowerComponents/bower_components . <co xml:id="ex-buildBowerComponentsDefault-2" />
|
|
|
|
export HOME=$PWD <co xml:id="ex-buildBowerComponentsDefault-3" />
|
|
|
|
${pkgs.nodePackages.gulp}/bin/gulp build <co xml:id="ex-buildBowerComponentsDefault-4" />
|
|
|
|
'';
|
|
|
|
|
|
|
|
installPhase = "mv gulpdist $out";
|
|
|
|
}
|
|
|
|
</programlisting>
|
2018-05-01 23:54:21 +00:00
|
|
|
</example>
|
|
|
|
|
|
|
|
<para>
|
|
|
|
A few notes about <xref linkend="ex-buildBowerComponentsDefaultNix" />:
|
|
|
|
<calloutlist>
|
|
|
|
<callout arearefs="ex-buildBowerComponentsDefault-1">
|
|
|
|
<para>
|
|
|
|
The result of <varname>buildBowerComponents</varname> is an input to the
|
|
|
|
frontend build.
|
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
<callout arearefs="ex-buildBowerComponentsDefault-2">
|
|
|
|
<para>
|
|
|
|
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.
|
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
<callout arearefs="ex-buildBowerComponentsDefault-3">
|
|
|
|
<para>
|
|
|
|
<command>gulp</command> requires <varname>HOME</varname> to refer to a
|
|
|
|
writeable directory.
|
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
<callout arearefs="ex-buildBowerComponentsDefault-4">
|
|
|
|
<para>
|
2016-03-26 16:50:45 +00:00
|
|
|
The actual build command. Other tools could be used.
|
2018-05-01 23:54:21 +00:00
|
|
|
</para>
|
|
|
|
</callout>
|
|
|
|
</calloutlist>
|
|
|
|
</para>
|
|
|
|
</section>
|
2016-03-26 16:50:45 +00:00
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<section xml:id="ssec-bower2nix-troubleshooting">
|
2016-03-26 16:50:45 +00:00
|
|
|
<title>Troubleshooting</title>
|
|
|
|
|
2018-05-01 23:54:21 +00:00
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
2018-06-01 01:03:37 +00:00
|
|
|
<term>
|
|
|
|
<literal>ENOCACHE</literal> errors from <varname>buildBowerComponents</varname>
|
2016-03-26 16:50:45 +00:00
|
|
|
</term>
|
|
|
|
<listitem>
|
2018-05-01 23:54:21 +00:00
|
|
|
<para>
|
|
|
|
This means that Bower was looking for a package version which doesn't
|
|
|
|
exist in the generated <filename>bower-packages.nix</filename>.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
If <filename>bower.json</filename> has been updated, then run
|
|
|
|
<command>bower2nix</command> again.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
It could also be a bug in <command>bower2nix</command> or
|
|
|
|
<command>fetchbower</command>. If possible, try reformulating the version
|
|
|
|
specification in <filename>bower.json</filename>.
|
|
|
|
</para>
|
2016-03-26 16:50:45 +00:00
|
|
|
</listitem>
|
2018-05-01 23:54:21 +00:00
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
</section>
|
2016-03-26 16:50:45 +00:00
|
|
|
</section>
|