作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
Furkan Yavuz's profile image

Furkan Yavuz

Furkan是一名经验丰富的全栈开发人员,自2016年以来一直远程工作. 他的主要专长包括Java、Angular和Heroku.

Expertise

Previously At

Turkish Airlines
Share

对于一些项目需求,静态页面生成不仅仅是 sufficient, it’s also the most efficient 在速度和可扩展性方面.

In the first half of this series, we combined Node.js, Express, MongoDB, cron, and Heroku 提供一个CI-ready的后端,根据每天的时间表使用GitHub的API. 现在我们准备将Gatsby添加到混合中,以完成静态页面生成项目.

开发前端:使其成为盖茨比网站

因为盖茨比的网站是基于 React,如果你已经熟悉如何用React构建网站,它会很有帮助.

对于样式,我更喜欢Bootstrap、reactstrap和react-markdown. You may know that GitHub中的发行说明以Markdown格式存储,因此我们需要一个转换器.

静态网站项目结构

我们的文件/文件夹结构如下:

一个标准的前端项目根目录,包含一个空的公共文件夹和一个src文件夹,用于存放package之类的文件.json. src文件夹下是一个styles子文件夹,用于全局.CSS和用于所有存储库的模板子文件夹.js and repository.js.

What are these files for? Let’s see:

  • env.development and env.production 环境变量是配置文件吗.
  • The all-repositories.js 模板将用于我们的主页,其中包含一个存储库列表.
  • The repository.js 模板将用于显示给定存储库的详细信息.
  • gatsby-node.js 是我们使用后端端点并运行 createPage methods.
  • package.json与往常一样,包含依赖项和项目属性.
  • global.css is our main style sheet file.

Gatsby Website Implementation

As with our back end, run npm install (or yarn(如果你已经安装了Yarn),然后将所需的依赖项添加到前端 package.json:

{
  // ...
  "dependencies": {
    "axios": "^0.18.0",
    "bootstrap": "^4.3.1",
    "gatsby": "^2.0.0",
    "react": "^16.5.1",
    "react-dom": "^16.5.1",
    "react-markdown": "^4.0.6",
    "reactstrap": "^7.1.0"
  }
  // ...
}

The env.development and env.production 文件只有对应环境的后端URL. The former has:

API_URL=http://localhost:3000

…while production has:

API_URL = http:// [YOUR_UNIQUE_APP_NAME].herokuapp.com

gatsby-node.js 在构建代码时只运行一次吗. 所以我们必须从后台收集所有必要的信息. 然后,响应将与模板一起使用,以生成适当的静态页面.

In our case, all-repositories.js needs all repositories, and repository.js 每次迭代都需要相应的存储库. 最后,我们可以动态地生成页面路径,传递存储库 owner and name parameters as part of the path field:

Const axios = require('axios');

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`
});

const getRepositoryData = async () => {
  console.log(process.env.API_URL);
  return axios.get(`${process.env.API_URL}/repositories`);
};

exports.createPages = async ({
  actions: {
    createPage
  }
}) => {
  let repositories = await getRepositoryData();
  repositories = repositories.data;

  //创建一个页面,列出所有存储库.
  createPage({
    path: `/`,
    component: require.resolve('./ src /模板/所有存储库.js'),
    context: {
      repositories
    }
  });

  //为每个存储库创建一个页面.
  repositories.forEach(repository => {
    createPage({
      路径:/仓库/ ${库.owner}/${repository.name}`,
      component: require.resolve('./src/templates/repository.js'),
      context: {
        repository
      }
    });
  });
};

For all-repositories.js and repository.js,如果我们省略样式化,我们只是从 pageContext 并像在React中使用参数一样使用它.

In all-repositories.js, we will use the repositories field of pageContext like this:

export default ({pageContext: {repositories}}) => (
// ...
    
      {/*因为repositories参数是一个列表, 我们遍历所有项并使用它们的字段*/}
      {repositories.map(repository => (repository.tagName &&
        
// ...
              
                {`${repository.repositoryDescription}`}
              
// ...
        
      ))}
    
// ...
);

