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

    相关文章

    java图像识别工具类(ImageRecognitionUtils)使用实例详解

    《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

    python管理工具之conda安装部署及使用详解

    《python管理工具之conda安装部署及使用详解》这篇文章详细介绍了如何安装和使用conda来管理Python环境,它涵盖了从安装部署、镜像源配置到具体的conda使用方法,包括创建、激活、安装包... 目录pytpshheraerUhon管理工具:conda部署+使用一、安装部署1、 下载2、 安装3

    Mysql虚拟列的使用场景

    《Mysql虚拟列的使用场景》MySQL虚拟列是一种在查询时动态生成的特殊列,它不占用存储空间,可以提高查询效率和数据处理便利性,本文给大家介绍Mysql虚拟列的相关知识,感兴趣的朋友一起看看吧... 目录1. 介绍mysql虚拟列1.1 定义和作用1.2 虚拟列与普通列的区别2. MySQL虚拟列的类型2

    使用MongoDB进行数据存储的操作流程

    《使用MongoDB进行数据存储的操作流程》在现代应用开发中,数据存储是一个至关重要的部分,随着数据量的增大和复杂性的增加,传统的关系型数据库有时难以应对高并发和大数据量的处理需求,MongoDB作为... 目录什么是MongoDB?MongoDB的优势使用MongoDB进行数据存储1. 安装MongoDB

    关于@MapperScan和@ComponentScan的使用问题

    《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

    mysql数据库分区的使用

    《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

    使用Python实现在Word中添加或删除超链接

    《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

    Linux使用fdisk进行磁盘的相关操作

    《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

    C#使用HttpClient进行Post请求出现超时问题的解决及优化

    《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

    SpringBoot使用Apache Tika检测敏感信息

    《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学