@computesdk/vercel

中文文档
1.7.54发布于 2026/11/06MITTypeScriptESM + CJS构建来源已验证近 30 天下载 1.3万

ComputeSDK的Vercel Sandbox提供商 - Vercel边缘网络上的Python和Node.js的无服务器代码执行

中文使用文档
文档目录24 节
  1. 安装
  2. 认证
  3. 方法1: OIDC Token(建议)
  4. 方法2:访问托肯+团队/项目ID
  5. 快速启动
  6. 配置
  7. 环境变量
  8. 配置选项
  9. 特征
  10. API 参考
  11. 命令执行
  12. 文件系统操作
  13. 沙盒管理
  14. 持久性
  15. 处理错误
  16. 实例
  17. 节点.js Web 服务器模拟
  18. Python 数据处理
  19. 文件系统操作管道
  20. 软件包安装和使用
  21. 最佳做法
  22. 限制
  23. 支助
  24. 许可证

@ computesdk/ vercel (帮助)

ComputeSDK的Vercel提供商-在安全,孤立的Vercel沙盒中执行Node.js和Python代码.

安装

npm install @computesdk/vercel

认证

Vercel提供者支持两种认证方法:

最简单的认证方法。 Vercel 管理符号自动过期 .

发展:

vercel env pull  # Downloads VERCEL_OIDC_TOKEN to .env.local

生产: Vercel自动提供 VERCEL_OIDC_TOKEN 在您的部署环境中.

方法2:访问托肯+团队/项目ID

使用明确证书的替代方法:

export VERCEL_TOKEN=your_vercel_token_here
export VERCEL_TEAM_ID=your_team_id_here
export VERCEL_PROJECT_ID=your_project_id_here

从 Vercel 账户托肯斯

快速启动

import { vercel } from '@computesdk/vercel';

const compute = vercel({
  token: process.env.VERCEL_TOKEN,
  teamId: process.env.VERCEL_TEAM_ID,
  projectId: process.env.VERCEL_PROJECT_ID,
  timeout: 600000 // 10 minutes
});

const sandbox = await compute.instances.create();

const result = await sandbox.runCommand('node -e "console.log(\"Hello from Vercel!\")"');
console.log(result.stdout);

await sandbox.destroy();

OIDC 信使( O)VERCEL_OIDC_TOKEN当配置中没有提供明确的证书时,则自动从环境中发现.

配置

环境变量

# Method 1: OIDC Token (Recommended)
export VERCEL_OIDC_TOKEN=your_oidc_token_here

# Method 2: Traditional
export VERCEL_TOKEN=your_vercel_token_here
export VERCEL_TEAM_ID=your_team_id_here
export VERCEL_PROJECT_ID=your_project_id_here

配置选项

interface VercelConfig {
  /** Vercel API token - if not provided, will use VERCEL_TOKEN env var */
  token?: string;
  /** Vercel team ID - if not provided, will use VERCEL_TEAM_ID env var */
  teamId?: string;
  /** Vercel project ID - if not provided, will use VERCEL_PROJECT_ID env var */
  projectId?: string;
  /** Execution timeout in milliseconds */
  timeout?: number;
  /** Ports to expose */
  ports?: number[];
}

特征

  • ✅ 命令执行 - 在沙盒中运行外壳命令(Node.js 22, Python 3. 13 可用)
  • ✅ 文件系统操作 - 通过 shell 命令访问完整文件系统
  • ✅ 长期任务 - 最多45分钟的处决时间
  • ✅ 全球基础设施 - 在Vercel的全球网络上运行
  • ❌ 交互式终端 - 由Vercel Sandbox不支持
  • ❌ 沙盒重联 - 沙盒为麻黄(单一使用)

API 参考

命令执行

// Run Node.js code via heredoc
const result = await sandbox.runCommand(`node - <<'JS'
const data = { message: "Hello from Node.js" };
console.log(JSON.stringify(data));
JS`);

// Run Python code via heredoc
const result = await sandbox.runCommand(`python - <<'PY'
import json
data = {"message": "Hello from Python"}
print(json.dumps(data))
PY`);

// List files
const result = await sandbox.runCommand('ls -la');

// Install packages (Node.js)
const result = await sandbox.runCommand('npm install lodash');

// Install packages (Python)
const result = await sandbox.runCommand('pip install requests');

// Run scripts
const result = await sandbox.runCommand('node script.js');

文件系统操作

// Write file
await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello World")');

// Read file
const content = await sandbox.filesystem.readFile('/tmp/hello.py');

// Create directory
await sandbox.filesystem.mkdir('/tmp/data');

// List directory contents
const files = await sandbox.filesystem.readdir('/tmp');

// Check if file exists
const exists = await sandbox.filesystem.exists('/tmp/hello.py');

// Remove file or directory
await sandbox.filesystem.remove('/tmp/hello.py');

沙盒管理

// Get sandbox info
const info = await sandbox.getInfo();
console.log(info.id, info.provider, info.status);

