个性化阅读
专注于IT技术分析

前端:使用Gatsby.js和Node.js进行静态网站更新

本文概述

对于某些项目要求, 静态页面生成不仅足够, 而且在速度和可伸缩性方面也是最高效的。

在本系列的前半部分, 我们将Node.js, Express, MongoDB, cron和Heroku结合在一起, 提供了一个CI就绪的后端, 该后端根据每日时间表使用了GitHub的API。现在, 我们准备将Gatsby添加到组合中, 以完成我们的静态页面生成项目。

开发前端:使其成为Gatsby网站

由于Gatsby(Gatsby)网站是基于React的, 因此如果你已经熟悉如何使用React构建网站, 这将非常有帮助。

对于样式, 我更喜欢Bootstrap, reactstrap和react-markdown。你可能知道GitHub中的发行说明以Markdown格式存储, 因此我们需要转换器。

静态网站项目结构

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

一个标准的前端项目根目录,带有一个空的公共文件夹和一个src文件夹,用于存储package.json之类的文件。在src文件夹下面是global.css的样式子文件夹,以及all-repositories.js和repository.js的模板子文件夹。

这些文件是做什么用的?让我们来看看:

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

Gatsby网站实施

与我们的后端一样, 在将必需的依赖项添加到前端的package.json中之后, 运行npm install(如果安装了Yarn, 则运行yarn):

{
  // ...
  "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"
  }
  // ...
}

env.development和env.production文件仅具有其相应环境的后端URL。前者有:

API_URL=http://localhost:3000

…同时生产有:

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

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

在我们的例子中, all-repositories.js需要所有存储库, 而repository.js每次迭代都需要相应的存储库。最后, 我们可以动态生成页面路径, 并将存储库所有者和名称参数作为路径字段的一部分传递:

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;

  // Create a page that lists all repositories.
  createPage({
    path: `/`, component: require.resolve('./src/templates/all-repositories.js'), context: {
      repositories
    }
  });

  // Create a page for each repository.
  repositories.forEach(repository => {
    createPage({
      path: `/repository/${repository.owner}/${repository.name}`, component: require.resolve('./src/templates/repository.js'), context: {
        repository
      }
    });
  });
};

对于all-repositories.js和repository.js, 如果我们省略样式, 我们只是从pageContext收集数据并在React中使用参数时使用它。

在all-repositories.js中, 我们将像这样使用pageContext的repositories字段:

export default ({pageContext: {repositories}}) => (
// ...
    <ListGroup>
      {/* Because the repositories parameter is a list, we are iterating over all items and using their fields */}
      {repositories.map(repository => (repository.tagName &&
        <ListGroupItem className="repository-list-item">
// ...
              <Row>
                {`${repository.repositoryDescription}`}
              </Row>
// ...
        </ListGroupItem>
      ))}
    </ListGroup>
// ...
);

至于repository.js, 我们将改用pageContext的repository字段:

export default ({pageContext: {repository}}) => (
  <div className="layout">
    {repository.tagName &&
    <ListGroupItem className="repository-list-item">
// ...
          <h1 className="release-notes">{`Release notes`}</h1>
          <hr/>
          {/* This the place where we will use Markdown-formatted release notes */}
          <ReactMarkdown source={`${repository.releaseDescription}`}/>
    </ListGroupItem>
    }
// ...
  </div>
);

现在, 确保你的后端已启动并正在运行。你会回想起该项目, 我们将其设置为http:// localhost:3000。

接下来, 从前端项目的根目录运行gatsby development并打开http:// localhost:8000。

如果确实向后端添加了一些存储库(所有者/名称)并至少运行一次update-via-GitHub-API功能, 则应该看到类似以下内容:

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

在单击其中一个存储库后, 你应该会看到类似以下内容:

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

完成上述更改后, 我们的前端实现就完成了。

大!现在我们只需要部署。

部署前端

在这一部分中, 我们不需要对前端应用程序进行任何更改。我们只需将其部署到Netlify, 你将在那里需要一个帐户。

但是首先, 我们必须将代码部署到GitHub, GitLab或Bitbucket。与后端一样, 我将代码部署到GitHub。

然后, 登录Netlify并单击仪表板上的”来自Git的新站点”按钮。按照屏幕上的步骤选择你的Git提供程序并找到你的存储库。

对于最后一步, 如果你正确地构建了代码, Netlify将自动设置build命令并正确地发布目录, 如下所示:

