Swdev 0.4.0 の新機能、ローカルファイルの読み書き機能とその制限
swdev 0.4.0 のリリースをしました。面白機能をいっぱい足しました。
Swdev とは何か: おさらい
No Bundle Frontend を目指して、 service worker ですべてをコンパイルすることを目標としています。ブラウザ内で完結してることが他にない優位で、効率的なホットリロードなどを実現できる基盤を作ろうとしています。
インストール
$ deno install -qAf --unstable https://deno.land/x/swdev/swdev.ts
$ swdev init myapp
$ cd myapp
$ swdev serve #=> localhost:7777
No Assets!
swdev init xxx
で生成したプロジェクトが、ローカルに swdev 用のアセットを生成しないようにしました。
swdev の開発環境として起動する /__swdev-client.js
と /__swdev-worker.js
はサーバー内に同梱したので、自分で静的アセットとして管理する必要がなくなりました。
なので、プロジェクトとしての最小パターンは index.html
だけで、 swdev serve
するだけになります。
(もしローカルにアセットがあったら、それを優先する、という処理が入っています。これは後でカスタマイズしたコンパイラをビルドして注入する口にするかも)
Correct Cache Buster!
ライブリロードでキャッシュ破棄する対象に、 import { x } from "./x.ts"
以外に、 import "./x.ts";
と export { x } from "./x.ts";
に対応しました。
Experimental: Local Read / Write
これが今回の一番のおもしろ機能です。
swdev serve --write
で起動すると、ブラウザ側からファイルの読み書きが可能になります。
// declare to touch
declare const DenoProxy: {
exec: any;
};
// GET ALL FILES
console.log(await DenoProxy.exec("getFiles")); // get current files
// READ
console.log(await DenoProxy.exec("readTextFile", "index.html"));
// WRITE: need -w
await DenoProxy.exec("writeTextFile", "foo.ts", "export default 1;");
元々サーバーがファイルを読むために Read 権限を持ってて、これを readFileText
という RPC としてブラウザ側から使えるように実装しました。ついでに、起動時に --write
オプションを付けると、ブラウザから指定ディレクトリに対するファイルの書き込みを許可します。(あとで --allow-write に変えるかも)
node や他の言語でも websocket rpc によるシステム命令の発行自体は可能だったんですが、面白いのは Deno 自体がアプリケーションレベルで環境変数の参照や書き込みスコープを制限できます。これで、今までより安心してユーザーに書き込み権限を渡すことができます。
現状はDenoProxy
のグローバル変数に生やしてて、 これは Deno の Deno
オブジェクトに真似てるつもりなんですが、あとで変更するかもしれません。
この DenoProxy
は production ビルド時は存在しません。ローカルで読み書きする想定。
次にやりたいこと: 自己書き換えエディタ
これを使ってブラウザ内で完結して自己書き換えができるエディタを作ろうとしています。口自体は用意したので、あとは実装するだけです。
ちょっと雑に作ってみたやつがあるんですが、雑なので多分捨てて書き直します。
元々、実験的に https://esnip.dev というサービスを作っていて、ここでは主にブラウザ上で TypeScript がバリバリ効くエディタを作っています。こいつを移植しようと考えています。
次にやりたいこと: ブラウザ内 Terminal
Deno Readline と xterm.js を使って、ブラウザ内からコマンドを安全に流せないか検討しています。
xtermjs/xterm.js: A terminal for the web
これで、swdev でセットアップした開発環境から、 git やそれ以外のコントロールができるようになるかもしれません。
コマンド直通ではなく、git 等のコマンド個別に Deno.run
をパーミッション付きで実行したほうがいいかも。
次にやりたいこと: Deno Deploy
Service Worker としてコンパイラで書き換えてる部分を、 Service Worker から Deno Deploy でも動くようにしようとしています。API が似てるのでいける気がしてます。
これができると、swdev をインストールせずに、組み込みのエディタと合わせて、誰かに手元の環境を双方向編集できるようになるかもしれません。
この際、バックエンドを実装する必要があり、GitHub API での読み書きとか、誰かがサーバーを立ててホストとして FS を公開してバックエンドになるとか考えていますが、まだ思いついていません。
その他: 設定
swdev.config.js
でコンパイラの設定できるとか、 ts や svelte 以外のカスタムコンパイラを挟めるようにしたい、みたいな気持ちがあります。
書き込みパーミッション等も設定できないか考えていますが、デフォルトでも動いて、あると読み込み、ぐらいの想定です。
今後
正直、 swdev で安定して開発できる、というより、今までにない面白機能を足していくことを優先しています。
ブラウザ開発はライブリロードのキャッシュ効率等から、ブラウザ内でやったほうがいい、という持論があります。それを実証することが自分の目標です。
Discussion