(correct url) |
m (Just wording) |
||
Line 68: | Line 68: | ||
== Installing Modules == | == Installing Modules == | ||
Most node modules do not contain their own install mechanism | Most node modules do not contain their own install mechanism. Instead they rely on npm to do it for them. npm '''must not''' be used to install modules in Fedora packages, since it usually requires network access, always tries to bundle libraries, and installs files in a manner inconsistent with the Filesystem Hierarchy Standard (FHS). | ||
Instead, install files in their proper place manually. Most files should be installed in ''%{nodejs_sitelib/<npm module name>'', but documentation should be installed via <code>%doc</code>. In the event that the module ships content other than JavaScript code, that content should installed in <code>%{_datadir}</code>, and the module should be patched to cope with that. | Instead, install files in their proper place manually. Most files should be installed in ''%{nodejs_sitelib/<npm module name>'', but documentation should be installed via <code>%doc</code>. In the event that the module ships content other than JavaScript code, that content should installed in <code>%{_datadir}</code>, and the module should be patched to cope with that. |
Revision as of 14:18, 20 January 2013
Original Author: T.C. Hollingsworth
Based on the guidelines of other interpreted languages like Ruby and Python.
Naming Guidelines
- The name of a Node.js extension/library package must start with nodejs- then the upstream name or name used in the npm registry. For example: nodejs-foomodule. While it is uncommon for package's name to contain node, if it does, you should still add the nodejs prefix. For instance, the npm registry contains a uuid and a node-uuid module, which would need to be named nodejs-uuid and nodejs-node-uuid, repsectively.
- Application packages that mainly provide tools (as opposed to libraries) that happen to be written for Node.js follow the general naming guidelines instead.
BuildRequires
To build a package containing pure JavaScript node modules, you need to have:
BuildRequires: nodejs-devel
Additional BuildRequires may be necessary for native modules. See #Building native modules with node-gyp for more information.
Macros
In Fedora 18 and later, as well as EPEL 6, the following macros are defined for you:
Macro | Normal Definition | Notes |
---|---|---|
__nodejs | %{_bindir}/node | The Node.js interpreter |
nodejs_version | e.g. 0.9.5 | The currently installed version of Node.js. |
nodejs_sitelib | %{_prefix}/lib/node_modules | Where Node.js modules written purely in JavaScript are installed |
nodejs_sitearch | %{_prefix}/lib/node_modules | Where native C++ Node.js modules are installed |
nodejs_symlink_deps | %{_bindir}/nodejs-symlink-deps | See #Symlinking Dependencies below. |
nodejs_fixdep | %{_bindir}/rpm/nodejs-fixdep | See #Correcting Dependencies |
These macros are provided by the nodejs package.
During %install
or when listing %files
you can use the %nodejs_sitelib
or %nodejs_sitearch
macro to specify where the installed modules are to be found. For instance:
%files # A pure JavaScript node module %{nodejs_sitelib}/foomodule/ # A native node module %{nodejs_sitearch}/barmodule/
Using this macro instead of hardcoding the directory in the specfile ensures your spec remains compatible with the installed Node.js version even if the directory structure changes radically (for instance, if %nodejs_sitelib
moves into %{_datadir}
).
Using tarballs from the npm registry
The canonical method for shipping most node modules is tarballs from the npm registry. The Source0
for such modules should be of the form http://registry.npmjs.org/<modulename>/-/<modulename>-<version>.tgz
. For instance:
Source0: http://registry.npmjs.org/npm/-/npm-1.1.70.tgz
This method should be preferred to using checkouts from git or automatically generated tarballs from GitHub.
Installing Modules
Most node modules do not contain their own install mechanism. Instead they rely on npm to do it for them. npm must not be used to install modules in Fedora packages, since it usually requires network access, always tries to bundle libraries, and installs files in a manner inconsistent with the Filesystem Hierarchy Standard (FHS).
Instead, install files in their proper place manually. Most files should be installed in %{nodejs_sitelib/<npm module name>, but documentation should be installed via %doc
. In the event that the module ships content other than JavaScript code, that content should installed in %{_datadir}
, and the module should be patched to cope with that.
Client-side JavaScript
Many node modules contain JavaScript that can be used both client and server-side, and it is sometimes hard to identify code intended only for use in the browser. Since there are no current packaging guidelines for client-side JavaScript, and given the fact that bundling of such code is currently permitted in Fedora, it is currently permissible for client-side JavaScript to exist in %{nodejs_sitelib}
.
Automatic Requires and Provides
The nodejs package includes an automatic Requires and Provides generator that automatically adds versioned dependencies based on the information provided in a module's package.json file.
Provides
It also adds virtual provides in the form npm(<module name>)
to identify modules listed in the npm registry. If a module is not listed in the npm registry, it must not provide this. Modules that aren't listed in the npm registry should set private to true in their package.json file. If not, you must patch it to include that or use RPM's filtering mechanism to remove the Provides.
Correcting Dependencies
Occasionally the dependencies listed in package.json are inaccurate. For instance, the module may work with a newer version of a dependency than the one explictly listed in the package.json file. To make correcting such dependencies easier, the %nodejs_fixdep
macro is provided and may be used instead of RPM's usual filtering mechanism. This macro should be used in %prep
and will patch package.json to contain the correct dependency information.
To convert any dependency to not list a specific version, just call %nodejs_fixdep
with the npm module name of the dependency. This changes the version in package.json to *
. (Or adds one if it wasn't already listed.) For example:
%prep %setup -q -n package %nodejs_fixdep foomodule
You can also specify a version:
%prep %setup -q -n package %nodejs_fixdep foomodule '>2.0'
The second argument to %nodejs_fixdep
must be a valid package.json version specifier as explained in
.
man npm json
You can also remove a dependency:
%prep %setup -q -n package %nodejs_fixdep -r foomodule
Symlinking Dependencies
Node.js and npm require that dependencies explicitly be included or linked into a node_modules directory inside the module directory. To make this easier, a %nodejs_symlink_deps
macro is provided and will automatically create a node_modules tree with symlinks for each dependency listed in package.json. This macro should be called in the %install
section of every Node.js module package.
Removing bundled modules
Some node modules contain copies of other libraries in their source tree. You must remove these in %prep
. Simply running rm -rf node_modules
is sufficient for most modules.
%nodejs_symlink_deps
outputs a warning when a node_modules directory already exists in the %buildroot
, and will fail if it cannot create a symlink because a directory for it already exists.
Building native modules with node-gyp
To build a native module designed to be built with node-gyp, add BuildRequires: node-gyp
, along with -devel packages for any shared libraries needed by the module. Then, simply run node-gyp rebuild
in the %build
section of the spec file to compile the module.
The WAF build system was abandoned by upstream prior to the introduction of Node.js to Fedora, and is not supported in Fedora at all.