WebContainers初体验-在浏览器端运行node.js

在最近学习wasm的过程中,就一直有一个想法,是不是可以开发一个wasm应用让node代码能够在浏览器端运行,虽然这个想法感觉有点扯,但是今天我发现真的有产品实现了这个功能,它就是WebContainers。

一、什么是WebContainers

提到WebContainers,就不得不提到StackBlitz,它是一个用于JavaScript生态的即时全栈web IDE,由WebContainers提供支持,WebContainers是第一个基于WebAssembly的操作系统,可以在几毫秒内安全地在浏览器中启动Node.js环境。

主要特性:

①、便捷:能够在浏览器中运行 node.js 及其工具链,比如npmwebpack等等

②、灵活:在 WebContainers 支持下,我们不需要费劲去安装node搭建开发环境,一切都在浏览器端发生,而且我们可以通过开发者工具无缝调试前后端应用。

③、安全:所有的内容均运行在浏览器页面中,非常的安全

④、快速:可以毫秒级启动整个开发环境

二、快速体验

我们可以在stackblitz官网(https://stackblitz.com/)在线体验webContainers技术,目前官网已经初始提供了不少开发环境,比如:

我们只需要简单点击我们需要的项目类型,即可快速在浏览器端启动对应的环境(首次需要稍微等待一会儿,需要下载代码和新安装依赖)。

三、启动流程

①、启动webContainer

import { WebContainer } from '@webcontainer/api';
webcontainerInstance = await WebContainer.boot();

有点像电脑开机,我们需要等到启动完成才能使用webcontainerInstance

②、挂载文件

const files = {
  'index.js': {
    file: {
      contents: `
import express from 'express';
const app = express();
const port = 3111;
  
app.get('/', (req, res) => {
    res.send('Welcome to a WebContainers app! 🥳');
});
  
app.listen(port, () => {
    console.log(\`App is live at http://localhost:\${port}\`);
});`,
    },
  },
  'package.json': {
    file: {
      contents: `
          {
            "name": "example-app",
            "type": "module",
            "dependencies": {
              "express": "latest",
              "nodemon": "latest"
            },
            "scripts": {
              "start": "nodemon index.js"
            }
          }`,
    },
  },
};

await webcontainerInstance.mount(files);

③、安装依赖

const exitCode = await installDependencies();
if (exitCode !== 0) {
  throw new Error('Installation failed');
};

async function installDependencies() {
  // Install dependencies
  const installProcess = await webcontainerInstance.spawn('npm', ['install']);
  installProcess.output.pipeTo(new WritableStream({
    write(data) {
      console.log(data);
    }
  }))
  // Wait for install command to exit
  return installProcess.exit;
}

这里使用到了spawn方法,该方法接受3个参数:

1、参数1:字符串类型,接收命令名称,例如 npm

2、参数2:数组类型,命令的选项,比如 ["install"] / ["run", "start"]

3、参数3: spawn的参数(例如指定环境变量,禁止输出等),非必须④、运行dev server

startDevServer();

async function startDevServer() {
  // Run `npm run start` to start the Express app
  await webcontainerInstance.spawn('npm', ['run', 'start']);

  // Wait for `server-ready` event
  webcontainerInstance.on('server-ready', (port, url) => {
    window.open(url);
  });
}

一般我们会通过类似http://localhost:3111的方式来访问我们的应用,但现在我们的服务运行在浏览器上,由于安全限制没有权限绑定端口,因此当server-ready后,会在回调参数中返回一个url用于访问引用,类似:https://stackblitzwebcontainerapistart-e5id--5173.local-credentialless.webcontainer.io,访问url并抓包我们会发现这个请求并没有实际请求外部资源,而是在Service Worker中直接做了响应:

四、结语

虽然目前WebContainers支持的功能看起来还十分有限,但这的确是一个非常有意义的尝试,为开发人员带来了一种全新的工作模式,也能大大提升开发人员的工作效率,比如环境搭建、编码体验,代码调试等各方面。相信在不久的将来,WebContainers会支持更多的特性。

  • 支付宝二维码 支付宝
  • 微信二维码 微信

本文地址: /webcontainers.html

版权声明: 本文为原创文章,版权归 逐梦个人博客 所有,欢迎分享本文,转载请保留出处!

相关文章