Stackblitz WebContainers。在浏览器中运行Next.js

1,320 阅读7分钟

Stackblitz是一个流行的在线IDE,用于创建和分享项目,被谷歌和GitHub等公司使用。Stackblitz由VS Code提供支持,它为用户提供了旋转和分享使用React、Vue和Angular等框架和库的全堆栈应用程序的能力。由于Stackblitz项目可以立即上线,你只需点击一下就可以分享你的项目

上周,Stackblitz推出了WebContainers,它允许用户在浏览器内运行整个Node.js进程,为安全性、速度和性能提供了好处。
因此,用户也可以在浏览器中运行Next.js项目了

在这篇文章中,我们将深入探讨这一功能。让我们开始吧!

Node.js原语

在了解Stackblitz如何工作之前,我们必须先了解Node.js背后的功能。Node.js是一个JavaScript运行时,建立在ChromeV8引擎之上,它将开发者编写的JavaScript代码转换为计算机可以理解的东西。

Node.js使开发者有可能在操作系统等本地环境中运行他们的JavaScript代码,而不需要浏览器。作为标准库的一部分,I/O原语允许Node.js执行访问数据库、进行网络请求和从文件系统读取等操作。

Node.js提供了I/O基元的阻塞和非阻塞的实现。然而,我们更喜欢非阻塞式基元,它在一个单线程上执行。Node.js依赖于它自己独特的基于事件的系统,该系统可以防止并行运行操作时由于多线程而产生的并发问题。

Nodejs Primitives Operating System Diagram

浏览器中的Node.js

你可以在macOS、Windows和Linux机器上安装Node.js。虽然目前仍处于测试阶段,但由于WASM能力API的存在,也可以在浏览器中运行Node.js了

在Stackblitz WebContainers中,WASM层成功地将操作系统层抽象出来,使得在浏览器标签中运行的Node.js进程实际上就像在一个成熟的操作系统中运行一样。

Nodejs Primitives Webassembly Diagram

设置一个Node.js WebContainer

现在,让我们来试试吧!让我们到Stackblitz去尝试运行一些我们自己的代码。要启动一个新项目,请访问主页并点击Node.js。几秒钟之内,一个新的项目就会为我们创建,其中包括左边的项目文件系统,中间的代码编辑器用于进行修改,底部是一个终端。

为了添加我们的代码,在终端中运行下面的代码片段。

node index.js

我们目前使用的Node.js的版本将通过代码打印到控制台。

让我们写一些与我们的文件系统一起工作的代码。在同一个项目中创建一个名为tmp.txt 的文件,并添加以下文字。

Hello World

接下来,我们将添加下面的代码片段,它读取该文件并将其截断为只有五个字符。

const { open } = require('fs/promises');
async function readAndTruncate() {
  let filehandle = null;
  try {
    filehandle = await open('tmp.txt', 'r+');
    await filehandle.truncate(5);
  } finally {
    await filehandle?.close();
  }
}
readAndTruncate();

在运行这段代码并检查tmp.txt ,我们看到我们的初始输入已被修改为读取Hello ,这意味着我们的Node.js读写文件的原始方法已经成功了

浏览器中的Next.js

现在我们已经成功运行了Node.js WebContainer,让我们建立一个Next.js项目。首先,让我们了解Next.js和Stackblitz背后的功能。请记住,Next.js是一个基于React的框架,开箱即提供静态渲染、服务器端渲染和图像优化。

让我们简单地考虑一下访问React应用程序和访问Next.js应用程序之间的区别。

访问一个React应用程序

要访问一个React应用程序,我们在浏览器中输入应用程序的URL。浏览器将获取HTML、CSS和JavaScript包。然后JavaScript在浏览器上被编译,同时React代码被转换为相应的HTML和CSS,生成页面。然后,该页面被插入到获取的HTML内部的div ,拉出用户界面。

访问Next.js应用程序

要访问一个Next.js应用程序,我们在浏览器中输入URL。在构建时,有几个页面被标记为静态。如果请求的页面是静态的,它就会按原样提供。如果页面不是静态的,浏览器会检查它是否是一个服务器端渲染的页面。如果是,就会进行必要的API调用,最后生成的HTML和CSS被发送到浏览器上直接显示。

