Skip to content
⚠️ This article was written in 2020. Some content may be outdated.

Deno 1.0 正式リリース:実際に使えるのか?

Deno 1.0 がついにリリースされた。Node.js の生みの親である Ryan Dahl による「2 回目の挑戦」であり、Node.js の十大設計上の後悔を是正している。1.0 を迎えたこの機会に、プロジェクトでの採用に耐えるかどうかを真剣に評価してみる。

Deno の中心的な売り ​

typescript
// 1. 安全:默认沙箱,需要显式授权
// 运行这个脚本会报错
const text = await Deno.readTextFile('/etc/hosts');
// error: Uncaught PermissionDenied

// 需要 --allow-read
deno run --allow-read script.ts

// 2. TypeScript 原生支持
interface User {
  name: string;
  age: number;
}

function greet(user: User): string {
  return `你好 ${user.name},你 ${user.age} 岁了`;
}

console.log(greet({ name: '张三', age: 28 }));
// 直接运行,不需要 tsconfig.json
// deno run greet.ts

// 3. 标准库
import { serve } from 'https://deno.land/std@0.50.0/http/server.ts';
import { readJson } from 'https://deno.land/std@0.50.0/fs/read_json.ts';

Node.jsとの詳細比較 ​

markdown
| 特性         | Node.js              | Deno                 |
|-------------|----------------------|----------------------|
| 语言         | JavaScript           | TypeScript 原生      |
| 模块系统     | CommonJS + node_modules | ES Modules + URL  |
| 包管理       | npm / yarn           | URL 直接导入         |
| 安全模型     | 无限制               | 沙箱 + 显式授权       |
| 异步         | Callback → Promise   | 原生 async/await     |
| 标准库       | 无(依赖 npm)        | 内置标准库           |
| 工具链       | 需要额外配置          | 内置 test/lint/format |
| TypeScript   | 需要 ts-node         | 原生支持             |

内置工具链 ​

bash
# 测试
deno test

# 代码检查
deno lint

# 格式化
deno fmt

# 文档生成
deno doc

# 依赖树
deno info script.ts
typescript
// Deno.test 内置测试框架
Deno.test('加法测试', () => {
  const result = 1 + 2;
  if (result !== 3) {
    throw new Error('1 + 2 应该等于 3');
  }
});

Deno.test('异步测试', async () => {
  const response = await fetch('https://httpbin.org/get');
  const data = await response.json();
  console.assert(data.url === 'https://httpbin.org/get');
});

実際に小さなサービスを書いてみる ​

typescript
// server.ts
import { Application, Router } from 'https://deno.land/x/oak@v5.0.0/mod.ts';

const app = new Application();
const router = new Router();

interface Todo {
  id: number;
  title: string;
  completed: boolean;
}

let todos: Todo[] = [];
let nextId = 1;

router
  .get('/api/todos', (ctx) => {
    ctx.response.body = todos;
  })
  .post('/api/todos', async (ctx) => {
    const body = await ctx.request.body();
    const todo: Todo = {
      id: nextId++,
      title: body.value.title,
      completed: false,
    };
    todos.push(todo);
    ctx.response.status = 201;
    ctx.response.body = todo;
  })
  .delete('/api/todos/:id', (ctx) => {
    const id = Number(ctx.params.id);
    todos = todos.filter(t => t.id !== id);
    ctx.response.status = 204;
  });

app.use(router.routes());
app.use(router.allowedMethods());

console.log('服务器运行在 http://localhost:8000');
await app.listen({ port: 8000 });
bash
deno run --allow-net server.ts

現時点での実際の課題 ​

markdown
1. 生态太小:npm 有 130 万个包,Deno 的第三方模块很少
2. 企业支持:没有大公司在生产环境使用
3. 兼容性:很多 npm 包无法直接使用
4. IDE 支持:VSCode 插件还在早期
5. 部署方案:没有 PM2 这样的进程管理
6. 调试:Chrome DevTools 支持有,但体验不如 Node.js

どんなときに Deno を検討できるか ​

markdown
适合:
- 个人工具脚本(替代 Python/Shell)
- 小型 API 服务
- 技术预研和学习
- CLI 工具

暂时不适合:
- 企业级项目
- 需要大量 npm 依赖的项目
- 性能关键的后端服务
- 需要 C++ addon 的项目

まとめ ​

  • Deno 1.0 はセキュリティと開発体験の面で確かに Node.js より優れている
  • TypeScript・テスト・lint・フォーマットを内蔵し、導入直後から使える
  • URL インポートによって node_modules が不要になった一方で、バージョン管理の問題を生む
  • エコシステムが最大の弱点で、npm のエコシステムは数年では追いつかない
  • 2020 年時点ではツール系スクリプトでの利用が現実的で、本番プロジェクトでは引き続き Node.js を使うべきだ

MIT Licensed