1.0.3 • Published 8 months ago

d8d-webcontainer-api v1.0.3

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

@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: {},
        }),
      },
    },
  });
  // 执行命令
  await container.spawn("npm", ["install"], {
    onOutput: (data) => console.log(data),
  });
}

API 参考

WebContainer

静态方法

WebContainer.getInstance(config: WebContainerConfig)

创建或获取 WebContainer 实例。

参数:

  • config.serverUrl: WebContainer 服务器地址

返回值: Promise<WebContainer>

const container = await WebContainer.getInstance({
  serverUrl: "http://localhost:3000",
});
WebContainer.hasInstance()

检查是否已存在 WebContainer 实例。

返回值: boolean

WebContainer.destroyInstance()

销毁当前的 WebContainer 实例。

实例方法

mount(files: FileSystemTree)

挂载文件系统。

参数:

  • files: 文件系统树结构对象
await container.mount({
  src: {
    directory: {
      contents: {
        "index.js": {
          file: {
            contents: 'console.log("Hello");',
          },
        },
      },
    },
  },
});
spawn(command: string, args?: string[], options?: SpawnOptions)

执行命令。

参数:

  • command: 要执行的命令
  • args: 命令参数数组
  • options.onOutput: 输出回调函数
await container.spawn("npm", ["install"], {
  onOutput: (data) => console.log(data),
});

文件系统 API

通过 container.fs 访问文件系统 API。

list(path?: string)

列出目录内容。

参数:

  • path: 目录路径,默认为 '.'

返回值: Promise<{ name: string; type: 'file' | 'directory' }[]>

const files = await container.fs.list("./src");

writeFile(path: string, content: string)

写入文件内容。

参数:

  • path: 文件路径
  • content: 文件内容
await container.fs.writeFile("config.json", '{"port": 3000}');

remove(path: string)

删除文件或目录。

参数:

  • path: 文件或目录路径
await container.fs.remove("temp");

mkdir(path: string)

创建目录。

参数:

  • path: 目录路径
await container.fs.mkdir("src/components");

类型定义

FileSystemTree

interface FileSystemTree {
  [path: string]:
    | {
        file: {
          contents: string;
        };
      }
    | {
        directory: {
          contents: FileSystemTree;
        };
      };
}

SpawnOptions

interface SpawnOptions {
  onOutput?: (data: string) => void;
}

示例

创建并运行 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");
}

注意事项

  1. WebContainer 实例是单例的,同一时间只能存在一个实例。

  2. 在组件卸载时应该调用 WebContainer.destroyInstance() 清理资源。

  3. 文件路径使用正斜杠 / 作为分隔符。

  4. spawn 命令的输出会通过 onOutput 回调返回,包括 stdout 和 stderr。

  5. 错误输出会以红色显示,退出信息会以黄色显示。

License

MIT

1.0.2

8 months ago

1.0.3

8 months ago

1.0.1

9 months ago