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

Deno 1.x in Practice: From Node.js to a More Secure Runtime

It's been two years since Deno 1.0 shipped. The 1.2x ecosystem has gradually matured, and Deno Deploy has given it real deployment scenarios. This article covers Deno's core philosophy and my hands-on experience with it.

Core Philosophy ​

Deno 和 Node.js 的设计差异:

特性Node.jsDeno
安全模型信任所有代码默认沙箱,需显式授权
模块系统CommonJS + ESM纯 ESM(URL 导入)
TypeScript需要编译原生支持
标准库需要 npm 包deno.land/std 标准库
工具链分散(npm + ts-node + eslint + jest)内置(格式化 + lint + 测试)

Basic Usage ​

typescript
// hello.ts
const greeting = (name: string): string => `Hello, ${name}!`;

console.log(greeting('Deno'));
bash
# 直接运行 TypeScript
deno run hello.ts

# 带权限
deno run --allow-net --allow-read server.ts

URL Imports ​

typescript
// 从 URL 导入,不需要 npm install
import { serve } from 'https://deno.land/std@0.170.0/http/server.ts';
import { oak } from 'https://deno.land/x/oak@v11.1.0/mod.ts';

// 也可以用 npm: 协议(Deno 1.28+)
import express from 'npm:express@4.18.2';

HTTP Server ​

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

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

router
  .get('/api/hello', (ctx) => {
    ctx.response.body = { message: 'Hello from Deno!' };
  })
  .get('/api/users/:id', async (ctx) => {
    const { id } = ctx.params;
    const user = await getUser(id);
    ctx.response.body = user;
  });

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

console.log('Server running on http://localhost:8000');
await app.listen({ port: 8000 });
bash
deno run --allow-net --allow-read server.ts

Permission System ​

typescript
// 读文件需要 --allow-read
const data = await Deno.readTextFile('./config.json');

// 写文件需要 --allow-write
await Deno.writeTextFile('./output.txt', data);

// 网络请求需要 --allow-net
const res = await fetch('https://api.example.com');

// 环境变量需要 --allow-env
const port = Deno.env.get('PORT') || '8000';

// 细粒度权限
// --allow-read=/tmp(只允许读 /tmp)
// --allow-net=api.example.com(只允许访问特定域名)

Built-in Tools ​

bash
# 格式化
deno fmt src/

# Lint
deno lint src/

# 测试
deno test

# 打包
deno bundle mod.ts dist/bundle.js

# 文档生成
deno doc mod.ts
typescript
// math.test.ts
import { assertEquals } from 'https://deno.land/std@0.170.0/testing/asserts.ts';
import { add, multiply } from './math.ts';

Deno.test('加法', () => {
  assertEquals(add(1, 2), 3);
});

Deno.test('乘法', () => {
  assertEquals(multiply(3, 4), 12);
});

Deno.test('异步测试', async () => {
  const result = await asyncAdd(1, 2);
  assertEquals(result, 3);
});

Standard Library ​

typescript
// 路径处理
import { join, extname } from 'https://deno.land/std@0.170.0/path/mod.ts';

const filePath = join('src', 'components', 'Button.tsx');
console.log(extname(filePath)); // .tsx

// 加密
import { crypto } from 'https://deno.land/std@0.170.0/crypto/mod.ts';

const hash = await crypto.subtle.digest(
  'SHA-256',
  new TextEncoder().encode('hello')
);
console.log(new Uint8Array(hash));

// 环境变量
import { config } from 'https://deno.land/std@0.170.0/dotenv/mod.ts';

const env = await config();
console.log(env.DATABASE_URL);

// HTTP 工具
import { serve } from 'https://deno.land/std@0.170.0/http/server.ts';

serve((req) => new Response('Hello!'), { port: 8000 });

Deno Deploy (Edge Deployment) ​

typescript
// deploy.ts — 部署到 Deno Deploy
addEventListener('fetch', (event: FetchEvent) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request: Request): Promise<Response> {
  const url = new URL(request.url);

  if (url.pathname === '/api/time') {
    return Response.json({
      time: new Date().toISOString(),
      region: Deno.env.get('DENO_REGION'),
    });
  }

  return new Response('Not Found', { status: 404 });
}

Deno Deploy 提供全球边缘网络,类似 Cloudflare Workers。

Real-World Problems ​

  1. 生态不够成熟:很多 npm 包在 Deno 上不能直接跑
  2. 企业采用少:生产环境很少用 Deno
  3. Deno.land 不稳定:依赖 URL 导入,版本管理不如 npm 方便
typescript
// 解决方案:用 import_map 管理依赖
// deno.json
{
  "imports": {
    "oak/": "https://deno.land/x/oak@v11.1.0/",
    "std/": "https://deno.land/std@0.170.0/"
  }
}

Summary ​

Deno 的理念是正确的——安全、TypeScript 原生、内置工具链。但 Node.js 的生态护城河太深,Deno 更适合作为特定场景(边缘计算、CLI 工具、安全敏感应用)的选择。2022 年的 Deno 适合体验和实验,不适合替代 Node.js。

MIT Licensed