🔨

Deno の拡張を作ってリリースしてみた。

2022/06/28に公開

はじめに

最近 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 からロードして実行する物を作りました。

https://deno.land/x/expandhome

単純に UNIX パス形式の ~/path/to/home/mattn/path/to に展開するライブラリです。~/ だけでなく ~dankogai/path/to という別のユーザのパス展開もサポートしています。これのためにC言語を使っています。(これが無いなら $HOME だけで出来る)
Linux、MacOS、Windows で動作します。UNIX の場合は getpwnam で得た情報から、Windows の場合は...いろいろやってるので興味のある人はソースを見て下さい。

https://github.com/mattn/deno-expandhome

興味本位で作ったので実用性等はまったく考えていません。

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