@d8d-webcontainer/api
v1.0.13
Published
Client API for D8D WebContainer
Downloads
27
Readme
@d8d-webcontainer/api
WebContainer API 客户端库,提供容器操作和文件系统功能。
安装
npm install @d8d-webcontainer/api
基本用法
import { WebContainer } from "@d8d-webcontainer/api";
async function main() {
// 初始化 WebContainer
const container = await WebContainer.getInstance({
serverUrl: "http://localhost:3000",
});
// 挂载文件
await container.mount({
"package.json": {
file: {
contents: JSON.stringify({
name: "my-project",
dependencies: {},
}),
},
},
});
// 监听文件变化
const watcher = await container.fs.watch('src/**/*.ts', {
onChange: (event) => {
console.log('文件变化:', {
type: event.type, // 'create' | 'update' | 'delete'
path: event.path
});
}
});
// 执行命令
await container.spawn("npm", ["install"], {
onOutput: (data) => console.log(data),
});
}
API 参考
WebContainer
静态方法
WebContainer.getInstance(config: WebContainerConfig)
创建或获取 WebContainer 实例。
参数:
config.serverUrl
: WebContainer 服务器地址
返回值: Promise<WebContainer>
WebContainer.hasInstance()
检查是否已存在 WebContainer 实例。
返回值: boolean
WebContainer.destroyInstance()
销毁当前的 WebContainer 实例。
实例方法
mount(files: FileSystemTree)
挂载文件系统。
参数:
files
: 文件系统树结构对象
spawn(command: string, args?: string[], options?: SpawnOptions)
执行命令。
参数:
command
: 要执行的命令args
: 命令参数数组options.onOutput
: 输出回调函数
on<K extends keyof WebContainerEvents>(event: K, handler: WebContainerEvents[K])
添加事件监听器。
参数:
event
: 事件名称handler
: 事件处理函数
off<K extends keyof WebContainerEvents>(event: K, handler: WebContainerEvents[K])
移除事件监听器。
参数:
event
: 事件名称handler
: 要移除的事件处理函数
文件系统 API
通过 container.fs
访问文件系统 API。
list(path?: string)
列出目录内容。
参数:
path
: 目录路径,默认为 '.'
返回值: Promise<{ name: string; type: 'file' | 'directory' }[]>
readFile(path: string)
读取文件内容。
参数:
path
: 文件路径
返回值: Promise<string>
writeFile(path: string, content: string)
写入文件内容。
参数:
path
: 文件路径content
: 文件内容
remove(path: string)
删除文件或目录。
参数:
path
: 文件或目录路径
mkdir(path: string)
创建目录。
参数:
path
: 目录路径
watch(glob: string, options: WatchOptions)
监听文件变化。
参数:
glob
: 要监听的文件 glob 模式options.onChange
: 文件变化回调函数
返回值: Promise<{ close: () => void }>
文件监听
fs.watch(glob: string, options: WatchOptions)
监听文件变化。
参数:
glob
: 要监听的文件 glob 模式'.'
- 监听当前目录及其所有子内容'src'
- 监听特定目录及其所有子内容'src/**/*.ts'
- 监听特定目录下的特定文件类型
options.onChange
: 文件变化回调函数
返回值: Promise<{ close: () => void }>
FileChangeEvent
interface FileChangeEvent {
type: 'create' | 'update' | 'delete'; // 变化类型
path: string; // 文件路径
kind: 'file' | 'directory'; // 实体类型
}
WatchOptions
interface WatchOptions {
onChange: (event: FileChangeEvent) => void; // 文件变化回调函数
ignore?: string[]; // 要忽略的文件模式
ignoreInitial?: boolean; // 是否忽略初始文件扫描事件
}
文件监听示例
// 监听当前目录,忽略初始扫描事件
const watcher = await container.fs.watch('.', {
onChange: (event) => {
if (event.type === 'create') {
console.log(`新${event.kind}创建:`, event.path);
} else if (event.type === 'update') {
console.log(`${event.kind}已修改:`, event.path);
} else if (event.type === 'delete') {
console.log(`${event.kind}已删除:`, event.path);
}
},
ignore: [
'**/node_modules/**', // 忽略 node_modules 目录
'**/.git/**', // 忽略 .git 目录
'**/dist/**', // 忽略构建输出目录
'**/.DS_Store', // 忽略 macOS 系统文件
'**/thumbs.db', // 忽略 Windows 系统文件
'**/.idea/**', // 忽略 IDE 配置目录
'**/.vscode/**' // 忽略 VSCode 配置目录
],
ignoreInitial: true // 忽略初始文件扫描事件
});
// 监听特定目录,包含初始扫描事件
const srcWatcher = await container.fs.watch('src', {
onChange: (event) => {
console.log(`src目录变化:`, event);
},
ignore: [
'**/*.test.ts', // 忽略测试文件
'**/*.spec.ts', // 忽略规格文件
'**/coverage/**' // 忽略测试覆盖率目录
],
ignoreInitial: false // 包含初始文件扫描事件
});
// 监听特定文件类型,忽略临时文件
const tsWatcher = await container.fs.watch('src/**/*.ts', {
onChange: (event) => {
console.log(`TypeScript文件变化:`, event);
},
ignore: [
'**/*.tmp.ts', // 忽略临时文件
'**/*.bak.ts' // 忽略备份文件
]
});
// 停止监听
await watcher.close();
await srcWatcher.close();
await tsWatcher.close();
事件
server-ready
当开发服务器就绪时触发。
事件参数:
interface ServerReadyEvent {
port: number;
url: string;
localUrl?: string;
}
类型定义
WebContainerConfig
interface WebContainerConfig {
serverUrl: string;
}
SpawnOptions
interface SpawnOptions {
onOutput?: (data: string) => void;
}
FileSystemTree
interface FileSystemTree {
[path: string]:
| {
file: {
contents: string;
};
}
| {
directory: {
contents: FileSystemTree;
};
};
}
SpawnOptions
interface SpawnOptions {
onOutput?: (data: string) => void;
}
FileChangeEvent
interface FileChangeEvent {
type: 'create' | 'update' | 'delete'; // 变化类型
path: string; // 文件路径
kind: 'file' | 'directory'; // 实体类型
}
WatchOptions
interface WatchOptions {
onChange: (event: FileChangeEvent) => void;
ignore?: string[]; // 要忽略的文件模式
}
示例
创建并运行 Node.js 项目
import { WebContainer } from "@d8d-webcontainer/api";
async function createNodeProject() {
const container = await WebContainer.getInstance({
serverUrl: "http://localhost:3000",
});
// 创建项目文件
await container.mount({
"package.json": {
file: {
contents: JSON.stringify({
name: "node-demo",
type: "module",
dependencies: {
express: "^4.18.2",
},
}),
},
},
"index.js": {
file: {
contents: `import express from 'express'; const app = express(); app.get('/', (req, res) => { res.send('Hello from WebContainer!'); }); app.listen(3000);`,
},
},
});
// 安装依赖
await container.spawn("npm", ["install"], {
onOutput: console.log,
});
// 运行服务器
await container.spawn("node", ["index.js"], {
onOutput: console.log,
});
}
文件操作示例
async function fileOperations(container: WebContainer) {
// 创建目录
await container.fs.mkdir("src");
// 写入文件
await container.fs.writeFile("src/hello.js", 'console.log("Hello");');
// 列出文件
const files = await container.fs.list("src");
console.log("Files:", files);
// 读取文件
const content = await container.fs.readFile("src/hello.js");
console.log("Content:", content);
// 删除文件
await container.fs.remove("src/hello.js");
}
文件监听示例
async function watchFiles(container: WebContainer) {
// 设置文件监听
const watcher = await container.fs.watch('src/**/*', {
onChange: (event) => {
if (event.type === 'create') {
console.log(`新${event.kind}创建:`, event.path);
} else if (event.type === 'update') {
console.log(`${event.kind}已修改:`, event.path);
} else if (event.type === 'delete') {
console.log(`${event.kind}已删除:`, event.path);
}
}
});
// 执行一些文件操作
await container.fs.writeFile('src/test.ts', 'console.log("Hello");');
await container.fs.writeFile('src/test.ts', 'console.log("Updated");');
await container.fs.remove('src/test.ts');
// 停止监听
await watcher.close();
}
注意事项
WebContainer 实例是单例的,同一时间只能存在一个实例。
在组件卸载时应该调用
WebContainer.destroyInstance()
清理资源。文件路径使用正斜杠
/
作为分隔符。spawn 命令的输出会通过 onOutput 回调返回,包括 stdout 和 stderr。
错误输出会以红色显示,退出信息会以黄色显示。
文件监听会自动处理文件和目录的创建、修改和删除事件
每个变化事件都会包含实体类型(file/directory)信息
可以使用 '.' 监听当前目录下的所有变化
默认会忽略 node_modules 和 .git 目录
可以通过 ignore 选项自定义要忽略的文件模式
ignore 模式支持 glob 语法,如
**/node_modules/**
ignoreInitial 参数控制是否触发已存在文件的初始事件
建议在组件卸载时调用
watcher.close()
清理监听器
License
MIT