// Get existing sandbox
const existing = await compute.instances.getById('sandbox-id');

// Destroy sandbox
await compute.instances.destroy('sandbox-id');

// Note: Vercel doesn't support listing all sandboxes
// Each sandbox is ephemeral and single-use

持久性

创建了沙盒 persistent: false 默认情况下 —— 持续沙盒自动拍摄其文件系统 stop(),它累积了Vercel快照存储费。 选择坚持(如果计划以后恢复或快照沙盒就需要),通过 persistent: true (或共享的) ephemeral: false 创建时间 :

const sandbox = await compute.instances.create({ persistent: true });

处理错误

import { vercel } from '@computesdk/vercel';

try {
  const compute = vercel({ 
    token: process.env.VERCEL_TOKEN,
    teamId: process.env.VERCEL_TEAM_ID,
    projectId: process.env.VERCEL_PROJECT_ID
  });
  const sandbox = await compute.instances.create();
  
  const result = await sandbox.runCommand('invalid code');
} catch (error) {
  if (error.message.includes('Missing Vercel authentication')) {
    console.error('Set VERCEL_OIDC_TOKEN or VERCEL_TOKEN environment variables');
  } else if (error.message.includes('authentication failed')) {
    console.error('Check your Vercel credentials');
  } else if (error.message.includes('team/project configuration failed')) {
    console.error('Check your VERCEL_TEAM_ID and VERCEL_PROJECT_ID');
  } else if (error.message.includes('Syntax error')) {
    console.error('Code has syntax errors');
  }
}

实例

节点.js Web 服务器模拟

import { vercel } from '@computesdk/vercel';

const compute = vercel({});
const sandbox = await compute.instances.create();

const result = await sandbox.runCommand(`node - <<'JS'
const http = require('http');
const url = require('url');

// Simulate API endpoints
const routes = {
  '/api/users': () => ({
    users: [
      { id: 1, name: 'Alice', role: 'Developer' },
      { id: 2, name: 'Bob', role: 'Designer' }
    ]
  }),
  '/api/health': () => ({ 
    status: 'healthy', 
    timestamp: new Date().toISOString() 
  })
};

// Process request
const path = '/api/users';
const response = routes[path] ? routes[path]() : { error: 'Not found' };

console.log('Response:', JSON.stringify(response, null, 2));
JS`);

console.log(result.stdout);
await sandbox.destroy();

Python 数据处理

import { vercel } from '@computesdk/vercel';

const compute = vercel({});
const sandbox = await compute.instances.create();

const result = await sandbox.runCommand(`python - <<'PY'
import json
import statistics
from collections import Counter

# Sample data
sales_data = [
    {"product": "laptop", "quantity": 5, "price": 999},
    {"product": "mouse", "quantity": 20, "price": 25},
    {"product": "keyboard", "quantity": 15, "price": 75},
    {"product": "laptop", "quantity": 3, "price": 999},
    {"product": "mouse", "quantity": 10, "price": 25}
]

# Aggregate sales
product_sales = {}
for sale in sales_data:
    product = sale["product"]
    revenue = sale["quantity"] * sale["price"]
    product_sales[product] = product_sales.get(product, 0) + revenue

# Calculate statistics
revenues = list(product_sales.values())
total_revenue = sum(revenues)
avg_revenue = statistics.mean(revenues)

print(f"Total Revenue: ${total_revenue}")
print(f"Average Revenue per Product: ${avg_revenue:.2f}")
print("\\nRevenue by Product:")
for product, revenue in sorted(product_sales.items(), key=lambda x: x[1], reverse=True):
    print(f"  {product}: ${revenue}")
PY`);

console.log(result.stdout);
await sandbox.destroy();

文件系统操作管道

import { vercel } from '@computesdk/vercel';

const compute = vercel({});
const sandbox = await compute.instances.create();

// Create project structure
await sandbox.filesystem.mkdir('/tmp/project');
await sandbox.filesystem.mkdir('/tmp/project/data');
await sandbox.filesystem.mkdir('/tmp/project/output');

// Create configuration file
const config = {
  project_name: "Vercel Data Pipeline",
  version: "1.0.0",
  settings: {
    input_format: "json",
    output_format: "csv",
    debug: true
  }
};

await sandbox.filesystem.writeFile(
  '/tmp/project/config.json', 
  JSON.stringify(config, null, 2)
);

// Create sample data
const sampleData = [
  { id: 1, name: "Alice", department: "Engineering", salary: 95000 },
  { id: 2, name: "Bob", department: "Marketing", salary: 75000 },
  { id: 3, name: "Charlie", department: "Engineering", salary: 105000 },
  { id: 4, name: "Diana", department: "Sales", salary: 85000 }
];

await sandbox.filesystem.writeFile(
  '/tmp/project/data/employees.json',
  JSON.stringify(sampleData, null, 2)
);

