Project IDX 中的全栈开发

十一月 07, 2023
Prakhar Srivastav Software Engineer
Kaushik Sathupadi Software Engineer
Kristin Bi Software Engineer
Alex Geboff Technical Writer

我们推出了 Project IDX,这是我们实验性的基于浏览器的新开发体验,旨在降低构建全栈应用时会遇到的复杂性,并简化从(后)端到(前)端的开发过程。

在传统的软件开发中,大多数 Web 应用由至少两个不同的层次构建:前端(界面)层和后端层。当您考虑在一个基于浏览器的开发者工作区中构建应用时,人们可能不会立即想到那些拥有功能强大且齐全的后端的全栈应用。因为在基于网络的环境中开发后端层往往容易遭遇困难且成本高昂。例如,开发环境与生产环境之间的身份验证设置差异很大;难以确保后端与前端之间安全通信的实施;构建一个完全独立的(封闭)测试环境十分复杂,成本和不便之处也会随之增加。

我们知道许多开发者都期待亲自尝试 IDX,但在大家等待的同时,我们想分享这篇关于在 Project IDX 中进行全栈开发的帖子。我们会解决开发者在基于网络的工作环境中构建前后端层时可能会遇到的一些复杂情况,比如开发者身份验证、前端与后端之间的通信,以及封闭测试等。此外,我们还将介绍我们如何努力简化您的开发过程。同时,我们也非常希望听到你们的意见:我们还应该构建哪些功能以使全栈开发对您来说更加便捷!

简化的应用预览

首先,我们简化了应用前端与虚拟机的后端服务进行通信的过程,以便您可以轻松地在浏览器中预览您的全栈应用。

IDX 工作区建立在 Google Cloud Workstations 基础之上,并可通过服务帐号安全地访问连接的服务。每个工作区都有唯一的服务帐号,该帐号支持应用前端无缝且经过身份验证的预览环境。因此,在您使用 Project IDX 时,应用预览会直接构建到您的工作区中,您实际上无需设置不同的身份验证路径来预览界面。当前,IDX 仅支持预览 Web 应用,但很快 IDX 工作区将支持 Android 和 iOS 应用预览。

此外,如果您的开发环境要求您从浏览器预览之外的地方与 IDX 中正在开发的后端 API 进行通信,我们还建立了一些机制,以便开发者暂时获取对托管这些后端 API 的端口的访问权限。

简单的前端到后端通信

如果您使用的框架支持前后端层同时通过同一端口提供服务,那么您可以在工作区配置文件中传递 $PORT 标志,以使用自定义的 PORT 环境变量(该配置文件由 Nix 驱动并直接存储在您的工作区内)。这是 Project IDX 基本设置流程的一部分,因此除了在配置文件中设置变量之外,您无需执行任何特别的操作。以下是一个基于 Nix 的配置文件示例:

{ pkgs, ... }: {
 
# 注意:这是对完整的 Nix 配置示例的节选。
 
# 启用预览和自定义配置
idx.previews = {
  enable = true;
  previews = [
    {
      command = [
        "npm"
        "run"
        "start"
        "--"
        "--port"
        "$PORT"
        "--host"
        "0.0.0.0"
        "--disable-host-check"
      ];
      manager = "web";
      id = "web";
    }
  ];
};

然而,如果您的后端服务器运行在与界面浏览器不同的端口上,那么您需要采用不同的策略来实现通信。一种方法是让前端作为代理发送到后端,就像使用 Vite 的自定义服务器选项那样。

在端口之间建立通信的另一种方法是设置代码,使得在界面中运行的 JavaScript 能够通过 AJAX 请求与后端服务器进行通信。

让我们首先来看一个同时包含后端和前端的示例代码。以下是一个使用 Express.js 编写的后端服务器示例:

import express from "express";
import cors from "cors";
 
 
const app= express();
app.use(cors());
 
app.get("/", (req, res) => {
    res.send("Hello World");
});
 
app.listen(6000, () => {
    console.log("Server is running on port 6000");
})

示例代码中加粗的这一行“app.use(cors());”用于设置 CORS 标头。虽然根据您选择的语言和框架,具体的设置方式可能会有所不同,但无论在本地还是在 IDX 上开发,您的后端都需要返回这些标头。

在 IDX 终端中运行服务器时,后端端口将显示在 IDX 面板中。服务器运行的每个端口都会自动映射到您可以调用的网址中。

现在,让我们编写一些客户端代码来对此服务器进行 AJAX 调用。

// 此 URL 是从显示后端端口视图的侧面板复制的
const WORKSPACE_URL = "https://6000-monospace-ksat-web-prod-79679-1677177068249.cluster-lknrrkkitbcdsvoir6wqg4mwt6.cloudworkstations.dev/";
 
async function get(url) {
  const response = await fetch(url, {
    credentials: 'include',
  });
  console.log(response.text());
}
 
// 调用后端
get(WORKSPACE_URL);

此外,我们还确保了 fetch() 调用包含凭据。IDX 网址已经过身份验证,因此需要包含凭据。这样一来,AJAX 调用中就会包含用于向服务器进行身份验证的 Cookie。

如果您使用的是 XMLHttpRequest 而不是 fetch,则可以设置“withCredentials”属性,如下所示:

const xhr = new XMLHttpRequest();
xhr.open("GET", WORKSPACE_URL, true);
xhr.withCredentials = true;
xhr.send(null);

根据您用于进行 AJAX 调用的客户端库,您的代码可能与示例中的代码有所不同。如果确实存在差异,请查看您所使用的客户端库的文档,了解如何提出凭据请求。此操作的关键在于确保发起的是一个包含凭据的请求。

无需登录即可进行服务器端测试

在某些时候,您可能希望在未登录 Google 帐号的情况下访问 Project IDX 上的应用;或者从一个无法登录 Google 帐号的环境中访问。例如,如果您想使用 Postman 或 cURL 通过个人笔记本电脑命令行来访问 IDX 中正在开发的某个 API。您可以通过使用由 Project IDX 生成的临时访问令牌来实现这一目的。

在 Project IDX 中运行服务器后,您可以调出命令菜单以生成访问令牌。此访问令牌的有效期较短,可使您暂时访问自己的工作站。

请务必注意,此访问令牌提供了对您整个 IDX 工作区的访问权限,包括但不限于您正在预览的应用。因此,您不应将此访问令牌随意分享给任何他人。我们建议您仅在测试场景下使用此令牌。

access token command

从 IDX 运行此命令时,访问令牌将显示在对话框窗口中。复制访问令牌并使用它向工作站上运行的服务发起 cURL 请求,如下所示:

$ export ACCESS_TOKEN=myaccesstoken
$ curl -H "Authorization: Bearer $ACCESS_TOKEN" https://6000-monospace-ksat-web-prod-79679-1677177068249.cluster-lknrrkkitbcdsvoir6wqg4mwt6.cloudworkstations.dev/
Hello world

现在,您可以在经过身份验证的服务器环境中运行测试了!

基于网络的全封闭测试

正如我们强调的那样,您可以通过 IDX 在一个完全独立、经过身份验证且安全的环境中测试应用的前端和后端。此外,您可以在基于网络的开发环境中运行本地模拟器,以对应用的后端服务进行测试。

例如,您可以在 IDX 工作区中直接运行 Firebase Local Emulator Suite。如要安装这个模拟器套件,请在 IDX 的“终端”标签页中执行命令 firebase init emulators,然后按照提示步骤来配置您想要启用的模拟器及其对应端口。

firebase emulators

成功安装后,在 IDX 终端中,您便可以像在本地开发环境中那样配置和使用模拟器。

后续工作

如您所见,Project IDX 能够满足您在全栈开发过程中的许多需求,无论是前端和后端开发方面的需求,还是中间所需的模拟器。

如果您已经在使用 Project IDX,欢迎您在社交媒体上使用标签 #projectidx 来告诉我们 Project IDX 如何帮助您进行全栈开发。如果您尚未使用,请访问 idx.dev 加入等待名单。