As for repository.js, we will instead use the repository field of pageContext:

export default ({pageContext: {repository}}) => (
  
{repository.tagName && // ...

{`Release notes`}


{/*我们将在这里使用markdown格式的发布说明*/}
} // ...
);

现在,确保您的后端已启动并运行. 您应该还记得,对于这个项目,我们将其设置为 http://localhost:3000.

Next, run gatsby develop 从您的前端项目的根目录中打开 http://localhost:8000.

如果你添加了一些存储库(所有者/名称)到你的后端,并运行update-via-GitHub-API功能至少一次, 你应该看到这样的内容:

我们的应用程序的存储库列表主页,显示了GitHub repos示例的基本信息

点击其中一个仓库后,你应该会看到这样的内容:

一个示例库详细页面,显示有关facebook/react GitHub仓库的更多信息

After our changes above, 我们的前端实现完成了.

Great! Now we just have to deploy.

Deploying the Front End

在这一部分中,我们不需要对前端应用程序进行任何更改. We will simply deploy it to Netlify—you’ll need an account there.

但首先,我们必须将代码部署到GitHub、GitLab或Bitbucket. As with the back end, I deployed my code to GitHub.

然后,登录netflix,点击仪表板上的“New site from Git”按钮. 按照屏幕上的步骤选择Git提供程序并找到存储库.

For the final step, 如果你的代码结构正确的话, netflix会自动设置build命令和发布目录,如下所示:

netflix构建选项的正确设置:部署主服务器, use "gatsby build" as the build command, and publish to the "public/" directory.

Then click “Deploy site.它会将你的网站部署到一个随机生成的网飞子域名, 但你可以随时更改——我将部署更改为 http://sample-create-page-api-gatsby.netlify.com,在那里你可以找到一个完整的应用程序的现场演示.

So far, so good. 但由于它是一个静态页面应用程序,我们必须每天重新构建它以保持更新.

使用构建钩子进行每日更新

在netflix中构建钩子作为构建触发器工作, 因此,您可以在cron作业完成后从后端触发它们. 为了做到这一点,首先在netflix中创建一个构建钩子.

Under the “Build & “部署→持续部署”部分,您可以找到“构建钩子”.” Click “Add build hook.”

在netflix哪里可以找到构建钩子

Give it a name and save it. (I called mine build-from-backend.)然后复制它生成的链接.

现在让我们打开后端项目并将这几行添加到 cron.controller.js file. We are simply sending a POST 请求netflix的build-hook URL.

const Axios = require(' Axios ');
const Config = require('../config/env.config');

const NETLIFY_BUILD_HOOK_URI = Config.netlifyEndpoint;

function updateGatsby() {

  if (NETLIFY_BUILD_HOOK_URI) {
    console.log('盖茨比构建请求将被发送');

    Axios.post(NETLIFY_BUILD_HOOK_URI).then(() => {
      console.log('Gatsby构建请求成功');
    });
  }
}

Then update our updateDaily function:

function updateDaily() {
  RepositoryController.updateRepositories().then(() => {
    updateGatsby();
  });
}

Finally, update our env.config.js file to set the netlifyEndpoint 属性,从环境变量中收集:

"netlifyEndpoint": process.env.NETLIFY_BUILD_HOOK || ""

Now, you’ll need to set the NETLIFY_BUILD_HOOK 环境变量,你刚才从netflix复制的. In Heroku, 您可以在应用程序的“设置”部分设置环境变量.

After pushing your commit, 后端应用程序将向netflix发送构建请求,您的页面将每天更新, at the end of your cron job. 回购应该是这样的 在添加构建钩子功能之后,以及 the back-end repo and the front-end repo.

作为项目的最后一笔,我们将展示如何使用 AWS 由AWS CloudWatch触发的Lambda函数,将在每次每日更新时及时唤醒您的后端.

