Building a node app is easy, but we need to check some things before packaging our apps in Arch Linux.
The dependencies
Each node app has a package.json
in which it specifies its dependencies, later installed inside the node_modules
folder.
Since our app is not compatible with any version of such dependencies, the package.json
specifies the compatibility range by using Semantic Versioning, (a.k.a. semver).
Due to this versioning, we need to install the node_modules
content inside the /usr/lib/<package-name>
folder to avoid installing it globally on the system. We should build the package having that in mind. Let’s go!
For this post we're using the PKGBUILD for webtorrent-cli, powered by feross.
Installing the packages
If our node app doesn't need a build process, like converting TypeScript files to Nodejs compatible JavaScript code, we can use this simple build()
function in the PKGBUILD
:
build() {
cd "$srcdir/$pkgname-$pkgver"
npm install --production
}
We don't need to install the devDependencies
declared in the package.json
, so --production
will reduce the package size of this app.
But, what if we have a build process? Then, our build()
will be somewhat as follows:
build() {
cd "$srcdir/$pkgname-$pkgver"
npm install
npm run build
npm prune --production
}
After completing the build process, we should remove the devDependencies
using the npm prune --production
command.
Package the node modules
we should copy the node_modules
folder inside the package as well as the app code itself.
package() {
install -dm755 "${pkgdir}/usr/lib/${pkgname}"
cp -a bin node_modules package.json "${pkgdir}/usr/lib/${pkgname}/"
}
💡 Tip: ${var}
is another way to reference the variable $var
in Bash.
Check the code before packaging
The ArchWiki recommends to use the check()
function. This step happens between the build
and the package
, and this is the perfect place to run tests to check the compatibility with the current platform.
build() {
cd "$srcdir/$pkgname-$pkgver"
npm install
npm run build
}
check() {
cd "$srcdir/$pkgname-$pkgver"
npm test
npm prune --production
}
The testing libraries are commonly located in the devDepencies
of our package.json
, because they aren't used in production runtime. So, we should prune the node_modules
in the check()
step instead of build()
.
Building using nvm
And the last issue for today is nvm. When we must build our package in a specific node version we should use the nvm
package.
We already know that Arch Linux is a rolling release so the official nodejs package is the latest version, not the latest LTS.
🧠 The node team calls this version current
, and the even-numbered major version will transition to Long Term Support when a new major version appears. Nowadays, the current
version is 14.x
and, when the 15.0.0
is publicly released as current
, the 14.x
will be the latest LTS available.
We should add nvm
as makedepends
, and it's a good practice if we add the node version that we need as a variable in the PKGBUILD
:
_nodeversion=12
makedepends=('npm' 'nvm')
Then, add the nvm
to the build()
function:
build() {
source /usr/share/nvm/init-nvm.sh
nvm use ${_nodeversion} || nvm install ${_nodeversion}
cd "$srcdir/$pkgname-$pkgver"
npm install --production
}
We have a few things here. First, we load the init-nvm.sh
in the build()
function. Now, we can use the installed 12.x
version with the nvm use 12
command, if node v12 isn't installed we proceed to install it using nvm install 12
.
It's done! We can ship your package. 😁
Top comments (2)
If our node app requires the nodejs 18 LTS version, then how we are going to use this in the makedepends or depnds entries? I've tried to directly use the nodejs but when I tried to log the version in build function it's showing it's using the node 12.
Can you provide the Git Repo link for PKGBUILD file pls?