在编程时,开发人员会遇到需要重复使用代码的问题,导致重复性编程,这可能会浪费时间并降低生产力。这就产生了对称为 "代码片段 "的可重复使用的源代码的需求。这些代码片断可以防止在编程过程中出现重复的代码,可以保存起来供将来使用,并且可以共享。
在本教程中,我们将使用Next.js网络开发框架建立一个网站,帮助用户保存每天的代码片段,并由Fauna数据库来处理代码片段的存储、操作和显示。通过研究这个有趣的项目,我们还将学习如何用Next.js和FaunaDB创建一个基本的CRUD应用,该应用也可用于构建其他类似项目。
这个项目的工作版本可以在GitHub上找到。要跟着学习,你需要在你的机器上安装Node,以及一个FaunaDB账户和一个Google账户(用于认证)。
安装依赖项
在本节中,我们将看看如何使用npx create-next-app 命令来安装Next.js。这将初始化Next CLI并构建一个新的Next.js应用程序。
我们还将通过命令行安装我们将在后端使用的依赖项--FaunaDB和SWR。SWR(statewhile-revalidate)是Next.js用于获取数据的钩子。我们将在本教程的后面深入讨论这个问题。
Next.js的安装
要安装Next.js,请在CLI中输入以下命令。
npx create-next-app snippetapp
上述命令创建了一个名为snippetapp 的项目目录,其中有Next.js的启动模板,它包含了用Next编码所需的文件。当Next安装完成后,换到新创建的目录中。
cd snippetapp
FaunaDB和SWR的安装
为了安装Fauna,我们将在CLI中使用以下命令。
npm install --save faunadb
然后来安装SWR。
npm install swr@0.3.8
这样,我们就安装好了所有用于构建我们应用程序的依赖项,现在可以继续在Fauna上设置我们的数据库了。
FaunaDB的设置
FaunaDB是一个无服务器、实时的数据库。它将传统的数据库转变为一个灵活的数据API,仍然保留了数据库的功能和性能,同时提供对应用程序数据的安全和可扩展的访问。
在这里,我们将创建一个用户账户,并设置数据库以存储我们将在片段应用中使用的数据。
创建用户账户
要创建一个用户账户,请浏览Fauna注册页面并创建一个账户。

创建用户账户后,您将被重定向到仪表板。

创建片段数据库和集合
在这里,我们将创建一个带有管理我们应用程序的代码片段所需集合的数据库。点击CREATE DATABASE。我们将创建一个名为snippets 的数据库。

在打开的新页面上,点击新建集合,创建一个名为codesnippet 的集合。

创建完集合后,我们会得到一个页面,在这里我们可以创建一个文档。

在这里,你将点击NEW DOCUMENT。一个JSON文档将会打开,你可以在这里输入细节,如下图。

{
name: "Prompt User",
description: "prompts the user",
language: "javascript",
code: "prompt('would you like to continue')"
}
在这里,我们定义一个带有属性的片段。name,description,language 和code 。点击SAVE来保存新的集合。我们已经成功地将一个片段添加到我们的数据库中。现在我们可以继续获取我们的访问凭证,以便在我们的应用程序中使用。
创建密匙
在仪表板上,点击安全。这将打开一个新页面来创建我们的安全密钥。