Netlify的构建选项的正确设置:部署主服务器,使用" gatsby build"作为构建命令,然后发布到" public /"目录。

然后单击”部署站点”。它将把你的站点部署到随机生成的Netlify子域中, 但是你可以随时更改它-我将部署更改为https://sample-create-page-api-gatsby.netlify.com, 你可以在其中找到实时演示已完成的应用程序。

到现在为止还挺好。但是, 由于它是静态页面应用程序, 因此我们必须每天对其进行重建以使其保持最新状态。

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

Netlify中的构建挂钩作为构建触发器, 因此你可以在cron作业完成后从后端触发它们。为此, 首先在Netlify中创建一个构建挂钩。

在”构建和部署→连续部署”部分下, 你可以找到”构建挂钩”。点击”添加构建挂钩”。

在Netlify中哪里可以找到构建挂钩

给它命名并保存。 (我叫mine build-from-backend。)然后复制它生成的链接。

现在, 打开我们的后端项目, 并将这几行添加到cron.controller.js文件中。我们只是向Netlify的构建挂钩URL发送POST请求。

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('Gatsby build request will be send');

    Axios.post(NETLIFY_BUILD_HOOK_URI).then(() => {
      console.log('Gatsby build request was successful');
    });
  }
}

然后更新我们的updateDaily函数:

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

最后, 更新我们的env.config.js文件以将netlifyEndpoint属性设置为从环境变量中收集:

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

现在, 你需要设置你刚才从Netlify复制的NETLIFY_BUILD_HOOK环境变量。在Heroku中, 你可以从应用程序的”设置”部分设置环境变量。

推送你的提交后, 后端应用程序将向Netlify发送构建请求, 并且你的页面将在cron作业结束时每天进行更新。添加了构建挂钩功能以及后端存储库和前端存储库的最终版本后, 存储库应如下所示。

作为项目的最后一步, 我们将展示如何使用由AWS CloudWatch触发的AWS Lambda函数, 该函数将及时唤醒你的后端, 进行每日的每日更新。

AWS Lambda和AWS CloudWatch简单请求

AWS Lambda是无服务器计算平台。在这里, 我们只需要该平台的基础知识即可。你需要一个AWS账户。

首先, 使用你的账户登录AWS, 然后找到Lambda管理控制台。例如, 对于us-east-2, 可以在https://us-east-2.console.aws.amazon.com/lambda/home上找到。

如果尚未选择, 请转到”功能”部分:

AWS Lambda"功能"部分

在这里, 我们将通过单击”创建功能”从头开始创建功能。让我们给它一个解释性的名字。我们将使用Node.js作为运行时语言。然后单击下一个”创建函数”完成。

AWS Lambda的"创建函数"页面,在创建triggerMyBackendAtUTCMidnight时填写,带有Node.js运行时和具有基本Lambda权限的新角色

它将重定向到新功能的页面, 在这里我们可以在index.js中编写代码。

让我们实现我们的第一个lambda函数。因为我们没有任何第三方依赖性, 所以我们必须使用Node.js的核心模块。 (如果你想启用第三方依赖关系, 请遵循AWS的本指南。)

确保导出的方法名称(在这种情况下为处理程序)与页面中的” Handler”参数匹配:

以" index.handler"为值的Handler参数

剩下的就是对你的后端的简单GET请求:

const https = require('https');

exports.handler = async (event) => {
  return new Promise((resolve, reject) => {
    https.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);
    });
  });
};

确保在页面中设置了HEROKU_APP_URL环境变量, 并保存配置:

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

最后一步是添加一个CloudWatch触发规则, 以在每次每日更新前十分钟运行此功能, 在本系列文章中, 该规则的执行时间为23:50:

配置CloudWatch Events以添加触发规则

我们的CloudWatch触发规则类型将为”时间表表达式”, 根据公认的格式, 我们的cron表达式将为cron(50 23 * *?*)。

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

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

现在为我们的静态网页提供动力:Gatsby / React和Netlify

通过将少量的AWS Lambda / CloudWatch添加到我们的Node.js / MongoDB / Heroku后端, 以及Gatsby和Netlify生成并托管我们的前端, 我们的应用程序就完成了!

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

你可以将其用作类似项目的蓝图-我希望这些文章将帮助你以更快, 更经济的方式来原型化你的应用程序。谢谢阅读!

srcmini是高级AWS咨询合作伙伴。
赞(0)
未经允许不得转载:srcmini » 前端:使用Gatsby.js和Node.js进行静态网站更新

评论 抢沙发

评论前必须登录!