deno使用rust_使用graphql和deno构建ssr react应用程序

2023-10-14 13:59

本文主要是介绍deno使用rust_使用graphql和deno构建ssr react应用程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

deno使用rust

介绍(Introduction)

Unless you have been living under a rock, I am sure you have been hearing all the hype on Deno and/or GraphQL in the past few years. If you are intrigued by these technologies and enjoy learning new technologies by building with them, then you're in the right place!

除非您一直生活在一块石头下,否则我相信您会在过去几年中听到有关Deno和/或GraphQL的所有炒作。 如果您对这些技术感兴趣,并且喜欢通过与它们一起构建来学习新技术,那么您来对地方了!

迪诺背景 (Background on Deno)

On May 13, 2018, Ryan Dahl, the creator of Node.js announced Deno, a new secure runtime for JavaScript and Typescript, during his “10 Things I Regret About Node.js” talk. In this talk, he mentioned some of the improvements that Deno aims to implement, such as abstracting the need for dependency solutions like NPM modules and package.json, supporting TypeScript out of the box by implementing a snapshotted TypeScript compiler, and breaking the sandboxed environment of the V8 engine.

2018年5月13日,Node.js的创建者Ryan Dahl在“我对Node.js的十件事感到遗憾”演讲中宣布了Deno,这是一个用于JavaScript和Typescript的新安全运行时。 在本次演讲中,他提到了Deno旨在实现的一些改进,例如抽象出对依赖解决方案(如NPM模块和package.json)的需求,通过实现快照TypeScript编译器开箱即用地支持TypeScript,以及打破沙盒环境。 V8引擎。

After two years, on May 13, 2020, it was announced that Deno was ready for production, and has been backed my major cloud providers such as AWS Lambda, Azure Functions, and Google Cloud Run.

两年后,即2020年5月13日,宣布Deno可以投入生产,并得到了我的主要云提供商的支持,例如AWS Lambda,Azure Functions和Google Cloud Run。

总览 (Overview)

Throughout this article, we will be building a simple application to show Rick and Morty character information utilizing React, GraphQL, and Deno. During the process, we will be implementing server-side rendering with Deno’s Oak framework, as well as executing and caching GraphQL queries with Deno’s Obsidian library.

在整个本文中,我们将构建一个简单的应用程序,以利用React,GraphQL和Deno显示Rick和Morty的角色信息。 在此过程中,我们将使用Deno的Oak框架实现服务器端渲染,并使用Deno的Obsidian库执行和缓存GraphQL查询。