在这里,我们将把角色设置为 "服务器",而不是 "管理员",你可以给密钥一个名字。点击 "SAVE"按钮来生成你的密钥。
创建一个.env 文件
我们现在将在我们项目的目录中创建一个.env 文件。这个文件将存储我们生成的密匙。在.env 文件中,我们有这个。
FAUNA_SECRET = paste your key here
创建一个代码片段页面
在本节中,我们将为代码片段建立显示和上传页面,并为其添加功能。
在你的代码编辑器中打开项目目录,并导航到你的页面文件夹中的index.js 文件。在这里,我们将清除代码并开始构建我们的应用程序。
import Head from "next/head"
import Image from "next/image"
import styles from "../styles/Home.module.css"
export default function Home() {
return (
<div className={styles.container}>
<Head>
<title>View Snippet</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1 className={styles.title}>Re-usuable Code Snippets</h1>
<p className={styles.info}>Add your code snippets here...</p>
<button>Create new snippet</button>
</main>
</div>
)
}
创建我们的组件
现在我们将创建一个组件文件,用来渲染我们的片段。在你的工作目录中创建一个名为component 的文件夹,并在其中创建一个名为Snippets.js 的文件,其代码如下。
import React from "react"
import styles from "../styles/Home.module.css"
function Snippets() {
return (
<div className={styles.cont}>
<p className={styles.lang}>language</p>
<h3 className={styles.name}>name of snippet</h3>
<p className={styles.descp}>description of snippet</p>
{/* Code will be displayed here*/}
<div className={styles.links}>
<a>Edit</a>
<a>Delete</a>
</div>
</div>
)
}
export default Snippets
将我们的组件导入到应用程序中
我们现在将在我们的index.js 中为这个文件添加导入。
import Snippets from "../components/Snippets"
并在我们的应用程序中使用它。
<button>Create new snippet</button>
<Snippets/>
设计我们的应用程序
现在我们可以为我们的页面设计样式。导航到styles 文件夹中的Home.module.css 文件,用以下内容替换其中的样式。
.container{
display: flex;
height: 100%;
min-height: 100vh;
background: rgb(48, 48, 255);
flex-direction: column;
align-items: center;
color: #fff;
font-family: Montserrat;
}
.cont{
color: #333;
margin-top: 5px;
background: rgb(214, 214, 214);
border-radius: 15px;
padding: 10px 15px;
}
.main button{
width: fit-content;
flex-grow: unset;
display: inline-block;
padding: 5px 10px;
outline: none;
border: none;
border-radius: 5%;
font-weight: bold;
color: rgb(48, 48, 255);
}
.main button:hover{
cursor: pointer;
}
.links{
margin-top: 10px;
}
.links a{
margin-left: 5px;
}
.links a:hover{
cursor: pointer;
}
查看我们的应用程序
在这一点上,你应该能够用npm run dev 启动开发服务器,访问http://localhost:3000,并看到我们应用程序的骨架。
设置片段显示区
接下来,我们将为片段代码创建显示区。在组件文件夹中创建一个名为Code.js 的新文件,并将其导入Snippets.js 。
import React from 'react'
import styles from '../styles/Home.module.css'
import Code from "./Code";
function Snippets() {
return (
<div className={styles.cont}>
<p className={styles.lang}>language</p>
<h3 className={styles.name}>name of snippet</h3>
<p className={styles.descp}>description of snippet</p>
{/* Code will be displayed here*/}
<Code />
<div className={styles.links}>
<a>Edit</a>
<a>Delete</a>
</div>
</div>
)
}
export default Snippets
对于代码的语法高亮,我们将使用两个包,即react-syntax-highlighter和react-copy-to-clipboard。我们可以通过CLI下载。
npm install react-syntax-highlighter react-copy-to-clipboard --save
然后在Code.js 。
import React from "react"
import { PrismLight as SyntaxHighlighter } from "react-syntax-highlighter"
import {atomDark} from "react-syntax-highlighter/dist/cjs/styles/prism"
import { CopyToClipboard } from "react-copy-to-clipboard"
import styles from "../styles/Home.module.css"
function Code() {
const codeString = "npm install import react from 'react'"
const [show, setshow] = React.useState(false)
return (
<div>
<button onClick={() => setshow(!show)}>Show Code</button>
{show ? (
<div>
<CopyToClipboard text={codeString}>
<button className={styles.btn}>Copy</button>
</CopyToClipboard>
<SyntaxHighlighter language="javascript" style={atomDark}>
{codeString}
</SyntaxHighlighter>
</div>
) : null}
</div>
)
}
export default Code
这里,我们创建了一个组件来显示带有语法高亮的代码。我们还添加了复制和切换显示的功能。现在在styles 文件中。
.btn{
left: 80%;
position: relative;
}
测试代码区块
要查看这一变化,你可以在命令行中运行npm run dev ,并在浏览器中查看。我们有字符串 "npm install import react from 'react' ",并以语法高亮显示为代码块。还有一个按钮可以隐藏和显示代码片段,还有一个按钮允许我们从代码块中复制代码。
FaunaDB初始化
在这一部分,我们将从FaunaDB数据库中获取数据到我们的应用程序。在你的项目目录下创建一个名为Fauna.js 的文件。
const faunadb = require("faunadb")
const faunaClient = new faunadb.Client({
secret: process.env.FAUNA_SECRET
})
const q = faunadb.query
const getResponse = async () => {
const { data } = await faunaClient.query(
q.Map(
q.Paginate(q.Documents(q.Collection("codesnippet"))),
q.Lambda("doc", q.Get(q.Var("doc")))
)
)
const snippets = data.map((snippet) => {
snippet.id = snippet.ref.id
delete snippet.ref
return snippet
})
return snippets
}
module.exports = {
getResponse,
}
在这里,我们已经用我们的秘钥初始化了FaunaDB。我们还设置了一个async 请求来查询我们的集合并返回数据。我们将返回的数据存储在一个名为snippets 的变量中,并删除了ref,以便更好地组织数据。创建、更新和删除片段的其他功能将在本教程的后面添加。
注意,如果你在控制台中得到一个未经授权的错误,你可能需要指定目标端点的域名。默认是db.fauna.com ,但自从引入区域组后,有三个云域可用。为你的数据库的区域组使用正确的域名。
- 经典(美国和欧盟)。
db.fauna.com - 美国(US)。
db.us.fauna.com - 欧洲(EU)。
db.eu.fauna.com
示例代码。
const faunaClient = new faunadb.Client({
secret: process.env.FAUNA_SECRET,
domain: "db.eu.fauna.com"
})
处理我们的API请求
我们还将创建一个文件来处理我们的数据库的API请求。在api 文件夹中的pages ,创建一个名为snippets.js 的文件,代码如下。
import { getResponse } from "../../Fauna.js"
export default async function handler(req, res) {
console.log(req)
if (req.method !== "GET") {
return res.status(405)
}
try {
const snippets = await getResponse()
return res.status(200).json(snippets)
} catch (err) {
console.log(err)
res.status(500).json({ msg: "Something went wrong." })
}
}
上面,我们简单地设置了一个函数来处理来自我们数据库的请求。这些片段会以Json 的形式返回,如果有错误发生,会记录下来。在Next.js中,存储在api 文件夹中的任何文件都被视为API端点,而不是一个页面,并在服务器端呈现。