基于 Storyblok 和 Nuxt 构建静态网站全流程指南
1. 数据从 Storyblok 到浏览器组件的映射
当数据从 Storyblok 传来时,它带有组件类型的描述。使用 slug 页面,我们总能定位到一个 Storyblok 组件,该组件会尝试将类型与
./storyblok
文件夹中的相应 Vue 组件匹配。这个组件可能是嵌套类型,即它包含另一个 Storyblok 组件实例,以此类推。一旦掌握了这种思维模式,就会觉得相当简单。不过,Nuxt 和 Storyblok 模块的自动化和假设机制可能会让其原理变得有些难以理解。
2. 修改内容模型
目前,无头 CMS 能够为我们的项目展示基本布局和内容,但功能仍十分有限。下面来看看如何处理内容模型,使其支持新特性。
2.1 更新现有类型
假设我们的 Teaser 块是 Heading 块。建议尽量保持块的静态性,不过还是来看看更改名称需要做什么。操作步骤如下:
1. 导航到 CMS 中的块库,将鼠标悬停在 Teaser 块上,通过上下文菜单进入编辑模式。
2. 在“Config”选项卡中更新名称。
3. 将
./storyblok
文件夹中的
Teaser.vue
组件重命名为
Heading.vue
。
需要注意的是,随着应用程序的发展,引入需要重命名或删除现有组件的模型更新会越来越危险,这些被视为重大更改,可能导致应用程序(暂时)崩溃。Storyblok 会警告你,更改可能需要一些时间才能在整个内容中传播,这可能会影响或阻止应用程序生成所有页面,因此要谨慎对待此类警告或错误。相比之下,添加新功能要安全得多。
2.2 扩展块属性
添加功能的更改更容易实现,下面看看如何扩展 Feature 块:
1. 打开编辑视图。
2. 添加以下字段:
- 添加一个资产类型的图像字段,创建后将该字段配置为仅允许图像。
- 添加一个链接类型的链接字段。
3. 保存更改后,更新组件以在预览编辑器中体验更改。打开
./storyblok/Feature.vue
文件并替换其内容:
<script setup lang="ts">
defineProps({
blok: {
type: Object as () => { name: string, image: any, link: any },
},
});
</script>
<template>
<div v-editable="blok" v-if="blok" class="text-center">
<ULink :to="blok.link.cached_url">
<img
v-if="blok.image"
:src="blok.image.filename + '/m/200x0'"
:alt="blok.image.alt"
/>
</ULink>
<header class="text-xl">
{{ blok.name }}
</header>
</div>
</template>
可以更新网站主页上的默认功能块,例如链接到一些项目组合项。如果不想使用现有功能,也可以将其删除。更新组件后,Storyblok 会很好地展示结果。
由于目前页面还比较空,因为没有添加文本的方式。这次先创建组件,然后在 CMS 中实现它。在
./storyblok
文件夹中创建一个
RichText.vue
组件,内容如下:
<script setup lang="ts">
const props = defineProps({
blok: { type: Object as () => { body: any }, required: true },
});
const richTextBody = computed(() => renderRichText(props.blok.body));
</script>
<template>
<div v-editable="blok" class="prose">
<div v-html="richTextBody" />
</div>
</template>
<style scoped>
.prose {
line-height: 1.8em;
}
</style>
然后,在 Storyblok 中添加一个名为
rich-text
的新块作为可嵌套块,只添加一个名为
body
的富文本类型字段。现在就可以立即添加内容块并开始为网站添加额外内容了!
为了让页面视觉效果更好,对块进行一些重构。在
./storyblok
文件夹中创建一个名为
Article.vue
的 Vue 组件:
<script setup lang="ts">
defineProps({
blok: { type: Object as () => { title: string, content: any }, required: true },
});
</script>
<template>
<div v-editable="blok" class="article">
<h2 v-if="blok.title" class="text-2xl mb-4">{{ blok.title }}</h2>
<StoryblokComponent
v-for="blok in blok.content"
:key="blok._uid"
:blok="blok"
/>
</div>
</template>
<style scoped>
.article {
max-width: 720px;
margin: 2em auto;
}
</style>
接着,切换到 CMS 创建一个名为
article
的新块作为可嵌套块,添加以下字段:
1. 添加一个文本类型的标题字段。
2. 添加一个块类型的内容字段,该字段允许我们用许多不同的可用块来组合文章类型。
此外,还可以利用 Storyblok 在项目根目录创建一个“Me”故事页面,用于自我介绍和分享经历。
3. 映射元字段
之前在展示项目组合部分为“Portfolio All”和“Portfolio”块添加了描述字段,但还未进行映射。这些字段旨在为页面提供一些元数据,用于搜索引擎优化(SEO)。可以使用语义 HTML 标签为搜索引擎索引专门描述页面内容,Nuxt 为此提供了一个开箱即用的解决方案和一个组合式函数(https://nuxt.com/docs/getting-started/seo-meta#usehead)。
由于字段名称相同,在脚本标签中插入以下代码来添加元字段:
useHead({
meta: [
{ name: 'description', content: props.blok.description }
]
});
此时查看网站源代码,就能看到标签和内容已渲染。要记住,CMS 中的内容不仅可用于网站的可见部分,还能在应用程序中作为变量处理,比如提供切换开关或主题等,无需部署新代码就能更改网站,这正是无头 CMS 在开发应用程序时的强大之处。
4. 添加新功能
完成上述步骤后,可以尝试为项目添加更多功能,例如设计精美的联系表或易于管理的简历部分。凭借已构建的基础,应该能够自行实现。
5. 生成独立网站
现在我们有了一个功能齐全的项目组合网站,这类网站内容非常静态,不随访问者变化,代码也可能不会每天更新,因此可以优化要部署到公共环境的输出。
我们创建的项目组合网站非常适合静态网站生成。通常,Nuxt 会作为服务器上的活动进程运行,可直接响应请求并实时获取数据。但发布时不需要实时数据,因此可以利用 Nuxt 的另一个功能。生成静态网站时,Nuxt 最初作为应用程序运行,对所有内部链接进行索引,对于每个内部链接,它会从服务器获取一次数据,然后将输出写入静态文件集合。
操作步骤如下:
1. 虽然命令已包含在
package.json
脚本中,但需要稍作修改,以便传递访问数据所需的 API 密钥:
{
"scripts": {
"build": "nuxt build",
"dev": "NODE_TLS_REJECT_UNAUTHORIZED=0 nuxt dev --dotenv .env --https --ssl-cert localhost.pem --ssl-key localhost-key.pem",
"generate": "nuxt generate --dotenv .env",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
}
}
- 在终端运行以下命令:
npm run generate
此时会看到正在生成静态网站所需的文件。完成后,Nuxt 生成过程会返回一个命令,用于将网站作为静态网站进行测试:
npx serve .output/public
运行此命令将启动一个简单的 HTTP 网络服务器,此时没有 Nuxt 进程运行,只是浏览器在运行 HTML、CSS 和 JavaScript 文件。除了图像(由 Storyblok CDN 提供服务),CMS 中的所有内容现在都已打包到网站中。
下面是生成独立网站的流程图:
graph TD;
A[修改 package.json 脚本] --> B[运行 npm run generate];
B --> C[生成静态文件];
C --> D[获取测试命令];
D --> E[运行 npx serve .output/public];
6. 发布静态网站
任何网络主机都能够提供这些静态文件,这是静态生成网站的一大优势,在托管方面有很大的自由度。这里选择 Netlify(https://app.netlify.com/),注册后可免费使用其免费套餐。注册时选择最适合的类别并为团队命名。
在下一步,选择 Netlify Drop 方式进行部署:
1. 选择“Try Netlify Drop”,会重定向到一个拖放空间,将项目
./output/public
文件夹中的输出文件拖放到此空间,注意要拖放整个
public
文件夹,而不是单独的内容。
2. 完成上传后,首次进入仪表板,点击“Open production deploy”按钮,即可访问已发布的项目组合网站。Netlify 会生成一个包含随机字词的子域名,可通过“Domain management”部分进行更改。
Netlify 的免费套餐提供处理域名的功能,可将自己的域名指向该空间。不过,静态生成网站的缺点是部署的网站与内容和 Nuxt 服务器完全分离,这意味着如果更新内容或更改代码中的功能,需要重新生成网站并手动将输出上传到 Netlify,虽然可行但并不理想。幸运的是,通过一些额外的努力和配置,可以在内容或代码更改时自动进行部署。
6.1 代码更改时自动构建和部署
Netlify 环境不了解我们的应用程序,它是一个用于部署 Web 应用程序的工具,无法直接连接到本地开发环境,因此需要将源代码托管到线上。
GitHub(https://github.com/)与 Netlify 有很好的集成,非常适合托管和管理代码版本。GitHub 可以检测到代码库中的代码何时更新,并在发生更改时触发某些操作。
操作步骤如下:
1. 创建一个新的空代码库。
2. 使用终端将代码关联到代码库:
git init
git branch -m master main
git remote add origin https://github.com/{YOUR_USERNAME}/{REPOSITORY_NAME}.git
git add .
git commit -am "published source to git"
git push -u origin main
- 在 Netlify 仪表板中,导航到“Site Configuration | Build & Deploy”,点击“Link repository”按钮,然后在 GitHub 账户上授权 Netlify。选择刚刚创建的项目组合代码库继续。
-
更改以下三个设置:
-
将“Build command”更改为
npm run generate。 -
将“Publish directory”更改为
./output/public。 -
添加环境变量,将
.env文件中的内容添加进去,键为NUXT_STORYBLOK_ACCESS_TOKEN,值为对应的访问令牌,并确保保存。
-
将“Build command”更改为
完成这些更改后,Netlify 会在代码发生更改时自动从代码库读取并拉取最新版本,然后在虚拟环境中运行
npm run generate
脚本进行静态网站渲染,最后将输出文件夹的内容部署到网站域名。需要注意的是,由于应用程序没有运行测试,无法验证代码是否功能正常,因此最好确保代码的关键功能能够正常工作。
6.2 内容更改时自动构建
如果能在内容更改时实现类似代码更改时的自动化操作就好了,幸运的是,可以使用 Webhook 来触发操作。Storyblok 会跟踪内容何时准备好发布,并在 Netlify 平台上触发一个操作,就像代码更改时一样执行构建。不过,这次 Nuxt 会在生成过程中获取最新版本的内容。
设置步骤如下:
1. 在 Netlify 中创建一个 Webhook:
- 导航到“Site configuration”,找到“Build & Deploy”下的“Build hooks”部分。
- 点击“Add build hook”按钮,给它一个有意义的名称,如“Deploy on Content Change”,设置默认构建主分支。
- 保存后会收到一个唯一的 URL,格式类似于
https://api.netlify.com/build_hooks/UNIQUE_IDENTIFIER
。
2. 在 Storyblok 中配置调用此 Webhook:
- 导航到“Settings”和“Webhook”部分,管理 Webhook。
- 创建一个新的 Webhook,同样给它一个有意义的名称。
- 在“Endpoint URL”区域粘贴 Netlify 的端点。
3. 选择事件触发器来调用 Webhook,建议尽量选择较少的触发器,因为每次构建过程都需要时间,连续调用 Webhook 会使请求排队,导致更改显示的等待时间变长。
保存设置后,更改项目组合中的一些内容。如果没有运行 Nuxt 开发服务器,仍可以使用右侧面板编辑内容,甚至可以使用“Show form view”按钮将其扩展以填充整个屏幕,,只是没有实时预览,但访问内容并非必须运行开发服务器。保存更改后,在 Netlify 仪表板的“Deploys”部分可以看到已触发新的构建。
通过以上步骤,我们将不同的平台和系统连接起来,构建了一个能够渲染静态网站的应用程序。这种结合多种专业解决方案优势的方式可以构建出强大且可部署的产品。Storyblok 的实时预览功能和使用 Nuxt 作为框架的开发体验,使这类项目易于上手和构建。同时,要明白 Nuxt 不一定要始终作为服务器运行,它可以一次性从服务器生成数据并存储输出,这种方法比实时数据获取更具可持续性和性能优势。而且,我们设置的 Storyblok 和 Nuxt 的集成方式,让任何人都能轻松构建网站。随着块数量的增加,可创建的可能性会大幅增加,同时对于非技术用户来说也很容易理解。所有的配置都是为了尽可能轻松地管理网站,无论是代码部署的自动化还是内容更改时自动生成新版本,都有助于实现这一目标。最后,建议用自己引以为傲的项目或成就完善项目组合,在开发过程中要接受实用主义,因为实际代码往往注重实用性,可能并非完美优化,但能有效实现预期目标,随着对项目的深入理解,自然会确定哪些方面需要优化。
7. 总结与展望
7.1 项目成果总结
通过前面一系列的操作,我们成功地构建了一个功能丰富且易于管理的静态网站。从数据从 Storyblok 到浏览器组件的映射,到修改内容模型、添加新功能、生成独立网站以及实现自动化部署,每一个步骤都为网站的完善和优化做出了贡献。
|操作步骤|主要成果|
| ---- | ---- |
|数据映射|实现了 Storyblok 数据与 Vue 组件的匹配,支持嵌套组件结构|
|内容模型修改|更新现有类型、扩展块属性,丰富了网站的内容展示形式|
|映射元字段|为网站添加了用于 SEO 的元数据,提高了网站在搜索引擎中的可见性|
|添加新功能|可根据需求为网站添加如联系表、简历部分等新特性|
|生成独立网站|利用 Nuxt 的静态网站生成功能,优化了网站的部署输出|
|自动化部署|实现了代码更改和内容更改时的自动化构建和部署,提高了开发和更新效率|
7.2 技术优势分析
- 无头 CMS 的强大之处 :无头 CMS 使得我们可以将 CMS 中的内容灵活地应用于网站的各个部分,不仅用于可见部分,还能作为变量在应用程序中处理,无需部署新代码就能更改网站,大大提高了开发的灵活性和效率。
- Nuxt 的多功能性 :Nuxt 既可以作为服务器实时响应请求和获取数据,也可以用于静态网站生成,将数据一次性生成并存储输出,在不同场景下都能发挥出色的性能。
- 集成平台的协同效应 :Storyblok 的实时预览功能和 Nuxt 作为框架的开发体验相结合,使得项目易于上手和构建,同时 Netlify 的部署和域名管理功能为网站的发布和管理提供了便利。
7.3 未来发展方向
- 功能扩展 :可以继续为网站添加更多的功能模块,如博客系统、在线商城等,进一步丰富网站的内容和服务。
- 性能优化 :对网站的性能进行进一步优化,如压缩图片、优化代码等,提高网站的加载速度和响应性能。
- 安全加固 :加强网站的安全防护,如设置访问权限、防止 SQL 注入和 XSS 攻击等,保障网站的安全性和稳定性。
7.4 实用建议
- 提前规划内容模型 :在项目初期,尽量提前规划好内容模型,避免后期频繁进行重大的模型更新,以免影响网站的稳定性。
- 谨慎选择 Webhook 触发器 :在设置 Webhook 触发器时,要谨慎选择,避免过多的触发导致构建过程频繁进行,增加等待时间。
- 进行代码测试 :在进行代码更改和功能添加时,建议进行充分的测试,确保代码的功能正常,避免出现潜在的问题。
下面是整个项目流程的 mermaid 流程图:
graph LR
A[数据映射] --> B[内容模型修改]
B --> C[映射元字段]
C --> D[添加新功能]
D --> E[生成独立网站]
E --> F[自动化部署]
F --> G[总结与展望]
通过以上的步骤和操作,我们完成了一个完整的静态网站构建项目。在这个过程中,我们充分利用了各种技术和工具的优势,实现了网站的高效开发、部署和管理。希望这些经验和方法能够帮助你在后续的项目中取得更好的成果。同时,不断探索和尝试新的技术和功能,让你的网站始终保持竞争力和创新性。
超级会员免费看
1808

被折叠的 条评论
为什么被折叠?



