分享一个适合前端初学者练手的小项目,strapi+nextjs全栈官网项目

前言

我们知道,官网通常是需要快速的首屏响应,也需要做seo优化,所以建议使用现代ssr框架来实现网站。诸如博客、官网之类的应用,都是以 内容发布 为主要功能的网站。往往需要一个后台系统,所以建议使用cms来作为内容管理系统。因此,在本项目选择了nextjs 来开发官网,选择strapi来作为后台系统,nextjsstrapi 都以 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社区开发的插件实现redisstrapi连接,这极大提高了本项目的后端性能。

官网开发

响应式网站开发

这里采用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 Routerapp 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中添加自定义newstview方法。

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-cachestrapi-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方法,以及最后的nextjsstrapidocker部署等等。篇幅所限,有心人就自行阅读源码吧O(∩_∩)O

源码地址

官网全栈项目(前端) 官网全栈项目(后端)

相关推荐
审小匠OpenCPAi32 分钟前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution6136 分钟前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化
mONESY39 分钟前
React useState 核心原理与最佳实践:从异步更新到性能优化全解
javascript
腻害兔1 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:CRM 客户关系模块深度解析——从线索到回款,一套完整的 B2B 销售闭环是怎么搭的?
java·前端·javascript·vue.js·产品经理·ai编程
whyfail1 小时前
前端学 Spring Boot(2):一次点击,如何穿过整个后端?
前端·spring boot·后端
AI多Agent协作实战派2 小时前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
gis开发之家2 小时前
《Vue3 从入门到大神37篇》Vue3 源码详解(七):watch 与 watchEffect 源码对比——副作用是如何被追踪的?
javascript·前端框架·vue3·vue3源码
2601_955760073 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby3 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
bloglin999993 小时前
langchain 和 langgraph 和 react
javascript·react.js·langchain