前言
我们知道,官网通常是需要快速的首屏响应,也需要做seo优化,所以建议使用现代ssr框架来实现网站。诸如博客、官网之类的应用,都是以 内容发布 为主要功能的网站。往往需要一个后台系统,所以建议使用cms来作为内容管理系统。因此,在本项目选择了nextjs
来开发官网,选择strapi
来作为后台系统,nextjs
与 strapi
都以 js/ts 为开发语言,本项目适合前端程序员单独开发。(本项目的 官网部分 改造自峰华全栈工程师的从零制作响应式网站-html&css课程成品 )
Nextjs
nextjs
是一个开发者广泛使用 react
同构ssr框架。nextjs 进行 ssr 渲染,也能 进行 Static Site Generation(SSG)
优化,这使得Nextjs开发的应用具有极强首屏渲染能力。
Strapi
strapi
是一个基于koa的 headless(无头) cms。headless 意味它仅有后台系统,并暴露接口给前端使用。strapi
拥有极强的可定制性,和扩展性。本项目将深入strapi
开发,使用 redis
作为后端缓存使用,采用strapi社区开发的插件实现redis
与 strapi
连接,这极大提高了本项目的后端性能。
官网开发
响应式网站开发
这里采用tailwindCSS
,来方便的实现响应式网站开发。在tailwindCSS
只需要加上前缀,如xl-
lg-
等,即可实现css中媒体查询一样的效果。注意:tailwindCSS
有小屏优先原则,默认即为小屏样式。
举例:
html
<div className="grid w-4/5 xl:w-3/5 mx-auto mt-7 mb-[60px]">
</div>
Nextjs的SSG优化
在nextjs
中,当page文件中导出名为 getStaticProps
(静态站点生成)的函数,nextjs
将在构建时使用 getStaticProps
返回的props
预渲染此页面。
本项目用到SSG的部分代码:
tsx
export const getStaticProps = async () => {
const { data = {} } = await request.get("/api/articles/newest", {
params: {
count: 3,
},
});
return { props: { newestArticles: data }, revalidate: 60 // 过期时间60s };
};
export default function Home({ newestArticles }) {
return (
// ...someting
);
}
这里首页进行了SSG优化,同时因为首页内容是需要动态更新的,设置了60s的过期时间,每隔60s重新预渲染。
注意:nextjs
有两种模式 page Router
与 app Router
,这里使用的是page Router
模式,
后台开发
strapi后台支持中文
strapi
后台应用是支持中文的,需要修改src/admin/app.js
配置文件
js
const config = {
locales: ["zh-Hans"],
};
const bootstrap = (app) => {
console.log(app);
};
export default {
config,
bootstrap,
};
然后,在个人配置中选择中文即可
strapi 自定义控制器方法与路由
在strapi
中创建的每一个内容类型(Content Type),strapi
都会生成默认crud接口供开发者使用。但这些往往不足以满足实际开发需求。这就要求我们拥有自定义strapi 控制器(controller)方法和 路由(route)的能力。
以本项目为例,在 src/api/article/routes
目录下新建文件 01-custom-article.js
(这是strapi
官方推荐的命名,使其能在默认路由文件article.js
之前读取),配置自定义路由。
js
module.exports = {
routes: [
{
// Path defined with a regular expression
method: "GET",
path: "/articles/newest", // Only match when the URL parameter is composed of lowercase letters
handler: "article.newest", // 对应controller下的newest方法
},
{
method: "GET",
path: "/articles/view/:id",
handler: "article.view",
},
],
};
在 src/api/article/controllers/article.js
中添加自定义newst
和view
方法。
js
module.exports = createCoreController("api::article.article", ({ strapi }) => ({
async newest(ctx) {
// ...
},
async view(ctx) {
// ...
}
},
}));
strapi 使用redis缓存
大多数时候,网站的内容是不变的。这使得我们可以通过缓存来获得性能提升。
这里主要使用strapi
社区的开源插件来实现。使用strapi-plugin-redis
插件来连接redis(项目中的文章访问量的实现,就使用了redis来缓存访客ip),使用strapi-plugin-rest-cache
和strapi-plugin-rest-cache-redis
插件实现strapi api缓存。
安装插件:
bash
yarn add \
strapi-plugin-rest-cache \
strapi-plugin-redis \
strapi-provider-rest-cache-redis
配置插件(config/plugins.js
):
js
module.exports = () => {
return {
// @see https://github.com/strapi-community/strapi-plugin-redis
redis: {
config: {
connections: {
default: {
connection: {
host: process.env.RedisHost || "redis",
port: 6379,
db: 0,
},
settings: {
debug: false,
},
},
},
},
},
"rest-cache": {
config: {
provider: {
name: "redis",
options: {
max: 32767, // 过期时间
connection: "default",
},
},
strategy: {
enableEtagSupport: true,
logs: true,
clearRelatedCache: true,
maxAge: 60000,
contentTypes: [
// list of Content-Types UID to cache
"api::head.head",
"api::footer.footer",
"api::article.article",
{// 自定义路由需要这样配置
contentType: "api::article.article",
routes: /* @type {CacheRouteConfig[]} */ [
{
path: "/api/articles/newest", // note that we set the /api prefix here
method: "GET", // can be omitted, defaults to GET
},
],
},
],
},
},
},
};
};
总结
本文分享了一个官网js全栈项目,并介绍了其中的部分重点。以本项目为例,证明了前端程序员可以在类似项目进行独立开发,并且拥有不错的性能。本项目中仍有其他难点没有介绍到,譬如nextjs
的ssr渲染写法、strapi
的controller方法,以及最后的nextjs
和strapi
docker部署等等。篇幅所限,有心人就自行阅读源码吧O(∩_∩)O