denoで単一実行可能ファイルの出力（Windows）

# 手順

## 1, インストール
公式ページのインストール手順に従って導入
https://deno-ja.vercel.app/#installation

今回は`PowerShell (Windows)`の方法でインストール

```powershell
iwr https://deno.land/x/install/install.ps1 -useb | iex
```

今回の使用バージョンは`1.10.1`

```powershell
> deno -V
deno 1.10.1
```

## 2, とりあえず出力してみる（Hello World）
公式マニュアルのTypeScriptのhello-world.tsを利用
https://deno-ja.vercel.app/manual@main/examples/hello_world#typescript

適当なフォルダにソースコードを作成し、下記のコマンドを実行

```powershell
deno compile hello-world.ts
```

成功するとexeが生成される

```powershell
> deno compile hello-world.ts
Check file:///path/to/edit_file/hello-world.ts
Bundle file:///path/to/edit_file/hello-world.ts
Compile file:///path/to/edit_file/hello-world.ts
Emit hello-world
```

生成されたexeファイルを実行して問題なく出力されることを確認

```powershell
> hello-world.exe   
Hello John
Hello Sarah
Hello Kai
```

## 3, 権限が必要な処理を出力
denoはセキュリティのため、実行時に権限の指定が必要になる
それは、`deno run`の場合だけでなく`deno compile`でも必要で権限を付与していないと実行時エラーとなる
JSONファイルを読み込み、編集して書き出すコードを用意
今回は、`edit_file`というフォルダを作成し、その直下にファイルを配置

```main.ts
const data = await Deno.readTextFile("./input.json")
const jsondata = JSON.parse(data)

jsondata["item0"] = "999"

await Deno.writeTextFile("./output.json", JSON.stringify(jsondata, null, 4))
```

```input.json
{
    "item0": "000",
    "item1": "111"
}
```

exeを生成・実行

```powershell
PS \path\to\edit_file> deno compile main.ts  
Check file:///path/to/edit_file/edit_file/main.ts
Bundle file:///path/to/edit_file/edit_file/main.ts
Compile file:///path/to/edit_file/edit_file/main.ts
Emit edit_file

PS \path\to\edit_file> .\edit_file.exe
error: PermissionDenied: Requires read access to "./input.json", run again with the --allow-read flag
    at deno:core/core.js:86:46
    at unwrapOpResult (deno:core/core.js:106:13)
    at async open (deno:runtime/js/40_files.js:46:17)
    at async Object.readTextFile (deno:runtime/js/40_read_file.js:40:18)
    at async file://$deno$/bundle.js:1:14
```

ファイルの読み込みに必要な権限がないとエラーになり`--allow-read`を指定するように求められたため、付与して再度生成・実行

```powershell
PS path\to\edit_file\edit_file> deno compile --allow-read main.ts
Check file:///path/to/edit_file/edit_file/main.ts
Bundle file:///path/to/edit_file/edit_file/main.ts
Compile file:///path/to/edit_file/edit_file/main.ts
Emit edit_file
PS \path\to\edit_file\edit_file> .\edit_file.exe
error: PermissionDenied: Requires write access to "./output.json", run again with the --allow-write flag
    at deno:core/core.js:86:46
    at unwrapOpResult (deno:core/core.js:106:13)
    at async open (deno:runtime/js/40_files.js:46:17)
    at async writeFile (deno:runtime/js/40_write_file.js:58:18)
    at async file://$deno$/bundle.js:4:1
PS \path\to\edit_file\edit_file>
```

今度はファイルの書き出しに必要な権限がないとエラーになり`--allow-write`を指定するように求められた
付与して再度生成・実行

```powershell
PS \path\to\edit_file\edit_file> deno compile --allow-read --allow-write main.ts 
Check file:///path/to/edit_file/edit_file/main.ts
Bundle file:///path/to/edit_file/edit_file/main.ts
Compile file:///path/to/edit_file/edit_file/main.ts
Emit edit_file
PS \path\to\edit_file\edit_file> .\edit_file.exe
```

無事エラーが発生せず実行完了
出力されたファイルもちゃんと書き換わった内容が反映されていることを確認

```output.json
{
    "item0": "999",
    "item1": "111"
}
```

（生成したexeを別PCで実行する確認ができていないので何か問題発生するかもしれない。分かり次第追記予定）

## 権限付与に関して補足

`--allow-all`を付与するとすべての権限が与えられるので上記のようなエラーは発生しなくなるが、不要な権限を与えることににもなるため使用する際は慎重に

```powershell
PS \path\to\edit_file\edit_file> deno compile --allow-all main.ts
```

## バイナリサイズに関して
`helloworld.exe`で**約55MB**！とでかい
`deno.exe`が同様に55MB程なのでこれがまるごと入っている雰囲気なので仕方なし・・・

# 調査の経緯
仕事柄、プログラマー以外の職種へツールを提供することが多い。
そのため、簡単にシングルバイナリを作成して提供できる方法を探しており、現在のところGoを候補にしていたが、denoの情報を見ていると`deno compile`という単一実行可能ファイル(exe)を生成するためのコマンドが標準で存在しているようだったので、使ってみると意外と簡単だったのでこちらも現在候補に入れて確認中。