[Deno] 開発環境構築 例 VSCode

1.インストール
https://deno.com/
・単体で動くJavaScriptの実行環境
・Node.jsを作った人がNode.jsの設計ミスから新しく作った

#denoのインストール(システムグローバル)
## Linux
$ curl -fsSL https://deno.land/x/install/install.sh | sh

## Windows PowerShell
$ iwr https://deno.land/x/install/install.ps1 -useb | iex

# バージョンを指定してインストール
$ deno upgrade --version 1.3.0

# deno自体を最新版にアップグレード
$ deno upgrade

※Deno自体は単一の実行可能ファイルなので余計なパスを生成しないzipファイルをDLしてもよい。
※複数バージョンを利用したい場合は環境切り替えツールを使うか、実行可能ファイルをリネームして使う(deno2.1.exe deno2.2.exeなど)
※キャッシュ(外部ライブラリ)自体はバージョン毎に保持されている。


2.実行
deno.json のタスクを使う(推奨)
deno.json に以下のように記述しプロジェクト内のDenoを意識せず実行する。
{
    "tasks": {
        // deno.json 内の "imports" に書かれたURLの更新を「確認」する
        "check-update": "./bin/deno.exe run --allow-read --allow-net https://deno.land/x/molt/main.ts ./deno.json",

        // deno.json 内のURL(バージョン数字)を最新に「書き換える」
        "update": "./bin/deno.exe run --allow-read --allow-write --allow-net https://deno.land/x/molt/main.ts --write ./deno.json",

        "backup": "DENO_DIR=./.deno_cache ./bin/deno.exe run --allow-all scripts/backup.ts",

        "dev": "DENO_DIR=./.deno_cache ./bin/deno.exe run --allow-all --watch main.ts",
        "release": "DENO_DIR=./.deno_cache ./bin/deno.exe run --allow-write --allow-run scripts/build.ts",

        "dev-2.5.6": "DENO_DIR=./.deno_cache ./bin/deno-2.5.6.exe run --allow-all --watch main.ts",
        "release-2.5.6": "DENO_DIR=./.deno_cache ./bin/deno-2.5.6.exe run --allow-write --allow-run scripts/build.ts",
    }
}
$ deno task dev # システムグローバルのDenoから起動する $ ./bin/deno task dev # プロジェクト内のDenoから起動する ※tasksではプロジェクト内のDenoを使う記述なのでどちらで起動しても同じ ※deno task (引数なし) を実行すると deno.json に登録されているタスク名と実行内容の一覧が表示される。 3.VSCodeで使う方法 ・プロジェクトディレクト内で完結する持ち運び可能な構成 ・Deno自体を格納する(./bin/deno.exe) ・プロジェクトで使う実行時に必要なDeno関連の追加モジュール(./.deno_cache) ☆必須拡張機能 Deno (公式)   拡張機能 ID: denoland.vscode-deno   提供元: denoland (Deno公式チーム)   役割: 型チェック、補完、フォーマット(整形)、リント(構文チェック)、デバッグ、テスト実行など、Deno開発に必要なすべての機能が含まれている。 3.1.設定ファイルの書き方 プロジェクトディレクトリ配下 .vscode/settings.json
{
    "deno.enable": true,
    "deno.lint": true,
    "deno.cacheOnSave": true,

    "deno.path": "./bin/deno.exe", 
    "terminal.integrated.env.windows": {
        "DENO_DIR": "./.deno_cache"
    },
}
・settings.json の "deno.path" は単一のパスしか保持できない。 ・エディタの補完(IntelliSense)に使うDeno本体を切り替えたい場合は deno.path を手動で書き換える必要がある。 3.2.推奨されるディレクトリ構成の例 my-project/ ├── .deno_cache/ プロジェクト専用キャッシュ ├── .vscode/ │ ├── settings.json VS Code拡張機能・ターミナルの設定 │ └── launch.json F5デバッグの設定 ├── bin/ │ └── deno.exe 特定バージョンのDeno本体 ├── scripts/ │ ├── build.ts リリース物生成 │ └── backup.ts 全体バックアップ ├── dist/ 自動作成されるリリース用生成物 ├── src/ ソースコード階層 │ ├── auth/ │ │ ├── mod.ts パッケージの玄関口 │ │ └── login.ts 内部ロジック │ └── utils/ 共通ユーティリティ │ ├── mod.ts パッケージの玄関口 │ └── logger.ts 内部ロジック ├── .gitignore git非対象パスの指定 ├── deno.json プロジェクト設定・タスク定義 └── main.ts エントリーポイント 3.3.インポートは相対パスで main.ts から auth パッケージを呼び出す場合は以下のように書く。
import { login } from "./src/auth/mod.ts";
3.4.mod.ts という慣習 Deno(およびRustなど)の世界では、ディレクトリ内の機能を外部に公開するファイル名を mod.ts とするのが一般的。Pythonの __init__.py と同じ役割で、そのディレクトリ内の「玄関口」になる。 3.5.deno.json でのパス解決(インポートマップ) 階層が深くなって ./../../ と書くのが面倒な場合は deno.json にエイリアス(別名)を設定する。
{
    "tasks": { ... },   // ここの詳細は上記を参照
    "imports": {
        // 外部ライブラリ
        "path": "https://deno.land/std@0.224.0/path/mod.ts",
        "zipjs": "https://deno.land/x/zipjs@v2.7.53/index.js",

        // 内部パッケージ
        "@auth/": "./src/auth/",
    } 
}
こうすると、どこからでも import { ... } from "@auth/mod.ts" で呼び出せるようになり、Pythonのパッケージインポートに近い感覚になる。 3.6.gitを使う場合 この構成をGitで管理する場合は .deno_cache/ は絶対に .gitignore に入れる。 理由: キャッシュにはダウンロードされた膨大な外部ライブラリが含まれるため、Gitのリポジトリが巨大化する。 推奨される .gitignore
.deno_cache/
dist/
4.実装のイメージ 4.1.内部ロジック (src/auth/login.ts)
export function authenticate(user: string): string {
    return `${user} は認証されました`;
}
4.2.玄関口 (src/auth/mod.ts) Pythonの from .login import authenticate に相当する
// 内部の必要な機能だけを選んで再エクスポート(Re-export)する
export { authenticate } from "./login.ts";
4.3.利用側(main.ts) インポートマップで定義したエイリアス、または mod.ts を直接指定して機能を呼び出す。
// パターンA:インポートマップ(deno.json)で設定した別名を使う場合
import { authenticate } from "@auth";

