Denoとは
DenoはRyan Dahl(Node.js作者)が開発した、セキュアなJavaScript/TypeScriptランタイムです。TypeScriptをネイティブサポートし、デフォルトでセキュアな権限システムを持ちます。
インストール
# macOS / Linux
curl -fsSL https://deno.land/install.sh | sh
# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex
# Homebrew
brew install deno
# バージョン確認
deno --version
基本的な使い方
スクリプト実行
# TypeScriptを直接実行
deno run hello.ts
# URLから直接実行
deno run https://deno.land/std/examples/welcome.ts
# REPLモード
deno
権限システム
# ネットワークアクセス許可
deno run --allow-net server.ts
# ファイル読み込み許可
deno run --allow-read app.ts
# ファイル書き込み許可
deno run --allow-write app.ts
# 環境変数アクセス許可
deno run --allow-env app.ts
# 全権限(開発時のみ)
deno run -A app.ts
# 特定ホストのみ許可
deno run --allow-net=api.example.com app.ts
# 特定ディレクトリのみ許可
deno run --allow-read=/tmp app.ts
HTTPサーバー
標準ライブラリ
// server.ts
import { serve } from "https://deno.land/std@0.220.0/http/server.ts";
const handler = (request: Request): Response => {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response("Hello, Deno!");
}
if (url.pathname === "/api/users") {
return Response.json([
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
]);
}
return new Response("Not Found", { status: 404 });
};
console.log("Server running on http://localhost:8000");
serve(handler, { port: 8000 });
Deno.serve(推奨)
// server.ts(Deno 1.35+)
Deno.serve({ port: 8000 }, (request: Request) => {
const url = new URL(request.url);
if (url.pathname === "/") {
return new Response("Hello, Deno!");
}
return new Response("Not Found", { status: 404 });
});
Oakフレームワーク
// oak-server.ts
import { Application, Router } from "https://deno.land/x/oak@v12.6.1/mod.ts";
const router = new Router();
router.get("/", (ctx) => {
ctx.response.body = "Hello, Oak!";
});
router.get("/api/users", (ctx) => {
ctx.response.body = [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" },
];
});
router.post("/api/users", async (ctx) => {
const body = await ctx.request.body().value;
ctx.response.status = 201;
ctx.response.body = { created: body };
});
const app = new Application();
app.use(router.routes());
app.use(router.allowedMethods());
console.log("Server running on http://localhost:8000");
await app.listen({ port: 8000 });
ファイル操作
// ファイル読み込み
const text = await Deno.readTextFile("data.txt");
console.log(text);
// JSON読み込み
const json = JSON.parse(await Deno.readTextFile("config.json"));
// バイナリ読み込み
const bytes = await Deno.readFile("image.png");
// ファイル書き込み
await Deno.writeTextFile("output.txt", "Hello, World!");
// JSON書き込み
await Deno.writeTextFile(
"data.json",
JSON.stringify({ key: "value" }, null, 2)
);
// ディレクトリ操作
await Deno.mkdir("new-folder", { recursive: true });
await Deno.remove("old-file.txt");
// ファイル情報取得
const stat = await Deno.stat("file.txt");
console.log(stat.size, stat.mtime);
環境変数
// 環境変数の取得
const apiKey = Deno.env.get("API_KEY");
const dbUrl = Deno.env.get("DATABASE_URL") ?? "localhost";
// 全環境変数
const allEnv = Deno.env.toObject();
console.log(allEnv);
// .envファイルの読み込み
import { load } from "https://deno.land/std@0.220.0/dotenv/mod.ts";
const env = await load();
console.log(env.DATABASE_URL);
npm互換性
// npm:プレフィックスでnpmパッケージを使用
import express from "npm:express@4";
import _ from "npm:lodash";
const app = express();
app.get("/", (req, res) => {
res.send("Hello from Express on Deno!");
});
app.listen(3000);
// deno.json
{
"imports": {
"express": "npm:express@4",
"lodash": "npm:lodash@4"
}
}
Import Maps
// deno.json
{
"imports": {
"@std/": "https://deno.land/std@0.220.0/",
"oak": "https://deno.land/x/oak@v12.6.1/mod.ts",
"zod": "https://deno.land/x/zod@v3.22.4/mod.ts"
}
}
// エイリアスで簡潔に
import { serve } from "@std/http/server.ts";
import { Application } from "oak";
import { z } from "zod";
テスト
// sum.test.ts
import { assertEquals, assertThrows } from "https://deno.land/std@0.220.0/assert/mod.ts";
import { sum, divide } from "./sum.ts";
Deno.test("sum adds two numbers", () => {
assertEquals(sum(1, 2), 3);
});
Deno.test("sum handles negative numbers", () => {
assertEquals(sum(-1, 1), 0);
});
Deno.test("divide throws on zero", () => {
assertThrows(
() => divide(10, 0),
Error,
"Division by zero"
);
});
// 非同期テスト
Deno.test("fetch data", async () => {
const response = await fetch("https://api.example.com/data");
assertEquals(response.status, 200);
});
# テスト実行
deno test
# 特定ファイル
deno test sum.test.ts
# ウォッチモード
deno test --watch
# カバレッジ
deno test --coverage=coverage
deno coverage coverage
タスクランナー
// deno.json
{
"tasks": {
"dev": "deno run --watch --allow-net server.ts",
"start": "deno run --allow-net server.ts",
"test": "deno test --allow-read",
"lint": "deno lint",
"fmt": "deno fmt"
}
}
deno task dev
deno task test
コンパイル
# 単一実行ファイルにコンパイル
deno compile --allow-net server.ts
# クロスコンパイル
deno compile --target x86_64-unknown-linux-gnu server.ts
deno compile --target x86_64-apple-darwin server.ts
deno compile --target x86_64-pc-windows-msvc server.ts
Node.jsとの違い
| 特徴 | Deno | Node.js |
|---|---|---|
| TypeScript | ネイティブサポート | 要トランスパイル |
| セキュリティ | デフォルトでセキュア | 制限なし |
| パッケージ管理 | URLインポート/npm: | npm/yarn |
| 設定ファイル | deno.json(オプション) | package.json必須 |
| 標準ライブラリ | 充実 | 最小限 |
| ES Modules | デフォルト | CommonJS中心 |
関連記事
- Bun入門 - 別のモダンランタイム
- Node.js Express - 従来の選択肢
- Honoフレームワーク - 軽量Webフレームワーク
まとめ
Denoは、セキュリティとTypeScriptサポートを重視したモダンなランタイムです。権限システムにより安全な実行環境を提供し、npm互換性により既存のエコシステムも活用できます。
← 一覧に戻る