Node.js 打包准则

来自 Arch Linux 中文维基
Arch 打包准则

32 位CLRCMakeCrossDKMSEclipseElectronFontFree PascalGNOMEGoHaskellJavaKDE内核模块LispMesonMinGWNode.jsNonfreeOCamlPerlPHPPythonRRubyRustVCSWebWine

本文档包含了给 Node.js 软件包编写 PKGBUILD 的规范与指导。

软件包命名[编辑 | 编辑源代码]

提示:可以用自定义变量 _pkgname 代替 pkgname,一般这个变量可以这样定义: _pkgname=${pkgname#nodejs-}

Node.js 库的软件包名应该以 nodejs- 开头。对于独立的应用,只使用程序名。

源代码[编辑 | 编辑源代码]

npm 提供了可靠的命名规范和下载 URL。PKGBUILD#source source=() 列表可以使用下面的 URL 模板:

https://registry.npmjs.org/$_pkgname/-/$_pkgname-$pkgver.tgz

使用 npm[编辑 | 编辑源代码]

使用 npm 安装时,应当将其添加为构建时依赖。

makedepends=('npm')

不需要解压压缩包:

noextract=("${_pkgname}-${pkgver}.tgz")

这是一个最小的 package 函数:

package() {
    npm install -g --prefix "${pkgdir}/usr" "${srcdir}/${_pkgname}-${pkgver}.tgz"

    # npm 会把所有文件的所有权交给构建用户
    # https://bugs.archlinux.org/task/63396
    chown -R root:root "${pkgdir}"
}

设置临时缓存[编辑 | 编辑源代码]

npm 处理 package.json 时,npm 会为了构建软件包,下载依赖到默认的缓存目录 $HOME/.npm。为了避免污染用户的 home 目录,可以用 --cache 选项,将缓存目录临时设为其他目录。

下载依赖到 ${srcdir}/npm-cache,然后安装它们到打包目录:

npm install --cache "${srcdir}/npm-cache" 

继续正常打包:

npm run packager

软件包包含向 $srcdir/$pkgdir 的引用[编辑 | 编辑源代码]

很不幸,npm 会创建指向 $srcdir$pkgdir 的引用。这是一个已知问题。但你可以手动删除这些引用,反正也不会用到它们。

所有依赖都会在 _where 属性里,包含指向 $pkgdir 的引用,你通常可以用一点 sed 魔法删除它们:

find "$pkgdir" -name package.json -print0 | xargs -r -0 sed -i '/_where/d'

你的主软件包也会包含一些其他引用,删除它们最简单的办法就删除所有有下划线的属性,但用 sed 不是很方便。你可以使用 jq 得到想要的结果:

local tmppackage="$(mktemp)"
local pkgjson="$pkgdir/usr/lib/node_modules/$_pkgname/package.json"
jq '.|=with_entries(select(.key|test("_.+")|not))' "$pkgjson" > "$tmppackage"
mv "$tmppackage" "$pkgjson"
chmod 644 "$pkgjson"

另一个你会找到对 $pkgdir 引用的地方,是软件包的 man 属性。如果你不在乎 man 页面(反正它们不会被作为依赖安装),你可以像这样删除它们:

find "$pkgdir" -type f -name package.json | while read pkgjson; do
    local tmppackage="$(mktemp)"
    jq 'del(.man)' "$pkgjson" > "$tmppackage"
    mv "$tmppackage" "$pkgjson"
    chmod 644 "$pkgjson"
done

一个使用了上面全部三个技巧的例子:readability-cliAUR

使用 nvm[编辑 | 编辑源代码]

当一个基于 node.js 的应用需要构建打包使用不同的 node.js 版本时,可以使用 nvmAUR

警告: 这只适用于应用的构建 / 打包时依赖,不影响运行时依赖.

把它加入构建时依赖:

makedepends=('npm' 'nvm')

nvmAUR 使用 NVM_DIR 环境变量来查找前缀(译注:指 nvm 的安装路径,下同)。如果不在 nvmAUR 初始化前指定,前缀就会被设置为 $HOME/.nvm

你可以用下面的函数创建自定义前缀,并将用户目录和前缀隔离开:

_ensure_local_nvm() {
    # let's be sure we are starting clean
    which nvm >/dev/null 2>&1 && nvm deactivate && nvm unload
    export NVM_DIR="${srcdir}/.nvm"

    # The init script returns 3 if version specified
    # in ./.nvrc is not (yet) installed in $NVM_DIR
    # but nvm itself still gets loaded ok
    source /usr/share/nvm/init-nvm.sh || [[ $? != 1 ]]
}

应该在使用 nvmAURnpm 或其他基于特定版本 Node.js 的程序前,调用这个函数。

示例 PKGBUILD 用法[编辑 | 编辑源代码]

prepare() {
    _ensure_local_nvm
    nvm install 14.15.0
}

build() {
    _ensure_local_nvm
    npm install
}

或者,执行不带参数的 nvm install,会在当前目录的 .nvrc 文件中查找版本字符串。

这个用法的一个例子可以在 insomniaAUR 找到。