// パターンB:相対パスで直接指定する場合(拡張子まで必須)
// import { authenticate } from "./src/auth/mod.ts";

console.log(authenticate("Deno太郎"));
4.4.Denoならではのポイント 明示的な指定: Denoでは ./src/auth のようにディレクトリ名で止めることはできず、必ず mod.ts などのファイル名と .ts 拡張子まで書くのが基本ルール。 カプセル化: login.ts に関数が多数あっても、mod.ts で export しない限り外部からは見えない。これによりパッケージの独立性を保てる。 5.デバッグ 5.1.F5でデバックするための設定 プロジェクトディレクトリ配下 .vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
      {
          "name": "Deno: Run (Standard)",
          "type": "deno",
          "request": "launch",
          "runtimeExecutable": "${workspaceFolder}/bin/deno.exe", // 標準のdeno.exe
          "cwd": "${workspaceFolder}",
          "program": "main.ts",
          "args": ["run", "--allow-all", "--inspect-wait"],
          "env": { "DENO_DIR": "./.deno_cache" },
          "attachMode": "tab"
      },
      {
          "name": "Deno: Run (v2.5.6)",
          "type": "deno",
          "request": "launch",
          "runtimeExecutable": "${workspaceFolder}/bin/deno-2.5.6.exe", // 特定バージョン
          "cwd": "${workspaceFolder}",
          "program": "main.ts",
          "args": ["run", "--allow-all", "--inspect-wait"],
          "env": { "DENO_DIR": "./.deno_cache" },
          "attachMode": "tab"
      }
    ]
}
設定のポイント 1.runtimeExecutable: ここにプロジェクト内の deno.exe をフルパス(変数を活用)で指定することで、システムのDenoではなく「そのプロジェクト専用のDeno」でデバッグが走る。 2.env: 実行時にもプロジェクト内のキャッシュディレクトリ(DENO_DIR)を強制的に参照させる。 3.--inspect-wait: デバッガーが接続されるまでプログラムの実行を待機させるフラグ。これにより、最初の1行目からステップ実行が可能になる。 6.リリース Windows以外の環境ならShebang(#!/usr/bin/env deno)が有効なので .ts ファイルのままでも実行可能。 Windows環境を含めた配布を考えるなら deno compile によるバイナリ化が最適。 6.1.scripts/build.ts 実行可能モジュールとしてリリースする場合はコンパル用のバッチプログラムを作っておく。
// 1. 保存先ディレクトリの作成
const distDir = "./dist";
await Deno.mkdir(distDir, { recursive: true });

// 2. 日時スタンプの生成
const now = new Date();
const pad = (n: number) => n.toString().padStart(2, "0");
const timestamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}_${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;

// 3. 出力パスの組み立て
const outputName = `myapp_v${timestamp}.exe`;
const outputPath = `${distDir}/${outputName}`;

console.log(`Building to: ${outputPath}...`);

// 4. コンパイル実行
const command = new Deno.Command("./bin/deno.exe", {
    args: [
      "compile",
      "--allow-all",
      "--output", outputPath, // dist/フォルダ内を指定
      "main.ts"
    ],
    env: {
      "DENO_DIR": "./.deno_cache" // ここでもキャッシュ場所を指定
    }
});

const { success, stderr } = await command.output();

if(success) {
    console.log(`Successfully created: ${outputPath}`);
}
else {
    console.error("Compile failed:");
    console.error(new TextDecoder().decode(stderr));
}
7.プロジェクトのバックアップ (scripts/backup.ts) プロジェクト全体をZIPにまとめ、親ディレクトリへ退避させるスクリプト。 ※実行には最新の std/archive モジュールを利用する想定。 7.1.scripts/backup.ts の実装
// deno.json のエイリアスを利用する場合のimport記述 
import * as path from "path";
import { compress } from "zipjs";

// 1. パスの準備
const projectRoot = Deno.cwd();
const projectName = path.basename(projectRoot);
const parentDir = path.dirname(projectRoot);

// 2. タイムスタンプ生成 (YYYYMMDDhhmmss)
const now = new Date();
const pad = (num: number) => num.toString().padStart(2, "0");
const timestamp = [
    now.getFullYear(),
    pad(now.getMonth() + 1),
    pad(now.getDate()),
    pad(now.getHours()),
    pad(now.getMinutes()),
    pad(now.getSeconds())
].join("");

// 3. 出力ファイル名の組み立て (親ディレクトリに配置)
const backupFileName = `${projectName}-backup-${timestamp}.zip`;
const backupPath = path.join(parentDir, backupFileName);

console.log(`Creating backup: ${backupPath}...`);

// 4. 圧縮実行 (プロジェクトディレクトリ全体を対象)
try {
    await compress(projectRoot, backupPath, {
      overwrite: true,
    });

    console.log(`Successfully backed up to: ${backupPath}`);
}
catch(err) {
    console.error("Backup failed:", err);
}