让我们开始吧! (Let's get right into it!)

First things first, we need to set up our file structure.

首先,我们需要设置文件结构。

my-app
├── client
│ ├── Components
| ├── static
│ ├── app.tsx
│ └── client.tsx
├── server.tsx
├── deps.ts
├── serverDeps.tsx
├── staticFileMiddleware.ts
├── tsconfig.json
└── README.md
  • client is where we will store all our React components, static files, and theapp.tsx andclient.tsx files.

    client是我们存储所有React组件,静态文件以及app.tsxclient.tsx文件的地方。

  • deps.ts and serverDeps.ts serve to import all of the Deno modules used throughout the application in one place.

    deps.tsserverDeps.ts用于将整个应用程序中使用的所有serverDeps.ts模块集中到一个位置。

  • staticFileMiddleware.ts will contain the logic to handle requests for static files.

    staticFileMiddleware.ts将包含处理静态文件请求的逻辑。

  • tsconfig.json specifies the root files and the compiler options required to compile the TypeScript project.

    tsconfig.json指定根文件和编译TypeScript项目所需的编译器选项。

导入Deno模块 (Importing Deno Modules)

Since we have determined all of the libraries that we will be importing on our client-side and server-side, we will begin by creating deps.ts files to import them into our application.

由于我们已经确定了要在客户端和服务器端导入的所有库,因此我们将首先创建deps.ts文件以将其导入到我们的应用程序中。

import React from 'https://dev.jspm.io/react@16.13.1';
import ReactDom from 'https://dev.jspm.io/react-dom@16.13.1';
import {ObsidianWrapper,useObsidian,
} from 'https://deno.land/x/obsidian@v0.1.6/ObsidianWrapper/ObsidianWrapper.jsx';export { React, ReactDom, ObsidianWrapper, useObsidian };
  • deps.ts is where we will be importing all the Deno modules that will be utilized in the client-side of the application.

    deps.ts是我们将导入将在应用程序客户端使用的所有Deno模块的地方。

import {Application,Router,Context,send,
} from 'https://deno.land/x/oak@v6.0.1/mod.ts';
import ReactDomServer from 'https://dev.jspm.io/react-dom@16.13.1/server';export { Application, Router, ReactDomServer, Context, send };
  • serverDeps.ts is where we will be importing all the Deno modules that will be utilized in the server-side of the application.

    serverDeps.ts中,我们将导入将在应用程序服务器端使用的所有Deno模块。

服务器端渲染 (Server-side Rendering)

Now that we have imported all our modules in one central location, we can begin setting up our server. We will be utilizing Deno’s Oak middleware framework, and ReactDOMServer to render components to static markup.

现在,我们已将所有模块导入一个中央位置,我们可以开始设置服务器了。 我们将利用Deno的Oak中间件框架和ReactDOMServer将组件呈现为静态标记。

import { Application, Router, ReactDomServer } from './serverDeps.ts';
import { React } from './deps.ts';
import App from './client/app.tsx';
import { staticFileMiddleware } from './staticFileMiddleware.ts';const PORT = 3000;// Create a new server
const app = new Application();// Router for base path
const router = new Router();router.get('/', handlePage);// Bundle the client-side code
const [_, clientJS] = await Deno.bundle('./client/client.tsx');// Router for bundle
const serverrouter = new Router();
serverrouter.get('/static/client.js', (context) => {context.response.headers.set('Content-Type', 'text/html');context.response.body = clientJS;
});// Implement the routes on the server
app.use(staticFileMiddleware);
app.use(router.routes());
app.use(serverrouter.routes());
app.use(router.allowedMethods());app.addEventListener('listen', () => {console.log(`Listening at http://localhost:${PORT}`);
});
await app.listen({ port: PORT });// Function to render entire application as a string
function handlePage(ctx: any) {try {const body = (ReactDomServer as any).renderToString(<App />);ctx.response.body = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><link rel="stylesheet" href="/static/style.css"><meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Rick and Morty</title></head><body ><div id="root">${body}</div><script  src="/static/client.js" defer></script></body></html>`;} catch (error) {console.error(error);}
}

If you are familiar with Express.js and/or Koa.js the structure for creating routers and endpoints with the Oak framework above should be very familiar. If you skim through the code there are two main things that differ from what you may be used to: the Deno.bundle function on line 17 and the HTML file at the bottom of the code block.

如果您熟悉Express.js和/或Koa.js,那么使用上述Oak框架创建路由器和端点的结构应该非常熟悉。 如果您浏览了代码,则有两个主要的方面与您可能习惯的有所不同:第17行的Deno.bundle函数和代码块底部HTML文件。

The Deno.bundle function is one of the great features that Deno provides. Similar to how you would use a bundler like Webpack to transpile and compile your application in Node.js, Deno has that functionality out of the box. The Deno.bundle function takes an entry point of the client-side code as an argument and transpiles and bundles the client-side file structure into a single javascript file to be sent to the client.

Deno.bundle函数是Deno.bundle提供的重要功能之一。 与您使用像Webpack这样的打包器在Node.js中转译和编译应用程序的方式类似,Deno可以立即使用该功能。 Deno.bundle函数将客户端代码的入口点作为参数,并进行编译并将客户端文件结构捆绑到单个javascript文件中,以发送给客户端。

The second nuance above is the handlePage function, starting on line 38. When this function is invoked, it begins by utilizing the rendertoString function that is provided by the ReactDOMServer package. The React application is passed into this function and converts the entire application into an HTML string. So when a “GET” request for the root endpoint is received by the server, the entire React application is sent to the client as a string.

上面的第二个细微差别是handlePage函数,从第38行开始。调用此函数时,它首先利用ReactDOMServer包提供的rendertoString函数。 React应用程序传递到此函数中,并将整个应用程序转换为HTML字符串。 因此,当服务器收到对根端点的“ GET”请求时,整个React应用程序将作为字符串发送到客户端。

While the page does load faster, it is a marked down version of the page, meaning that it does not have any of the React functionality — this is why a request is made for the bundled javascript file on line 52. With server-side rendering, the React application never uses the render method and instead uses a hydrate method. Since the webpage is already rendered, the browser receives the bundled javascript file and parses through the rendered application, seamlessly reinjecting the React functionality into the application.

尽管该页面确实加载得更快,但这是该页面的标记版本,这意味着它不具有任何React功能-这就是为什么在第52行上请求捆绑的javascript文件的原因。服务器端渲染,React应用程序从不使用render方法,而是使用hydrate方法。 由于已经渲染了网页,因此浏览器会接收捆绑的javascript文件并通过渲染的应用程序进行解析,从而将React功能无缝地重新注入到应用程序中。

客户端代码和GraphQL (Client-side code and GraphQL)

Now that we have covered server-side rendering from the server-side, let's take a look at how we are able to achieve this functionality on the client-side.

现在我们已经从服务器端介绍了服务器端渲染,下面让我们看一下如何在客户端上实现此功能。

import { React, ReactDom } from '../deps.ts';
import App from './app.tsx';// Hydrate the app and reconnect React functionality
(ReactDom as any).hydrate(<App />, document.getElementById('root'));

The code snippet above demonstrates the entry point into the client-side code. Notice how the hydrate method is used instead of render.

上面的代码段演示了客户端代码的入口点。 注意如何使用hydrate方法而不是render

Pretty simple, right? Well, let’s look into how we can incorporate GraphQL fetching and caching functionality into our application.

很简单,对吧? 好吧,让我们研究如何将GraphQL提取和缓存功能整合到我们的应用程序中。

import { React, ObsidianWrapper } from '../deps.ts';import MainComponent from './DemoComponents/MainComponent.tsx';declare global {namespace JSX {interface IntrinsicElements {div: any;}}
}const App = () => {return (<ObsidianWrapper><MainComponent /></ObsidianWrapper>);
};export default App;

In order to cache our GraphQL requests, we will be using the ObsidianWrapper . Similar to how you would wrap your application in a provider when using a React state management library, utilizing this wrapper supplies caching capabilities to our GraphQL requests. This improves the performance of the app, providing consistent data throughout the application and reducing the load on the backend.

为了缓存GraphQL请求,我们将使用ObsidianWrapper 。 与使用React状态管理库时将应用程序包装在提供程序中的方式类似,利用此包装器可以为我们的GraphQL请求提供缓存功能。 这可以提高应用程序的性能,在整个应用程序中提供一致的数据,并减少后端的负载。

提取和缓存GraphQL请求 (Fetching and caching GraphQL requests)

Finally, we will be taking a look at how we will be fetching and caching our GraphQL requests in the following code block.

最后,我们将研究如何在以下代码块中获取和缓存GraphQL请求。

import { React, useObsidian } from '../../deps.ts';
import Sidebar from './Sidebar.tsx';
import Carousel from './Carousel.tsx';declare global {namespace JSX {interface IntrinsicElements {h1: any;div: any;}}
}const GET_CHARACTERS = `query{characters(page:1){results{idnameimage}}}
`;const MainPage = () => {const [info, setInfo] = (React as any).useState({});const [characters, setCharacters] = (React as any).useState([]);const { gather } = useObsidian();(React as any).useEffect(() => {gather(GET_CHARACTERS, {endpoint: 'https://rickandmortyapi.com/graphql',destructure: false,}).then((resp: any) => setCharacters([...resp.data.characters.results]));}, []);return (<div id='main-container'><h1>Rick and Morty Character Guide</h1><div id='app-container'><Sidebar info={info} /><Carousel characters={characters} setInfo={setInfo} /></div></div>);
};export default MainPage;

We will first begin by importing the useObsidian hook which allows us to access the functionality provided by the wrapper. On line 31 we invoke the hook which gives us access to a few different methods. Here we are using the gather method which gives us the ability to fetch and cache GraphQL requests. The first parameter of this method is the GraphQL query and the second is an “options” parameter. For the sake of simplicity, we are using an external API and specifying to not destructure the query and response since this requires us to provide the application with the GraphQL schema. If you are curious about Obsidian’s normalization and destructuring capabilities, check out the article below.

首先,我们将导入useObsidian挂钩,该挂钩允许我们访问包装器提供的功能。 在第31行,我们调用该钩子,该钩子使我们可以访问一些不同的方法。 这里我们使用的gather方法,它为我们提供了获取和缓存GraphQL请求的能力。 此方法的第一个参数是GraphQL查询,第二个参数是“选项”参数。 为简单起见,我们使用外部API并指定不破坏查询和响应,因为这要求我们为应用程序提供GraphQL模式。 如果您对黑曜石的标准化和解构功能感到好奇,请查看下面的文章。

结语 (Wrapping up)

Now that we have built our core structure, we can add some additional functionality to query for more specific query information about each individual character. Finally, we add some minor styling to wrap it all up!

现在我们已经建立了核心结构,我们可以添加一些附加功能来查询有关每个字符的更具体的查询信息。 最后,我们添加一些较小的样式以将其全部包装!

Image for post

If you would like to have a look at the source code you can find the repository at https://github.com/Alonsog66/GraphQL-Deno-Medium-Demo.

如果您想看一下源代码,可以在https://github.com/Alonsog66/GraphQL-Deno-Medium-Demo中找到存储库。

结论 (Conclusion)

And there you have it! As you can see there are some major changes when working with Deno as opposed to Node.js — we do not store external modules locally, TypeScript can be compiled out of the box, and we did not need to configure a webpack.config.js file to specify the compiling as Deno can natively perform all of the transpiling and bundling. If you have any questions about any of this material covered feel free to post a comment below or reach out via LinkedIn.

在那里,您拥有了! 如您所见,与Deno相比,与Node.js相比,使用Deno时有一些重大更改-我们不在本地存储外部模块,TypeScript可以直接编译,并且我们不需要配置webpack.config.js文件指定编译,因为Deno可以本地执行所有转码和捆绑。 如果您对本文涵盖的任何内容有任何疑问,请随时在下面发表评论或通过LinkedIn进行联系。

Cheers!

干杯!

翻译自: https://medium.com/@alonsogarza6/building-an-ssr-react-application-with-graphql-and-deno-832c391bf8f2

deno使用rust


http://www.taodudu.cc/news/show-7958345.html

相关文章:

  • 带你五步学会Vue SSR
  • NGW,前端新技术赛场:Serverless SSR 技术内幕
  • 云原生时代的搜索服务算力管理
  • 阿里巴巴 Noslate 正式开源 - 面向云原生的 JavaScript 容器方案
  • 任正非一语成真,中国的鸡正回中国下蛋!一场巨变即将到来
  • 互联网大厂程序员,挣到1900万是财务自由的标准线?
  • cpython包_cpython 教程
  • Web开发团队常备工具
  • 将一组数据放入一个新数组中
  • 大华 摄像头 rtmp 拉流
  • 内网穿透代理服务器nps使用初探(三)微信小程序内网穿透
  • 微信小程序安装后打开一直提示:当前代理不是安全代理
  • 解决PC小程序抓包问题
  • 微信小程序请求数据出现跨域问题
  • 微信小程序https和wss,nginx代理,
  • burp抓不到微信小程序数据包的问题
  • 小程序如何访问本地后端服务
  • 【转】提升Exadata 计算节点本地IO性能
  • Repair the Wall
  • Exadata X3-2 存储服务器BBU 更换
  • opencv处理图片
  • Unity中全屏播放视频
  • STM32 CortexM4 主控板触摸屏保姆级别总结
  • html单标记语言有哪些,HTML(Hypertext Markup Language,超文本标记语言)是构成Web页面的主要工具,是用来表示网上信息的符号标记语言 。( )...
  • socket [WinError 10048]错误分析及解决方案
  • 虚幻引擎宣布和Quixel的合作了,作为开发者怎么获取Megascans库资源
  • 【Unreal】Unreal引擎学习-笔记二
  • [WinError 10061] 由于目标计算机积极拒绝,无法连接:requests.exceptions.ConnectionError: HTTPConnectionPool...
  • Error invoking remote method ‘fetch-data‘: FetchError: request to https://desktop.docker.com/tips.js
  • ue4屏幕空间反射关不掉问题
  • 这篇关于deno使用rust_使用graphql和deno构建ssr react应用程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/210980

    相关文章

    gitlab安装及邮箱配置和常用使用方式

    《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

    SpringBoot3应用中集成和使用Spring Retry的实践记录

    《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

    nginx启动命令和默认配置文件的使用

    《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

    在Windows上使用qemu安装ubuntu24.04服务器的详细指南

    《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

    使用Python和OpenCV库实现实时颜色识别系统

    《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

    Windows下C++使用SQLitede的操作过程

    《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

    Python常用命令提示符使用方法详解

    《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

    Python并行处理实战之如何使用ProcessPoolExecutor加速计算

    《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

    Python中help()和dir()函数的使用

    《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

    Linux脚本(shell)的使用方式

    《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删