Deno の拡張を作ってリリースしてみた。
はじめに
最近 Deno 遊びが楽しくなってしまった mattn ですこんばんわ。TypeScript は好きだけど node_modules に嫌気がさしてしまい、Deno に逃げてしまったのですが今は Deno が楽しくて仕方ないです。
Deno の良さ
僕が思う Deno の良さは以下の3つ
- node_modules が無い
- 余計なセットアップ無しに TypeScript が書け実行できる
- 危険なライブラリは許可しないと実行されない
最近は Cloudflare Workers や Deno Deploy でオレオレ Gyazo を作って遊んでいます。
既に deno.land にも沢山のライブラリが公開されているので、まだ Deno やった事がない人でもそんなに困らないと思います。
自作モジュールを作ってみた
みんな Deno モジュールを作ってる、作ってないのはお前だけ
そんな声が聞こえてきた気がしたので、Deno 拡張を作ってみました。ただ単に TypeScript のライブラリを作っても面白くないので、C言語のライブラリを Deno からロードして実行する物を作りました。
単純に UNIX パス形式の ~/path/to
を /home/mattn/path/to
に展開するライブラリです。~/
だけでなく ~dankogai/path/to
という別のユーザのパス展開もサポートしています。これのためにC言語を使っています。(これが無いなら $HOME
だけで出来る)
Linux、MacOS、Windows で動作します。UNIX の場合は getpwnam
で得た情報から、Windows の場合は...いろいろやってるので興味のある人はソースを見て下さい。
興味本位で作ったので実用性等はまったく考えていません。
deno.land、GitHub リポジトリ内には直接 DLL や so、dylib 等は置かず、GitHub Actions でビルドしてリリースしたライブラリを Release 物として GitHub にアップロードし、本モジュールのロード時にダウンロードされる様になっています。
Deno には、この辺りの仕組みが既に用意されているので、手順にそってソースを書けば、うまい具合にロードされる様になっています。
import { CachePolicy, download, join, normalize, prepare } from "./deps.ts";
let suffix = "";
switch (Deno.build.os) {
case "windows":
suffix = "dll";
break;
case "darwin":
suffix = "dylib";
break;
default:
suffix = "so";
break;
}
const lib = `./libexpandhome-${Deno.build.arch}.${suffix}`;
const version = "v0.0.1";
const policy = Deno.env.get("PLUGIN_URL") === undefined
? CachePolicy.STORE
: CachePolicy.NONE;
let url = Deno.env.get("PLUGIN_URL") ??
`https://github.com/mattn/deno-expandhome/releases/download/${version}/`;
url = join(url, lib);
const dylib = await prepare(
{
name: "expandhome",
url,
policy,
},
{
"expandhome": { parameters: ["pointer"], result: "pointer" },
"free_buf": { parameters: ["pointer"], result: "void" },
} as const,
);
deno.land での公開
deno.land にモジュール名を予約すると、GitHub リポジトリと連携する画面がでてきます。つまり先にリポジトリが必要です。GitHub リポジトリと連携した後は、モリモリと開発し、出来上がったら GitHub リポジトリに semver なタグを打ちます。すると自動で deno.land に公開される様になっています。
ただ今回は GitHub Actions で DLL/so/dylib を生成し、リリース物をアップロード、などなどをやっているので、うまく行くまでの間 v0.0.1
が何度もできて何度も消えるというアレをやってしまいました。
おわりに
Deno で動作するC言語で書かれたモジュールを作ってみました。単純なソースなので、これからC言語等で作ったライブラリを deno.land で公開してみたい人の参考になるかもしれません。
ただぶっちゃけ、このくらいの機能は Deno 本体が出来る様にして欲しい所ではあります。とはいえ JS を気にしなくてよい TypeScript サイコーというお気持ちです。
みなさんも Deno やりましょう。
Discussion