如果该页面既不是静态的,也不是服务器端渲染的,你可以用一种与React应用程序非常相似的方式来访问它。然而,最终的HTML和CSS将直接交付给浏览器,而不是在你解压JavaScript捆绑包时创建。

在浏览器中直接渲染你的页面,可以改善整个页面的加载时间,并增加与SEO爬虫的兼容性,造成整体性能的提升有了Stackblitz网络容器,你不必离开浏览器就可以获得这些好处。

在Stackblitz中创建我们的Next.js项目

Nextjs Stackblitz Browser Cycle

你可能已经注意到,在Next.js应用程序的生命周期中,服务器比普通React应用程序的生命周期发挥了更大的作用。

Next.js服务器是基于Node.js的,所以,从历史上看,Next.js服务器可以运行在任何可以支持运行Node.js的系统上。现在,Node.js可以通过WebContainers完全在浏览器中运行,这意味着我们也可以在浏览器中运行Next.js应用

要启动一个新的Next.js项目,请进入Stackblitz主屏幕并点击Next.js。或者,你可以打开任何浏览器,在地址栏中输入Next.new ,然后按回车键。一个新的Next.js项目就会为我们设置好了!

我们也可以根据Next.js GitHub中的例子创建一个新项目!我们只需要在Next.new 前面加上项目名称。例如,如果我想用blog-starter的例子来启动一个新项目,我可以在浏览器中运行以下代码。

next.new/blog-starter

集成一个API

按照上述步骤生成的项目有两个文件:index.jsabout.js 。这些文件迎合了Next.js启动器模板为你提供的两条路线,//about 。让我们把一个API集成到我们的项目中,并修改在/ 路由上呈现的用户界面。

在这个演示中,我们将使用NASA的事件API,它可以返回目前地球上发生的所有气候事件的摘要。我们将使用React Bootstrap库中的组件来设计我们的用户界面。通过在终端运行以下命令来安装该库。

npm install --save react-bootstrap@next bootstrap

我们要在浏览器内创建的Node.js环境中安装这些依赖项。接下来,让我们在index.js file 里面导入Bootstrap CSS。

import 'bootstrap/dist/css/bootstrap.css';

服务器端渲染

为了检索我们项目的数据,我们将使用Next.js中的getServerSideProps 函数。我们将在服务器端进行调用,然后在我们的React组件IndexPage 内使用结果。这样做指示Next.js在浏览器对这个特定组件发出任何请求时,都在服务器端进行调用。

export async function getServerSideProps(context) {
  const res = await fetch('https://eonet.sci.gsfc.nasa.gov/api/v2.1/events');
  const events = await res.json();
  return {
    props: { nasaEvents: events } // will be passed to the page component as props
  };
}

UI渲染

接下来,我们将返回在props key中获取的事件,Next.js将把这些事件作为props传递给React组件。然后,我们将使用Bootstrap组件以列表的形式显示这些事件。

export default function IndexPage({ nasaEvents }) {
  return (
    <div style={{ padding: 10 }}>
      <h2>Nasa Events</h2>
      <div>
        {nasaEvents.events.map(event => (
          <Item event={event} />
        ))}
      </div>
    </div>
  );
}

接下来,我们将把需要为每个事件渲染的用户界面抽象成另一个用户界面组件,我们命名为Item

Helper component
function Item({ event }) {
  return (
    <Card style={{ width: '90%', marginBottom: 10 }}>
      <Card.Body>
        <Card.Title>{event?.categories[0]?.title}</Card.Title>
        <Card.Text>{event.title}</Card.Text>
        <a href={event?.sources[0]?.url}>
          <Button>visit</Button>
        </a>
      </Card.Body>
    </Card>
  );
}

现在,我们的代码已经完成了!刷新后,我们将看到我们能够得到一个全球各地发生的气候事件的列表。

Final Next Stackblitz Project

结论

在本教程中,我们学习了如何使用Stackblitz WebContainers在浏览器中完全运行一个Next.js项目。我们设置了一个Node.js容器,然后通过它访问一个Next.js项目,将API与服务器端和UI渲染整合在一起。

我们的项目包括一个项目URL和一个部署URL,前者有助于协作开发,后者可以让用户预览最终结果。要分享这个项目,我可以简单地分享项目的URL。我希望你喜欢这个教程!

The postStackblitz WebContainers:浏览器中运行Next.js,首先出现在LogRocket博客上。