Denoを利用してコードを書いたものをnpmライブラリとして公開したいと思うことがあります。
npmライブラリに公開するためにはTypeScriptのままではだめなのでJavaScriptにビルドする必要があり、ビルド方法はいくつかあります。
その中でも最も簡単なのがdnt – Deno to Node Transformを利用することです。
dntの何がいいかと言うと、一番大きいのはpackage.jsonを始めとしたnpmライブラリとして公開するためのファイルを簡単に作成できることです。
せっかくdenoで書いているのに別でpackage.jsonなんて書くのは面倒ですからね。
そのdntのGitHubにはGitHub Actionsを使ったnpmレジストリへの公開方法は記載されていますが、GitLab CIを使った方法は記載されていません。
GitLab CIはdocker imageを使ってジョブを構築します。
dntはビルド時に npm install
を行うため、dockerのdenoイメージだけだと動作しません。
逆にnodejsイメージでdenoを動かすのも難しいです。
そこで、alpineを使ったの解決方法を見つけました。
alpine:edgeイメージを利用
色々試行錯誤した結果、denoもnpmも利用できる alpine:edge
を使用することで解決しました。
なぜ、edgeなのかというと2023年11月のv3.18時点ではdenoがまだ alpine:latest
に存在していないためです。
ビルドファイルを用意
ビルドファイルを作成したらそのファイルに対して deno run
を行えばよいです。
例えば、下記のビルドファイル(Node CLIビルド)が存在したとします。
dntでビルドした結果は npm
ディレクトリに格納されます。
// build.ts
import { build, emptyDir } from 'dnt'
await emptyDir('npm')
await build({
entryPoints: [{
kind: 'bin',
name: '名前',
path: 'メインファイルのパス',
}],
packageManager: 'npm',
outDir: './npm',
importMap: './import_map.json',
shims: {
deno: true,
},
package: {
name: '名前',
version: '1.0.0',
description: '説明',
main: './esm/main.js',
bin: {
'CLIコマンド名': './esm/main.js',
},
engines: {
node: '>=16.0.0',
npm: '>=8.0.0'
},
license: 'MIT',
repository: {
type: 'git',
url: 'Gitリポジトリのパス',
},
bugs: {
url: 'イシューのパス',
},
},
typeCheck: 'both',
test: false,
declaration: 'separate',
scriptModule: false,
})
Deno.copyFileSync('README.md', './npm/README.md')
GitLab CIの設定
ビルドファイル(build.ts
)を作ったら .gitlab-ci.yml
には下記のように記述します。
image: alpine:edge
stages:
- publish
default:
before_script:
- apk update
deploy:
stage: publish
script:
- apk add npm deno
- deno run -A build.ts
- cd npm
- npm publish
only:
refs:
- main
これでnpmレジストリへの公開ができます。