文章目录
- 前言
- 一、环境配置
- 1. 安装Deno
- 2. 安装idea插件
- 二、Hello World
- 1.创建项目
- 2.项目结构
- 3. 创建一个路由
- 4. 创建一个动态路由
- 5. 自定义handlers
- 1. 自定义响应头
- 2. 随即生成uuid
- 6. 表单提交
- 7. 部署到生产环境
- 1. 将代码上传到github
- 2. 在Deno控制面板创建一个项目
- 总结
前言
对新技术永远有一种探索欲。上次听说Fresh的时候还不是很完善,但是自称下一代Web全栈开发框架。
Fresh是一个面向JavaScript和TypeScript开发人员的全栈现代Web框架,旨在创建高质量、高性能和个性化的Web应用程序变得轻而易举。以下是关于Fresh的一些特点:
- 基于Deno运行时:Fresh由Deno原班人马开发,享有Deno一系列工具链和生态的优势,比如内置的测试工具、支持http
import等等。 - Islands SSR架构:Fresh整体采用Islands SSR架构,实现了客户端按需Hydration,有一定的渲染性能优势。
- Bundle-less构建:Fresh的构建层做到了Bundle-less,即应用代码不需要打包即可直接部署上线。
- 前端渲染层由Preact完成:包括Islands架构的实现也是基于Preact,且不支持其它前端框架。
可以说,Fresh中凝结这Deno对ES语系开发的理解,是他们技术的结晶。
时至今日,Fresh看起来已经发展的很不错了,本文将从我快速体验Fresh来带大家体验一下它。
一、环境配置
我当前所使用环境为
系统 | Pop! OS |
---|---|
Rust | 1.70 |
1. 安装Deno
使用Cargo来安装Deno
cargo install deno --locked
验证是否安装成功
deno --version
2. 安装idea插件
对于idea来说,安装还是相当容易的,直接一键安装
二、Hello World
1.创建项目
再终端直接运行
# 创建项目
deno run -A -r https://fresh.deno.dev
# 进入目录
cd fresh-project
# 运行项目
deno task start
图片中大致意思是
- 项目名(fresh-project)
- 是否支持tailwindcss(y)
- 是否使用vscode(Y)
运行后这个样子就启动成功辣。浏览器实际运行结果如下图
2.项目结构
在运行项目以后,目录结构如下
首先,前面俩.idea
、.vscode
是两软件的工程设置配置文件,这部分不必关心。
然后是4个及其重要的文件,没有他们fresh是启动不了的。
dev.ts
开发环境入口点,启动项目用的,名字可以改变,但是一般都是这个名字。main.ts
生产环境入口点,启动项目用的,名字可以改变,但是一般都是这个名字。fresh.gen.ts
清单文件,包括routes
和islands
,是自动生成
的。deno.json
是deno的配置文件,和package.json
类似,用来管理依赖以及deno cli命令的.
从这里开始,代码编辑器改用Vscode,因为对idea来说支持的还是不太好。
接下来是四个非常重要的文件夹
routes
存放你项目中的路由。islands
这个也不是很清楚怎么翻译好一点,但是他的作用就相当于页面之于组件,但中的来说是组件的封装。components
存放组件相关代码。static
存放静态文件,js、css等文件都放在这里。
islands
和components
是不一样的,后者更像是Web Component,而前者更像我们常规开发中的Component。
3. 创建一个路由
Fresh使用的是文件系统路由,对于经常使用电脑的人来说,这个概念会比较容易理解,如果你使用的是Linux的画就会更加容易理解,如果你使用的是Windows,同样也很容易就能理解。
文件系统路由是操作系统中的一个重要概念,它用于管理和组织计算机中的文件和文件夹。文件系统路由可以帮助我们在计算机上查找、访问和操作存储在不同位置的文件。
在Linux操作系统中,文件系统路由是通过Linux文件系统层次结构来实现的。在Linux中,根目录以斜杠(/)表示,所有其他文件和文件夹都是在根目录下的子目录。例如,如果我们要访问根目录下的名为“home”的文件夹,就可以使用路径“/home”。同样,如果要访问“home”文件夹下的“user1”的文件夹,可以使用路径“/home/user1”。
在Windows操作系统中,文件系统路由是通过驱动器和文件路径来实现的。Windows操作系统使用字母来表示驱动器。例如,C:\是计算机上的一个驱动器,它通常用于存储操作系统和应用程序。在Windows中,我们可以使用驱动器和文件夹路径来访问文件。例如,如果要访问C:\下的“Users”文件夹,可以使用路径“C:\Users”。同样,如果要访问“Users”文件夹下的“user1”的文件夹,可以使用路径“C:\Users\user1”。
在这两个操作系统中,文件系统路由允许我们在计算机上轻松浏览和访问文件和文件夹。通过使用正确的路径,我们可以快速找到所需的文件,进行复制、粘贴、移动或删除等操作。
假设我们有一个文件路由系统,用于管理和导航文件夹和文件。该系统可以通过一系列文件夹和子文件夹来组织文件。
例如,我们有一个名为“根文件夹”的文件夹,其中包含以下几个子文件夹:文件夹A、文件夹B和文件夹C。在文件夹A中,我们有一个名为“文件1”的文件和一个名为“文件2”的文件。在文件夹B中,我们有一个名为“文件3”的文件。
根文件夹
- 文件夹A
- 文件1
- 文件2
- 文件夹B
- 文件3
- 文件夹C
这是一个简单的示例,展示了文件路由系统中文件夹和文件的层次结构。
而在Fresh项目中,你可以将routes
文件夹作为根目录,下面的文件用来路由。此时如果添加一个/about
的页面,只需要创建个about.jsx
文件即可
Fresh使用了jsx,因此只需要返回你的html内容就可以了,和react是一样的,但是fresh没有用react,而是用的preact,这两者再用法上几乎没区别。
保存后可以直接在浏览器打开(热启动)
4. 创建一个动态路由
动态路由即需要传递参数,根据输入的参数来动态的生成页面的路由。
在Fresh中,默认提供了匹配路径参数的动态路由greet
其中name
为需要传递的参数,其文件内容为
import { PageProps } from "$fresh/server.ts";
export default function GreetPage(props: PageProps) {
const { name } = props.params;
return (
<main>
<p>Greetings to you, {name}!</p>
</main>
);
}
可以看出路径参数是通过props对象的params来获取的。
比如要给name传aaron,则访问
http://localhost:8000/greet/aaron
就会得到以下结果
5. 自定义handlers
hanldler是一个路由的处理程序,可以有一个hanldler覆盖所有HTTP方法,也可以每个方法有一个hanldler。hanldler的作用是Request => Response
hanldler必须返回一个Response对象。Response对象可以手动创建(例如API路由的JSON响应),也可以通过呈现页面组件来创建。默认情况下,所有未定义自定义处理程序的路由都使用仅呈现页面组件的默认处理程序。
创建handler只需要定义一个handler对象并导出就可以了,handler可以是纯函数,也可以是纯对象。
以下是官方给出的两个例子
1. 自定义响应头
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
async GET(_req, ctx) {
const resp = await ctx.render();
resp.headers.set("X-Custom-Header", "Hello");
return resp;
},
};
export default function AboutPage() {
return (
<main>
<h1>About</h1>
<p>This is the about page.</p>
</main>
);
}
2. 随即生成uuid
routes/api/random-uuid.ts
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
GET(_req) {
const uuid = crypto.randomUUID();
return new Response(JSON.stringify(uuid), {
headers: { "Content-Type": "application/json" },
});
},
};
此时访问该页面http://localhost:8000/api/random-uuid
6. 表单提交
在以上内容理解的基础上,就可以实现表单提交了,官方给出的例子
import { Handlers, PageProps } from "$fresh/server.ts";
const NAMES = ["Alice", "Bob", "Charlie", "Dave", "Eve", "Frank"];
interface Data {
results: string[];
query: string;
}
export const handler: Handlers<Data> = {
GET(req, ctx) {
const url = new URL(req.url);
const query = url.searchParams.get("q") || "";
const results = NAMES.filter((name) => name.includes(query));
return ctx.render({ results, query });
},
};
export default function Page({ data }: PageProps<Data>) {
const { results, query } = data;
return (
<div>
<form>
<input type="text" name="q" value={query} />
<button type="submit">Search</button>
</form>
<ul>
{results.map((name) => <li key={name}>{name}</li>)}
</ul>
</div>
);
}
可以看出,其实就是获取请求参数以后,使用render来渲染页面。
7. 部署到生产环境
部署fresh项目要经过两个步骤:
1. 将代码上传到github
在github新建一个项目,然后吧你的代码上传即可。
然后在你的目录运行
git init
git add .
git commit -m "first commit"
git branch -M main
git remote add origin 你的仓库地址
git push -u origin main
2. 在Deno控制面板创建一个项目
首先打开官网你的控制面板https://dash.deno.com/projects
,用你的github登陆即可,然后创建项目
选择你的账户
选择账户需要授权一下,允许即可
目前只需要这样就可以,然后点击部署,等待部署完成
完成后首页会出现你的域名
打开任意一个,比如我的dirty-pig-75.deno.dev
,打开就会出现部署的结果了
总结
现在的Fresh开发起来还是比较丝滑的,但是有一些问题也是真的。
比如在部署的时候可能会出莫名其妙的错误,导致样式直接没有了;
比如idea插件检测不到deno环境,那就只能换vscode了;
比如第一次运行项目可能有依赖加载不上。。。
一堆堆都是坑,然后莫名其妙就好了。
除此以外,这东西只能在Fresh的面板上部署吗?
在我目前看来,这玩意儿做个个人网站估计差不多了,免费版每个月限制1,000,000 个请求,100G流量,而且还只能部署在官方网站,但是专业版一个月20刀,友友们自己判断吧。
我认为如果能自己部署的话,还有必要再看看。