// Process data
const result = await sandbox.runCommand(`python - <<'PY'
import json
import csv
from collections import defaultdict

# Read configuration
with open('/tmp/project/config.json', 'r') as f:
    config = json.load(f)

print(f"Running {config['project_name']} v{config['version']}")

# Read employee data
with open('/tmp/project/data/employees.json', 'r') as f:
    employees = json.load(f)

# Process data - calculate department statistics
dept_stats = defaultdict(list)
for emp in employees:
    dept_stats[emp['department']].append(emp['salary'])

# Calculate averages
results = []
for dept, salaries in dept_stats.items():
    avg_salary = sum(salaries) / len(salaries)
    results.append({
        'department': dept,
        'employee_count': len(salaries),
        'average_salary': round(avg_salary, 2),
        'total_salary': sum(salaries)
    })

# Sort by average salary
results.sort(key=lambda x: x['average_salary'], reverse=True)

# Write results as JSON
with open('/tmp/project/output/department_stats.json', 'w') as f:
    json.dump(results, f, indent=2)

# Write results as CSV
with open('/tmp/project/output/department_stats.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['department', 'employee_count', 'average_salary', 'total_salary'])
    writer.writeheader()
    writer.writerows(results)

print("Processing complete!")
print(f"Generated {len(results)} department statistics")

# Print summary
for result in results:
    print(f"{result['department']}: {result['employee_count']} employees, avg salary ${result['average_salary']}")
PY`);

console.log('Execution Output:', result.stdout);

// Read and display results
const jsonResults = await sandbox.filesystem.readFile('/tmp/project/output/department_stats.json');
const csvResults = await sandbox.filesystem.readFile('/tmp/project/output/department_stats.csv');

console.log('JSON Results:', jsonResults);
console.log('CSV Results:', csvResults);

// List all generated files
const outputFiles = await sandbox.filesystem.readdir('/tmp/project/output');
console.log('Generated files:');
outputFiles.forEach(file => {
  console.log(`  ${file.name} (${file.size} bytes)`);
});

await sandbox.destroy();

软件包安装和使用

import { vercel } from '@computesdk/vercel';

const compute = vercel({});
const sandbox = await compute.instances.create();

// Install lodash
const installResult = await sandbox.runCommand('npm install lodash');
console.log('Install result:', installResult.stdout);

// Use lodash in code
const result = await sandbox.runCommand(`node - <<'JS'
const _ = require('lodash');

const data = [
  { name: 'Alice', age: 25, city: 'New York' },
  { name: 'Bob', age: 30, city: 'San Francisco' },
  { name: 'Charlie', age: 35, city: 'Chicago' }
];

// Group by city
const grouped = _.groupBy(data, 'city');
console.log('Grouped by city:', JSON.stringify(grouped, null, 2));

// Calculate average age
const avgAge = _.meanBy(data, 'age');
console.log('Average age:', avgAge);

// Find oldest person
const oldest = _.maxBy(data, 'age');
console.log('Oldest person:', oldest.name);
JS`);

console.log(result.stdout);
await sandbox.destroy();

最佳做法

  1. 认证: 尽可能使用 OIDC 符号方法进行更简单的设置
  2. 资源管理: 完成后摧毁沙盒(反正它们是电流)
  3. 处理错误: 使用试捕取区块进行稳健的错误处理
  4. 超时: 为长期任务设定适当的超时(最多45分钟)
  5. 文件组织: 使用文件系统 API 来组织工程文件
  6. 软件包安装: 视需要在运行时安装软件包

限制

  • 长相沙盒: 每个沙盒都是单用而无法重新连接
  • 无沙盒列表: Vercel 不支持列出所有沙盒
  • 没有交互式终端: 不支持终端操作
  • 内存限制: 受Vercel沙盒内存限制( 2048 MB per vCPU)
  • 执行时间: 执行时间最长为45分钟
  • 网络访问: 有限的出网访问

支助

许可证

麻省理工学院

版本与发布记录

@computesdk/vercel 共发布 102 个版本,首次发布于 2025/07/12;过去 12 个月发布了 87 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.7.54latest2026/11/064 天前
1.7.532026/11/046 天前
1.7.522026/10/2812 天前
1.7.512026/10/2317 天前
1.7.502026/10/2318 天前
1.7.492026/10/2218 天前

关于 @computesdk/vercel 的常见问题

@computesdk/vercel 是什么?

ComputeSDK的Vercel Sandbox提供商 - Vercel边缘网络上的Python和Node.js的无服务器代码执行

如何安装 @computesdk/vercel?

在项目目录运行 npm install @computesdk/vercel,或使用 pnpm add / yarn add / bun add。

@computesdk/vercel 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@computesdk/vercel 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@computesdk/vercel 可以商用吗?

@computesdk/vercel 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@computesdk/vercel 的下载量有多少?

根据 npm 官方下载统计,@computesdk/vercel 在 2026/10/11 – 2026/11/09 这 30 天内被下载 12,580 次,日均约 419 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@computesdk/vercel 还在维护吗?

最新版本 1.7.54 发布于 2026/11/06(4 天前);至今共发布 102 个版本,其中过去 12 个月发布了 87 个;首次发布于 2025/07/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。