本文概述
- 开发前端:使其成为Gatsby网站
- 部署前端
- 使用构建挂钩进行每日更新
- AWS Lambda和AWS CloudWatch简单请求
- 现在为我们的静态网页提供动力:Gatsby / React和Netlify
对于某些项目要求, 静态页面生成不仅足够, 而且在速度和可伸缩性方面也是最高效的。
在本系列的前半部分, 我们将Node.js, Express, MongoDB, cron和Heroku结合在一起, 提供了一个CI就绪的后端, 该后端根据每日时间表使用了GitHub的API。现在, 我们准备将Gatsby添加到组合中, 以完成我们的静态页面生成项目。
开发前端:使其成为Gatsby网站
由于Gatsby(Gatsby)网站是基于React的, 因此如果你已经熟悉如何使用React构建网站, 这将非常有帮助。
对于样式, 我更喜欢Bootstrap, reactstrap和react-markdown。你可能知道GitHub中的发行说明以Markdown格式存储, 因此我们需要转换器。
静态网站项目结构
我们的文件/文件夹结构如下:
这些文件是做什么用的?让我们来看看:
- 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功能, 则应该看到类似以下内容:
在单击其中一个存储库后, 你应该会看到类似以下内容:
完成上述更改后, 我们的前端实现就完成了。
大!现在我们只需要部署。
部署前端
在这一部分中, 我们不需要对前端应用程序进行任何更改。我们只需将其部署到Netlify, 你将在那里需要一个帐户。
但是首先, 我们必须将代码部署到GitHub, GitLab或Bitbucket。与后端一样, 我将代码部署到GitHub。
然后, 登录Netlify并单击仪表板上的”来自Git的新站点”按钮。按照屏幕上的步骤选择你的Git提供程序并找到你的存储库。
对于最后一步, 如果你正确地构建了代码, Netlify将自动设置build命令并正确地发布目录, 如下所示:
然后单击”部署站点”。它将把你的站点部署到随机生成的Netlify子域中, 但是你可以随时更改它-我将部署更改为https://sample-create-page-api-gatsby.netlify.com, 你可以在其中找到实时演示已完成的应用程序。
到现在为止还挺好。但是, 由于它是静态页面应用程序, 因此我们必须每天对其进行重建以使其保持最新状态。
使用构建挂钩进行每日更新
Netlify中的构建挂钩作为构建触发器, 因此你可以在cron作业完成后从后端触发它们。为此, 首先在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上找到。
如果尚未选择, 请转到”功能”部分:
在这里, 我们将通过单击”创建功能”从头开始创建功能。让我们给它一个解释性的名字。我们将使用Node.js作为运行时语言。然后单击下一个”创建函数”完成。
它将重定向到新功能的页面, 在这里我们可以在index.js中编写代码。
让我们实现我们的第一个lambda函数。因为我们没有任何第三方依赖性, 所以我们必须使用Node.js的核心模块。 (如果你想启用第三方依赖关系, 请遵循AWS的本指南。)
确保导出的方法名称(在这种情况下为处理程序)与页面中的” 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环境变量, 并保存配置:
最后一步是添加一个CloudWatch触发规则, 以在每次每日更新前十分钟运行此功能, 在本系列文章中, 该规则的执行时间为23:50:
我们的CloudWatch触发规则类型将为”时间表表达式”, 根据公认的格式, 我们的cron表达式将为cron(50 23 * *?*)。
现在, 我们已将AWS Lambda函数配置为由CloudWatch规则触发。
现在为我们的静态网页提供动力:Gatsby / React和Netlify
通过将少量的AWS Lambda / CloudWatch添加到我们的Node.js / MongoDB / Heroku后端, 以及Gatsby和Netlify生成并托管我们的前端, 我们的应用程序就完成了!
我之前分享了一个实时演示链接, 但也可以随时查看我的原型的增强版-它有一些额外的变化, 我知道你会喜欢的。
你可以将其用作类似项目的蓝图-我希望这些文章将帮助你以更快, 更经济的方式来原型化你的应用程序。谢谢阅读!
评论前必须登录!
注册