little-bee-client

little-bee-client-logo

Why

为了让大家了解“蜂工地”项目,这篇博文详细介绍了“蜂工地”项目的工作原理。

“蜂工地”的目的什么?

“蜂工地”力求用最简洁的形式(如:“蜂博客”),记录和展示大家在开发过程中的感悟和心得。希望可以促进技术的交流和进步。

“蜂工地”为什么选择”Gatsby”框架?

“蜂工地”主要以博客形式进行展示。当下比较流行的博客搭建框架有:HexoJekyllHugo以及“Gatsby”。每种框架都有各自的优缺点,这里只说我们为什么选择Gatsby。如果您对其他框架的特点也感兴趣,可以参考这篇文章

Gatsby主要特点如下:

What

“蜂工地”是什么项目?

“蜂工地”是“蜂乐园”项目中的基于Gatsby框架的子项目,是“蜂乐园”的入口,用于向用户展示整个“蜂乐园”项目。之所以叫“蜂工地”,是因为它还处于建设阶段。当前主要以“蜂博客”的形式,用图片和文字记录和展示开发过程中的感悟和心得。希望以后可以有更多、更有趣的形式加入进来。

Gatsby是如何工作的?

Gatsby涉及的技术比较多,简单地说它是一个静态网页生成器,可以读取Markdown文件并在网页中渲染出来。因此十分适合做一个博客系统。详情可参考“蜂博客”:什么是”Gastby”

“蜂工地”是如何工作的?

“蜂工地”是如何实现的?

“蜂工地”是一个基于“Gatsby”框架的React网站。下面罗列了部分“蜂工地”涉及的技术。如果您对以项某项内容感兴趣,那么您可以继续往下看。在“How”部分,我们将详细介绍“蜂工地”是如何实现的。

How

“蜂工地”项目结构

.
├── README.md           // 说明文档
├── configs             // 配置文件夹
|    ├── jest           // jest测试配置子文件夹
|    ├── metadata.js    // 自定义配置数据
|    └── postcss.js     // postcss配置文件
├── gatsby-browser.js   // Gatsby框架API文件
├── gatsby-config.js    // Gatsby框架API文件
├── gatsby-node.js      // Gatsby框架API文件
├── gatsby-ssr.js       // Gatsby框架API文件
├── jest.config.js      // jest测试主配置文件
├── package.json        // npm工程包管理文件
├── public              // 存放项目编译出的静态文件
├── src                 // 源文件夹
|    ├── assets         // 样式资源文件夹
|    ├── components     // React组件文件夹
|    ├── gatsby-api     // 存放Gatsby框架API调用的文件
|    ├── pages          // 静态页面文件夹
|    ├── shared         // 存放项目共享代码
|    └── templates      // 存放用于动态页面生成的模板
├── static              // 存放静态资源
|    ├── images         // 存放网站中用到的图片
|    ├── pages          // 存放菜单页面md文件
|    └── posts          // 存放博客页面md文件
└── tsconfig.json       // TypeScript配置文件

如何在“蜂工地”中添加一篇“蜂博客”

在“蜂工地”中添加一篇“蜂博客”非常简单,只需要以下几个步骤:

git clone https://github.com/yuxiang660/little-bee-client.git
npm i
gatsby develop

如何利用JS文件产生一个页面

“蜂工地”公开的网页都是通过模板动态生成的,只有一个内部调试的‘debug’页面利用JS文件(准确的说是TS文件,“蜂工地”为保证产品质量,都是基于TypeScript编写的)生成。
下面以此’debug’页面诠释Gatsby利用JS文件生成一个静态网页的工作流程。

Debug页面效果

Debug页面代码解析

const Debug = () =>
(
  <Layout title="Debug">
    <SiderBar /> // 页面左侧的侧边栏
    <Files /> // 页面右侧的文件名列表
  </Layout>
);
export default Debug;

如何利用模板动态生成一个页面

静态网站生成器之所以叫生成器,就是因为他们可以根据模板,自动生成多个页面。Gatsby作为一个强大的静态网站生成器(当然Gatsby的功能远大于一个静态网站生成器),自然可以根据模板生成页面。

简单来说,如下图所示,Gatsby读取对用户友好的Markdown文件,按照template模板的规则,自动生成对应的一个网页。这样,用户就可以只撰写一个Markdown语法格式的文档,就可以得到一个网页,分享在互联网上。 gatsby-template

下面以/src/templates/not-found.tsx为例子,阐述“蜂工地”的动态页面生成过程。

‘not-found’页面效果

‘not-found’动态页面生成代码分析

// /src/templates/not-found.tsx
const NotFoundTemplate = () => {
  const { title, subtitle } = useSiteMetadata();

  return (
    <Layout title={`Not Found - ${title}`} description={subtitle}>
      <Sidebar />
      <Page title="NOT FOUND">
        <p>You just hit a route that doesn&#39;t exist... the sadness.</p>
      </Page>
    </Layout>
  );
};
export default NotFoundTemplate;
// /src/gatsby-api/pages/index.js
createPage({
  path: '/404',
  component: path.resolve('./src/templates/not-found.tsx'),
});

你会发现,模板代码和静态页面的JS代码没有什么区别,都是export一个React-JSX。甚至对于not-found页面,把其模板文件挪到/src/pages文件夹下,并重命名为404.tsx。同样能在http://localhost:8000/404下访问到相同的页面。

动态生成网页的什么优势

对于单一页面,利用模板动态生成较静态页面并没有什么优势。但是,对于多页面,模板的优势就体现出来了。以博客系统为例,每篇博文的样式都是一样的,因此可以利用同一份模板,快速生成多个页面。

“蜂博客”渲染过程

在“蜂工地”中,Gatsby利用同一份‘post’模板,对不同的博客内容进行渲染,生成对应的博客页面。

“蜂博客”post模板

// 关键代码
const PostTemplate: React.FC<PostTemplateProps> = ({ data }) => {
  ...
  return (
    <Layout title={`${postTitle} - ${siteTitle}`} description={metaDescription}>
      <Post post={data.markdownRemark} />
    </Layout>
  );
};

// GraghQL API 用于获取网站中的任何数据
export const query = graphql`
  query PostBySlug($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      ...
  }
`;

export default PostTemplate;

对比post模板和not-found模板,post模板利用GraphQL获取了Markdown文件的内容,并一起被渲染成页面。而not-found模板没有处理外部数据,被渲染的只是一个空模板。

强大的’GraphQL’

‘GraphQL’Gatsby中最关键的技术,管理着Gatsby网页的所有数据。Gatsby在编译阶段,会将所有数据(包括以Markdown格式存放的博客文件)存入’GraphQL’,因此所有页面都可以很方便地通过GraphQL API获取所有数据。详情可参考“蜂博客”:什么是”Gastby”

为了便于调试,Gatsby还为我们自动生成了___graphql页面,用于本地开发调试。gatsby develop启动网站后,输入http://localhost:8000/___graphql即可得到如下页面,可用GraphQL API操作所有数据: graphql