AWS Lambda和AWS CloudWatch简单请求

AWS Lambda 是无服务器计算平台吗. We only need the very basics 为了我们的目的. You’ll need an AWS account.

首先,使用您的帐户登录AWS并找到Lambda管理控制台. For example, for us-east-2, it can be found at http://us-east-2.console.aws.amazon.com/lambda/home.

如果它还没有被选中,转到“函数”部分:

AWS Lambda“函数”部分

在这里,我们将通过单击“create function”从头创建函数.“让我们给它起一个解释性的名字. We will use Node.js as a runtime language. 然后点击下一个“创建函数”来完成它.

AWS Lambda's "Create function" page, filled out at create triggerMyBackendAtUTCMidnight with a Node.一个具有基本Lambda权限的新角色

它将把我们重定向到新函数的页面,我们可以在其中编写代码 index.js.

让我们实现第一个lambda函数. 因为我们没有任何第三方依赖,所以我们必须使用Node的核心模块.js. (如果您想启用第三方依赖项,请 follow this guide from AWS.)

确保导出的方法名(handler 在这种情况下)匹配页面中的" Handler "参数:

带有“index”的Handler参数.handler" as its value

The rest of it is a simple GET request to your back end:

Const HTTPS = require(' HTTPS ');

exports.handler = async (event) => {
  return new Promise((resolve, reject) => {
    http.get(process.env.HEROKU_APP_URL, (resp) => {
      let data = '';
      resp.on('data', (chunk) => {
        data += chunk;
      });

      resp.on('end', () => {
        resolve(JSON.parse(data));
      });
    }).on("error", (err) => {
      reject("Error: " + err.message);
    });
  });
};

Make sure you set the HEROKU_APP_URL 环境变量,并保存您的配置:

在AWS Lambda中设置所需的环境变量. 显示的值为http://sample-github-api-consumer-nod.herokuapp.com/repositories.

在本系列文章中,最后一步是添加CloudWatch触发规则,以便在每日更新前10分钟运行此函数, that works out to 23:50:

配置CloudWatch Events以添加触发规则

我们的CloudWatch触发规则类型将是“调度表达式”和, 根据接受的格式, our cron expression will be cron(50 23 * * ? *).

AWS CloudWatch“配置触发器”页面, 设置为创建一个名为cronDailyUpdate的新规则,使用上面给出的表达式并启用触发器

现在,我们已经将AWS Lambda函数配置为由CloudWatch规则触发.

现在为我们的静态网页提供动力:盖茨比/React和netflix

在我们的节点上添加一点AWS Lambda/CloudWatch.js/MongoDB/Heroku back end, 盖茨比和netflix生成和托管我们的前端, our app is complete!

我之前分享了一个现场演示链接,但也可以随意查看 我的原型的增强版它有一些额外的变化,我知道你会喜欢的.

您可以将此作为类似项目的蓝图—我希望这些文章将帮助您以更快、更经济的方式构建应用程序原型. Thanks for reading!

Toptal是高级AWS咨询合作伙伴.

Understanding the basics

  • What is Gatsby?

    Gatsby.js(或者简称为“Gatsby”)是一个开源的、基于react的静态站点生成框架.

  • What is Netlify?

    netflix是一个静态站点主机,类似于GitHub Pages,但有一些额外的功能.

  • 什么是静态站点生成器?

    静态网站生成器使用当前数据从模板创建静态网站. 生成的站点非常快, 但是能够定期生成它意味着它可以自动保持最新.

聘请Toptal这方面的专家.
Hire Now
Furkan Yavuz's profile image
Furkan Yavuz

Located in Istanbul, Turkey

Member since March 15, 2019

About the author

Furkan是一名经验丰富的全栈开发人员,自2016年以来一直远程工作. 他的主要专长包括Java、Angular和Heroku.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

Expertise

Previously At

Turkish Airlines

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

世界级的文章,每周发一次.

订阅意味着同意我们的 privacy policy

Toptal Developers

Join the Toptal® community.