<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Node - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Node - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 11 Jun 2026 20:33:07 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/tag/node/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 生产环境 Node.js  检查清单 ]]>
                </title>
                <description>
                    <![CDATA[ 你在生产中是否正确使用 Node？让我们看看人们在生产环境中运行Node的一些常见错误（直接来自我自己的项目——如codedamn [https://codedamn.com]），以及如何减少这些错误。 当你部署Node应用程序时，你可以把它作为你在生产环境中的检查清单。由于这是一篇关于生产环境准备的文章，当你在本地系统上开发应用程序时，其中很多内容并不适用。 以cluster（集群）模式运行/separate node进程 记住，Node是单线程（single threaded）的。它可以将很多事情（如HTTP请求和文件系统的读写）委托给操作系统，由它在多线程（multithreaded）环境下处理。但是，你写的代码，即业务逻辑，仍然是在单线程中运行。 通过在单线程中运行，你的Node进程总是被限制在你的CPU上一个核心。因此，如果你的服务器有多个CPU核，那么你在服务器上只运行一个Node进程就是在浪费计算能力。 running Node just once 是什么意思？你看，操作系统有一个内置的调度器，它负责程序进程如何在机器的CPU上分配。当你在一台双核机器上只运行2个 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/node-js-production-checklist/</link>
                <guid isPermaLink="false">658bf0a0576bb403fc79122c</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Wed, 27 Dec 2023 09:48:42 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2023/12/0_4citSsBqjYDX7hUO.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/node-js-production-checklist/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Ultimate Node.js Production Checklist</a>
      </p><!--kg-card-begin: markdown--><p>你在生产中是否正确使用 Node？让我们看看人们在生产环境中运行Node的一些常见错误（直接来自我自己的项目——如<a href="https://codedamn.com">codedamn</a>），以及如何减少这些错误。</p>
<p>当你部署Node应用程序时，你可以把它作为你在生产环境中的检查清单。由于这是一篇关于生产环境准备的文章，当你在本地系统上开发应用程序时，其中很多内容并不适用。</p>
<h2 id="clusterseparatenode">以cluster（集群）模式运行/separate node进程</h2>
<p>记住，Node是单线程（single threaded）的。它可以将很多事情（如HTTP请求和文件系统的读写）委托给操作系统，由它在多线程（multithreaded）环境下处理。但是，你写的代码，即业务逻辑，仍然是在单线程中运行。</p>
<p>通过在单线程中运行，你的Node进程总是被限制在你的CPU上一个核心。因此，如果你的服务器有多个CPU核，那么你在服务器上只运行一个Node进程就是在浪费计算能力。</p>
<p><code>running Node just once</code>是什么意思？你看，操作系统有一个内置的调度器，它负责程序进程如何在机器的CPU上分配。当你在一台双核机器上只运行2个进程时，操作系统会决定最好在不同的CPU核上分别运行这两个进程，以挤出最大的性能。</p>
<p>对Node也需要做类似的事情。在这一点上，你有两个选择：</p>
<ol>
<li><strong>Run Node in cluster mode</strong>——集群（cluster）模式是一种架构，Node本身已经支持。简单地说，Node会分叉（forks）出更多自己的进程，并通过一个主进程（master process）分配负载。</li>
<li><strong>Run Node processes independently</strong>——这个选项与上面的略有不同，因为你现在没有一个主进程来控制子Node进程。这意味着，当你产生不同的Node进程时，它们将完全独立运行。没有共享内存，没有IPC，没有通信，什么都没有。</li>
</ol>
<p>根据<a href="https://stackoverflow.com/a/47122606/2513722">stackoverflow answer</a>，后者（选择 2）的性能好得多，但设置起来有点麻烦。</p>
<p>为什么呢？因为在Node应用中，不仅有应用逻辑，而且当你在Node代码中设置服务时，几乎总是需要绑定端口。而一个应用程序的代码库不能在同一个操作系统上绑定两次相同的端口。</p>
<p>然而，这个问题是很容易解决的。环境变量、Docker容器、NGiNX前端代理（frontend proxy）等等都是这方面的一些解决方案。</p>
<h2 id="endpoints">限制你的接入点（endpoints）速率</h2>
<p>让我们面对现实吧。世界上不是每个人都对你的服务器抱有良好的意图。当然，像DDoS这样的攻击是非常复杂的，甚至像GitHub这样的巨头在发生这样的事情时也会瘫痪。</p>
<p>但是，你至少可以防止一个脚本小子对你的服务器上暴露的一个昂贵的、没有设置任何速率限制的 API 端点进行攻击，从而导致你的服务器瘫痪。</p>
<p>如果你使用Express和Node，有2个好用的包（packages），它们可以无缝地一起工作，在第7层限制流量。</p>
<ol>
<li>Express Rate Limit - <a href="https://www.npmjs.com/package/express-rate-limit">https://www.npmjs.com/package/express-rate-limit</a></li>
<li>Express Slow Down - <a href="https://www.npmjs.com/package/express-slow-down">https://www.npmjs.com/package/express-slow-down</a></li>
</ol>
<p>Express Slow Down实际上是给你的请求慢慢增加的响应延迟，而不是丢弃它们。这样一来，如果合法用户不小心DDoS了（在这里和那里点击按钮的超级活动），他们只是被减慢了速度，而不会被限制速率。</p>
<p>另一方面，如果有一个脚本小子在运行脚本来破坏服务器，Express速率限制器会根据用户的IP、用户账户或其他你想要的东西来监控和限制这个特定的用户。</p>
<p>速率限制也可以（应该！）通过IP地址应用在第4层（第4层意味着在发现内容之前阻止流量-HTTP）。如果你愿意，你可以设置一个NGiNX规则，在第4层拦截流量，拒绝来自一个IP的流量，从而使你的服务器进程不至于不堪重负。</p>
<h2 id="frontendserverssl">使用前端服务器（frontend server）终止SSL</h2>
<p>Node提供了开箱即用的支持，使用<code>https</code>服务器模块和所需的SSL证书与浏览器进行SSL握手。</p>
<p>但是，让我们在这里说实话，无论如何，你的应用程序不应该首先关注SSL。这不是应用逻辑应该做的事情。你的节点代码应该只负责处理请求，而不是对进出服务器的数据进行预处理和后处理。</p>
<p>SSL终止（SSL termination）是指将流量从HTTPS转换为HTTP。在这方面，有比Node更好的工具可用。我推荐NGiNX或HAProxy。两者都有免费版本，可以完成工作，Node不用处理SSL问题。</p>
<h2 id="frontendserver">使用前端服务器（frontend server）来提供静态文件服务</h2>
<p>同样，与其使用内置的方法如<code>express.static</code>来提供静态文件，不如使用前端的反向代理服务器如NGiNX来来处理磁盘上的静态文件。</p>
<p>首先，NGiNX比Node做得更快（因为它是从头开始建立的，只做这个）。但它也从单线程的Node进程中接过文件服务，而Node可以把别的事做得更好。</p>
<p>不仅如此--像NGiNX这样的前端代理服务器还可以利用GZIP压缩技术帮助你更快地传送内容。你还可以设置过期标题、缓存数据等等，这不是我们应该期望Node做的事情（不过，Node还是可以做到的）。</p>
<h2 id="">配置错误处理</h2>
<p>正确的错误处理可以使你免于花费数小时的时间来调试和试图重现困难的错误。在服务器上，设置错误处理的架构特别容易，因为你是运行它的人。我推荐像<a href="https://sentry.io">Sentry</a>与Node这样的工具，它可以记录、报告并在服务器因源代码中的错误而崩溃时向你发送电子邮件。</p>
<p>一旦到位，现在是时候在服务器崩溃时重新启动它了，这样整个网站就不会瘫痪几个小时，直到你手动将它重新启动。</p>
<p>为此，你可以使用像<a href="https://www.npmjs.com/package/pm2">PM2</a>这样的进程管理器。或者更好的是，使用一个docker化的容器环境，使用诸如<code>restart: always</code>的策略，并设置适当的内存和磁盘限制。</p>
<p>Docker设置确保即使你的容器在OME中运行，进程也会再次启动起来（这在PM2环境中可能不会发生，因为如果运行中的进程在某处有内存泄漏，操作系统可能会杀死PM2）。</p>
<h2 id="">正确配置日志</h2>
<p>所有的答案都在日志中。服务器黑客攻击、服务器崩溃、可疑的用户行为等。为此，你必须确保：</p>
<ol>
<li>每一个请求尝试都会被记录下来，包括IP地址/请求方式/访问路径，基本上可以记录尽可能多的信息（当然，密码和信用卡信息等私人信息除外）</li>
<li>这可以通过<a href="https://www.npmjs.com/package/morgan">morgan</a>软件包实现。</li>
<li>在生产中设置<strong>文件流日志（file stream logs）</strong>，而不是控制台输出。这更快，更容易看到，并允许你将日志导出到在线日志查看服务。</li>
<li>不是所有的日志信息都具有同等重要性。有些日志只是用来调试的，而如果有些日志出现了，则可能预示着火烧眉毛的情况（如服务器被黑或未经授权的访问）。使用 winston-logger 可记录不同级别的日志。</li>
<li>设置<strong>日志轮换（log rotation）</strong>，这样你就不会在一个月左右后看到服务器的日志大小为GB。</li>
<li>在轮换（rotation）之后，<strong>GZIP</strong>你的日志文件。文本系统开销少（Text is cheap），而且可压缩性高，容易存储。只要文本日志被压缩了，而且你运行的服务器有相当大的磁盘空间（25GB以上），你就不应该面临文本日志的问题。</li>
</ol>
<h2 id="">结语</h2>
<p>在生产过程中注意到一些做法很容易，这可以让你在日后的调试过程中少走弯路。请确保你遵循这些最佳做法，并让我知道你的想法，请在我的<a href="https://twitter.com/mehulmpt">推特</a>反馈。</p>
<p>如果你喜欢这篇文章，让我们在社交媒体上交流。这是我的<a href="https://instagram.com/mehulmpt">Instagram</a>和 <a href="https://twitter.com/mehulmpt">Twitter</a>。我是超级活跃的人，很愿意聊天，欢迎你和我联系。</p>
<p>Peace!<br>
Mehul</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何处理 Node 报错 Error: error:0308010c:digital envelope routines::unsupported ]]>
                </title>
                <description>
                    <![CDATA[ 如果你使用 Node.js 和命令行界面解决方案，如 Webpack、create-react-app 或 vue-cli-service，你可能已经遇到了这个错误，Error: error:0308010c:digital envelope routines::unsupported. 你并不孤单，因为我现在也遇到了： React 应用程序确实未能启动： 在这篇文章中，你将学习如何通过 3 种方式来解决这个错误。但首先，让我们讨论一下导致该错误的原因。 什么原因导致 “0308010c:digital envelope routines::unsupported” 的错误？ 你遇到这个错误的可能原因主要有两个：  * 你没有使用 Node JS 的 LTS（长期支持）版本。你可以看到我使用的是 Node 17.0.0，这不是 Node 的 LTS 版本。  * 你使用的 react-script 的版本小于 5。 这个错误也可能发生，因为你使用的是Node 17。 如何解决 “0308010c:digital envelope routines::unsupported ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/error-error-0308010c-digital-envelope-routines-unsupported-node-error-solved/</link>
                <guid isPermaLink="false">63871af6832e3f07817637c3</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chengjun.L ]]>
                </dc:creator>
                <pubDate>Wed, 30 Nov 2022 04:19:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/11/envelope-1829509_1280.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/error-error-0308010c-digital-envelope-routines-unsupported-node-error-solved/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Error: error:0308010c:digital envelope routines::unsupported [Node Error Solved]</a>
      </p><p>如果你使用 Node.js 和命令行界面解决方案，如 Webpack、create-react-app 或 vue-cli-service，你可能已经遇到了这个错误，<code>Error: error:0308010c:digital envelope routines::unsupported</code>.</p><p>你并不孤单，因为我现在也遇到了：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/11/ss1-1.png" class="kg-image" alt="ss1-1" width="600" height="400" loading="lazy"></figure><p>React 应用程序确实未能启动：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/11/ss2-1.png" class="kg-image" alt="ss2-1" width="600" height="400" loading="lazy"></figure><p>在这篇文章中，你将学习如何通过 3 种方式来解决这个错误。但首先，让我们讨论一下导致该错误的原因。</p><h2 id="-0308010c-digital-envelope-routines-unsupported-">什么原因导致 “0308010c:digital envelope routines::unsupported” 的错误？</h2><p>你遇到这个错误的可能原因主要有两个：</p><ul><li>你没有使用 Node JS 的 LTS（长期支持）版本。你可以看到我使用的是 Node 17.0.0，这不是 Node 的 LTS 版本。</li><li>你使用的 react-script 的版本小于 5。</li></ul><p>这个错误也可能发生，因为你使用的是Node 17。</p><h2 id="-0308010c-digital-envelope-routines-unsupported--1">如何解决 “0308010c:digital envelope routines::unsupported” 的错误</h2><p>你至少有 3 种方法可以解决这个错误。我们将一个一个地看。任何一个都应该对你有用。</p><h3 id="-openssl-legacy-provider-webpack-cli-">将 --openssl-legacy-provider 传递给 Webpack 或 CLI 工具</h3><p>例如，在 React 应用程序中，你可以将 <code>--openssl-legacy-provider</code> 传递给启动脚本，如 <code>"react-scripts --openssl-legacy-provider start"</code>。</p><p>这应该就可以了。但是，如果这不能修复错误，那么就进行下一个修复。在许多情况下，它是有效的。</p><h3 id="-node-js-lts-">使用 Node JS &nbsp;的 LTS 版本</h3><p>考虑将你的 Node 版本降级到 16.16.0 或其他 LTS 版本。</p><p>目前，Node 的最新 LTS 版本是 18.12.1。你可以从 Node JS 官方网站下载它，或者使用 NVM 来安装它。</p><h3 id="-react-5-">将 React 脚本升级到 5 以上版本</h3><p>如果你正在使用 React，而这仍然无法为你解决错误，那么这很可能是你的 React 脚本的问题。</p><p>如果你使用的 React 脚本版本低于 5，那么你应该把它升级到 5+ 版本。</p><p>就我而言，我目前使用的是 react-scripts 3.4.3：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/11/ss3.png" class="kg-image" alt="ss3" width="600" height="400" loading="lazy"></figure><p>要将 react-scripts 升级到 5+，你可以通过两种方式进行：</p><p>卸载并重新安装 react-scripts</p><ul><li>打开终端，运行 <code>npm uninstall react-scripts</code></li><li>运行 <code>npm install react-scripts</code></li></ul><p>手动改变 react 脚本的版本</p><ul><li>进入你的 <code>package.json</code>，将 react-script 版本改为 5.0.2</li><li>通过运行 <code>rm –rf node_modules</code> 删除 node_modules 文件夹</li><li>通过运行 <code>rm –rf package.lock.json</code> 来删除 package.lock.json 文件</li><li>运行 <code>npm install</code> 或 <code>yarn add</code>，这取决于你所使用的软件包管理器</li></ul><p>在将 react-scripts 的版本升级到 5+ 之后，我的 React 应用程序现在可以正常工作了：</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/11/ss4.png" class="kg-image" alt="ss4" width="600" height="400" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2022/11/ss5.png" class="kg-image" alt="ss5" width="600" height="400" loading="lazy"></figure><h2 id="-"><strong>总结</strong></h2><p>正如上文指出的，如果你收到 “0308010c:digital envelope routines::unsupported” 的错误，那么可能是你没有使用 Node JS 的 LTS 版本，或者你使用的 react-scripts 版本小于 5。</p><p>希望我们在本教程中讨论的修复方法能帮助你解决这个错误。如果其中一个修复方法不起作用，那么你可以尝试其他方法。在我的例子中，将 react-scripts 升级到 5 以上就行了。</p><p>谢谢你阅读本文。</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Node 版本管理器 NVM 安装指南 ]]>
                </title>
                <description>
                    <![CDATA[ 在本文中，我将解释如何在 Windows、Linux 和 Mac 上安装 NVM（Node 版本管理器）。 什么是 NVM？ 顾名思义，NVM 是一种用于管理设备上的 Node 版本的工具。 你设备上的不同项目可能使用不同版本的 Node.js。对这些不同的项目仅使用一个版本（由 npm 安装的版本）可能无法为你提供准确的执行结果。 例如，如果你将 10.0.0 的 Node 版本用于使用 12.0.0 的项目，则可能会出现一些错误。如果你用 npm 将 Node 版本更新到 12.0.0 ，并且你将它用于使用 10.0.0 的项目，你可能无法获得预期的体验。 事实上，你很可能会收到一条警告： This project requires Node version X 无需使用 npm 为你的不同项目安装和卸载 Node 版本，你可以使用 NVM，它可以帮助你有效地管理每个项目的 Node 版本。 NVM [https://github.com/nvm-sh/nvm] 允许你安装不同版本的 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/node-version-manager-nvm-install-guide/</link>
                <guid isPermaLink="false">63283c1e5ef0a407fd62febf</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Mon, 12 Sep 2022 10:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/09/install-nvm.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/node-version-manager-nvm-install-guide/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Node Version Manager – NVM Install Guide</a>
      </p><p>在本文中，我将解释如何在 Windows、Linux 和 Mac 上安装 NVM（Node 版本管理器）。</p><h2 id="-nvm-">什么是 NVM？</h2><p>顾名思义，NVM 是一种用于管理设备上的 Node 版本的工具。</p><p>你设备上的不同项目可能使用不同版本的 Node.js。对这些不同的项目仅使用一个版本（由 <code>npm</code> 安装的版本）可能无法为你提供准确的执行结果。</p><p>例如，如果你将 <strong>10.0.0</strong> 的 Node 版本用于使用 <strong>12.0.0</strong> 的项目，则可能会出现一些错误。如果你用 npm 将 Node 版本更新到 <strong>12.0.0</strong>，并且你将它用于使用 <strong>10.0.0</strong> 的项目，你可能无法获得预期的体验。</p><p>事实上，你很可能会收到一条警告：</p><pre><code class="language-bash">This project requires Node version X
</code></pre><p>无需使用 npm 为你的不同项目安装和卸载 Node 版本，你可以使用 NVM，它可以帮助你有效地管理每个项目的 Node 版本。</p><p><a href="https://github.com/nvm-sh/nvm">NVM</a> 允许你安装不同版本的 Node，并根据你正在通过命令行处理的项目在这些版本之间切换。</p><p>在接下来的部分中，我将向你展示如何在你的 Windows、Linux 或 Mac 设备上安装 NVM。</p><p>在继续之前，如果你已经安装了 Node.js，我还建议你卸载它，这样就不会有 Node.js 和 NVM 之间的任何冲突。</p><h2 id="-windows-nvm-">如何在 Windows 上安装 NVM？</h2><p>NVM 主要在 Linux 和 Mac 上得到支持。它不支持 Windows。但是 coreybutler 创建了一个类似的工具，用于在 Windows 中提供 NVM 体验，叫作 <a href="https://github.com/coreybutler/nvm-windows">nvm-windows</a>。</p><p><code>nvm-windows</code> 提供了一个管理实用程序，用于在 Windows 中管理 Node.js 版本。以下是它的安装方法：</p><h3 id="1-">1.点击“立即下载”</h3><p>在 <a href="https://github.com/coreybutler/nvm-windows#readme">nvm-windows 仓库的 Readme 文件</a>中，单击“立即下载”：</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/09/image-338.png" class="kg-image" alt="image-338" width="600" height="400" loading="lazy"></figure><p>这将打开一个显示不同 NVM 版本的页面。</p><h3 id="2-exe-">2.安装最新版本的 .exe 文件</h3><p>在最新版本（截至撰写本文时为 <a href="https://github.com/coreybutler/nvm-windows/releases/tag/1.1.9">1.1.9</a>）中，你会发现不同的资源。单击 <strong><strong>nvm-setup.exe</strong></strong> 资源，它是该工具的安装文件：</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2022/09/image-340.png" class="kg-image" alt="image-340" width="600" height="400" loading="lazy"></figure><h3 id="3-">3.完成安装向导</h3><p>打开你下载的文件，然后完成安装向导。</p><p>完成后，你可以通过运行以下命令确认 NVM 已安装：</p><pre><code class="language-bash">nvm -v
</code></pre><p>如果 NVM 安装正确，此命令将显示已安装的 NVM 版本。</p><h2 id="-linux-mac-nvm">如何在 Linux 和 Mac 上安装 NVM</h2><p>由于 Linux 和 Mac 有一些相似之处（它们都是基于 UNIX 的操作系统），因此你可以以类似的方式在它们上安装 NVM。</p><h3 id="1-nvm-">1.运行 NVM 安装程序</h3><p>在你的终端中，像这样运行 NVM 安装程序：</p><pre><code class="language-bash">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

# or

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
</code></pre><p>你可以根据设备上可用的命令使用 <code>curl</code> 或 <code>bash</code>。</p><p>这些命令会将 NVM 仓库克隆到设备上的 <code>~/.nvm</code> 目录。</p><h3 id="2-">2. 更新你的个人资料配置</h3><p>第 1 步的安装过程还应该自动将 NVM 配置添加到你的配置文件中。如果你使用的是 zsh，那将是 <code>~/.zshrc</code>。如果你使用的是 bash，那将是 <code>~/.bash_profile...</code> 或其他一些配置文件。</p><p>如果它没有自动添加 NVM 配置，你可以自己将其添加到你的配置文件中：</p><pre><code class="language-bash">export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] &amp;&amp; printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] &amp;&amp; \. "$NVM_DIR/nvm.sh"
</code></pre><p>上面的这个命令会加载 NVM 以供使用。</p><h3 id="3-shell-">3.重新加载 shell 配置</h3><p>随着你的配置文件配置更新，现在你将重新加载配置以供你的终端使用：</p><pre><code class="language-bash">source ~/.bashrc
</code></pre><p>执行此命令后，NVM 就可以使用了。你可以通过运行以下命令确认 nvm 已正确安装：</p><pre><code class="language-bash">nvm -v
</code></pre><p>这应该会显示所安装的 NVM 的版本。</p><h2 id="-">总结</h2><p>安装了 NVM 后，你现在可以在你的 Windows、Linux 或 Mac 设备中安装、卸载和切换不同的 Node 版本。</p><p>你可以像这样安装 Node 版本。</p><pre><code class="language-bash">nvm install latest
</code></pre><p>此命令将安装最新版本的 Node：</p><pre><code class="language-bash">nvm install vX.Y.Z
</code></pre><p>这将安装 <code>X.Y.Z</code> Node 版本。</p><p>你还可以通过运行以下命令将版本设置为默认版本：</p><pre><code class="language-bash">nvm alias default vX.Y.Z
</code></pre><p>如果你想在任何时候使用特定版本，你可以在终端中运行以下命令：</p><pre><code class="language-bash">nvm use vA.B.C
</code></pre><p>NVM 使管理需要不同 Node.js 版本的不同项目变得更加容易。</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 初学者的 Node 使用指南 ]]>
                </title>
                <description>
                    <![CDATA[ Node.js是一个JavaScript运行时环境，将其能力扩展到服务器端。它是建立在Chrome的V8 JavaScript引擎上。 Node是一个事件驱动的非阻塞I/O模型。这意味着它是异步的，不会因为一个请求而阻塞（而是立即移动到下一个请求），这使得Node异常快速和高效。 所谓事件驱动，是指一旦Node启动，它就会启动所有的变量和函数，并等待事件的发生。 NPM即Node包管理工具（Node Package Manager），辅助你管理Node包。 NPX即Node包执行（Node Package Execute），它可以执行任何NPM包，甚至无需安装。 可以前往https://nodejs.org/en/download/下载NPM。 编写你的第一个Node.js项目（Hello World） 在你的项目文件中创建一个名为hello_world.js的文件。 然后在如VS Code这样的代码编辑器中打开文件。在编辑器中输入console.log(“Hello World”);。 打开终端，并且导航到文件所在的位置。 输入node hello_world.js。 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/introduction-to-nodejs/</link>
                <guid isPermaLink="false">62dfafc68d13aa0845c62e56</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ PapayaHUANG ]]>
                </dc:creator>
                <pubDate>Mon, 25 Jul 2022 04:11:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/07/1200px-Node.js_logo.svg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/introduction-to-nodejs" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Get Started with Node.js – Beginner's Guide to Node</a>
      </p><!--kg-card-begin: markdown--><p>Node.js是一个JavaScript运行时环境，将其能力扩展到服务器端。它是建立在Chrome的V8 JavaScript引擎上。</p>
<p>Node是一个事件驱动的非阻塞I/O模型。这意味着它是异步的，不会因为一个请求而阻塞（而是立即移动到下一个请求），这使得Node异常快速和高效。</p>
<p>所谓事件驱动，是指一旦Node启动，它就会启动所有的变量和函数，并等待事件的发生。</p>
<p>NPM即Node包管理工具（Node Package Manager），辅助你管理Node包。 NPX即Node包执行（Node Package Execute），它可以执行任何NPM包，甚至无需安装。</p>
<p>可以前往<a href="https://nodejs.org/en/download/">https://nodejs.org/en/download/</a>下载NPM。</p>
<h2 id="nodejshelloworld">编写你的第一个Node.js项目（Hello World）</h2>
<p>在你的项目文件中创建一个名为hello_world.js的文件。</p>
<p>然后在如VS Code这样的代码编辑器中打开文件。在编辑器中输入<code>console.log(“Hello World”);</code>。</p>
<p>打开终端，并且导航到文件所在的位置。</p>
<p>输入<code>node hello_world.js</code>。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/06/image-196.png" alt="image-196" width="600" height="400" loading="lazy"></p>
<h2 id="node">如何导入Node核心模块</h2>
<p>让我们从基础包开始，即<strong>fs（文件系统）</strong>。我们使用它来创建、读取和修改文件。</p>
<p>导入fs模块，输入命令：<code>const fs = require(“fs”);</code>。</p>
<p>使用这个模块中的函数，可以参考<a href="https://nodejs.org/docs/latest-v17.x/api/fs.html#file-system">文档</a>。</p>
<p>创建文件，可以使用<code>fs.writeFileSync(filename, content);</code>。</p>
<pre><code class="language-js">const fs = require(“fs”);
fs.writeFileSync(“file.txt”, “Hi there..”);
</code></pre>
<p><img src="https://miro.medium.com/max/446/1*KzqmGo9SE7R3XPYOS-3LXg.png" alt="1*KzqmGo9SE7R3XPYOS-3LXg" width="600" height="400" loading="lazy"></p>
<p>在同一个文件中添加内容可以：</p>
<pre><code class="language-js">fs.appendFileSync(filename, content);.
</code></pre>
<p><img src="https://miro.medium.com/max/842/1*dOqUqcuJ5a5vl_BQ_E0dSg.png" alt="1*dOqUqcuJ5a5vl_BQ_E0dSg" width="600" height="400" loading="lazy"></p>
<h2 id="npm">如何安装NPM包</h2>
<p>我们将使用一个名为<strong>superheroes（超级英雄）</strong> 的基础NPM包（包含了一个随机的超级英雄清单）来帮助你理解NPM是如何运作的。</p>
<p>我们可以在cmd中使用这条命令来安装任意NPM包：</p>
<pre><code class="language-cmd">npm install superheroes
</code></pre>
<p>现在输入<code>const sh = require(“superheroes”);</code>导入这个安装好的包。</p>
<p>使用这条命令来随机展示超级英雄的名字：</p>
<pre><code class="language-js">console.log(sh.random());.
</code></pre>
<p><img src="https://miro.medium.com/max/1400/1*WfHNl2GDgyXBEwfV6oV0GQ.png" alt="1*WfHNl2GDgyXBEwfV6oV0GQ" width="600" height="400" loading="lazy"></p>
<p>再来试一试另外一个包。让我们安装时下最流行的一个npm包——“chalk"，这个包可以改变终端字符串的样式。</p>
<p>使用以下命令安装chalk（我们将安装版本2.4.2，在这个版本中可以使用<strong>require</strong>方法）。</p>
<pre><code class="language-js">npm install chalk@2.4.2
</code></pre>
<p>现在我们可以通过命令改变文本字符串演示，使用这条命令来选择文本颜色：</p>
<pre><code class="language-js">chalk.color(text)
</code></pre>
<p><img src="https://miro.medium.com/max/1400/1*AQ5TX0vxzPn5N0lzrSBbJw.png" alt="1*AQ5TX0vxzPn5N0lzrSBbJw" width="600" height="400" loading="lazy"></p>
<p>更多信息参考<a href="https://www.npmjs.com/package/chalk">chalk包的文档</a>。</p>
<h2 id="npm">如何在程序中初始化NPM</h2>
<p>我们可以使用以下命令来初始化NPM：</p>
<pre><code class="language-js">npm init
</code></pre>
<p>然后输入回车并且回答相应的问题：</p>
<p><img src="https://miro.medium.com/max/1400/1*G_SVRqNdjuuWssQANvZgbw.png" alt="1*G_SVRqNdjuuWssQANvZgbw" width="600" height="400" loading="lazy"></p>
<p>或者你可以直接通过<code>npm init -y</code>来完成初始化（相当于所有问题的答案都是回车）。</p>
<p><img src="https://miro.medium.com/max/1400/1*CafNbhzEhvGAayNHnpb29A.png" alt="1*CafNbhzEhvGAayNHnpb29A" width="600" height="400" loading="lazy"></p>
<p>初始化完毕后会生成一个 <strong>package.json</strong> 文件：</p>
<p><img src="https://miro.medium.com/max/1400/1*hYaMdTgcLdABQ1qqjQdpRQ.png" alt="1*hYaMdTgcLdABQ1qqjQdpRQ" width="600" height="400" loading="lazy"></p>
<h3 id="packagejson">所以，package.json是什么？</h3>
<p>package.json是Nodejs项目的一部分。它包含了所有依赖项（NPM包）的记录和每一个项目的原数据。</p>
<p>如果其他人下载了这个项目，他们可以通过这个文件来安装所有运行程序需要的依赖项。</p>
<h2 id="momentjsnpm">如何使用Moment.js — 一个NPM包</h2>
<p>这是使用最多的NPM包之一，可以使用这个包来解析和验证日期。</p>
<p>使用以下命令安装包：</p>
<pre><code class="language-js">npm i moment
</code></pre>
<p>导入包：</p>
<pre><code class="language-js">const moment = require(“moment”);
</code></pre>
<p>通过创建一个Date对象来获取当前日期和时间（JavaScript方法），运行以下代码：</p>
<pre><code class="language-js">const time = new Date();
</code></pre>
<p>使用包里的<strong>moment</strong>方法来解析或者格式化日期：</p>
<pre><code class="language-js">const parsedTime = moment(time).format("h:mm:ss");
</code></pre>
<p>打印解析后的日期：</p>
<pre><code class="language-js">console.log(parsedTime);
</code></pre>
<p><img src="https://miro.medium.com/max/1400/1*V3hJ24cmTASx9k6Rv83gXg.png" alt="1*V3hJ24cmTASx9k6Rv83gXg" width="600" height="400" loading="lazy"></p>
<p>该项目的package.json中包含的所有依赖项——这个例子中的依赖项就是<strong>moment</strong>。</p>
<p><img src="https://miro.medium.com/max/1400/1*kKFpiaEOtsRbxN67do4HDw.png" alt="1*kKFpiaEOtsRbxN67do4HDw" width="600" height="400" loading="lazy"></p>
<p>在项目文件夹中也有<strong>node_modules</strong>文件夹。该文件夹包含了所有项目依赖的的依赖项，包含moment，以及moment依赖的依赖包。</p>
<p><img src="https://miro.medium.com/max/454/1*-mxxdXnGzLxG98LE2ebMDQ.png" alt="1*-mxxdXnGzLxG98LE2ebMDQ" width="600" height="400" loading="lazy"></p>
<p><strong>package-lock.json</strong>是项目文件夹中另一个文件，包含了项目名称、依赖项、依赖项版本和锁定版本等信息。</p>
<p>该文件描述了项目生成的树，使后续安装可以生成相同的树。</p>
<p><img src="https://miro.medium.com/max/1400/1*b1VMBTQ3HtQtnaHUWGY8iQ.png" alt="1*b1VMBTQ3HtQtnaHUWGY8iQ" width="600" height="400" loading="lazy"></p>
<h1 id="expressjsnodejs">如何使用Express JS——一个NodeJS框架</h1>
<p>Express是Node.js的一个web应用框架，该框架提供了全面的功能来支持web和移动应用的开发。</p>
<h3 id="express">如何安装Express</h3>
<p>使用以下命令来创建Express：</p>
<pre><code class="language-js">npm install express
</code></pre>
<p>然后这样导入Express：</p>
<pre><code class="language-js">const express = require("express");
</code></pre>
<h3 id="express">如何创建一个Express应用</h3>
<p>使用以下命令来创建Express应用：</p>
<pre><code class="language-js">const app = express()
</code></pre>
<h3 id="3000">如何在端口3000启动服务器</h3>
<pre><code class="language-js">app.listen(3000, () =&gt; { 
    console.log("Server running on port 3000");
}
</code></pre>
<p><img src="https://miro.medium.com/max/1400/1*jD3FvRLcd_j2MuZ0U6_bXw.png" alt="1*jD3FvRLcd_j2MuZ0U6_bXw" width="600" height="400" loading="lazy"></p>
<p>你可以打开<a href="http://localhost:3000/"><strong>http://localhost:3000</strong></a>登录你创建的服务器。</p>
<p><img src="https://miro.medium.com/max/844/1*IMLmUArtV_ctmiAG18TnJg.png" alt="1*IMLmUArtV_ctmiAG18TnJg" width="600" height="400" loading="lazy"></p>
<p>这里的“cannot get /”意味着还没有定义路由“/” 。</p>
<p>可以使用 <code>app.get()</code>函数定义“/”路由。</p>
<p>**app.get (route, callback function)**函数被用于处理所有GET请求。</p>
<p>这个回调函数有两个参数，<strong>req</strong>和<strong>res</strong>，分别指代的是HTTP请求和期望的响应。参数名（req，res）并不是固定的，所以你可以重命名为其他值。</p>
<pre><code class="language-js">app.get("/", (req,res) =&gt; { 
    // app.get处理GET请求
    // req - http请求, res - 期望响应
    res.send("Hello World"); // 给这个路由发送Hello World
}
</code></pre>
<h2 id="expresshelloworld">如何使用Express来创建Hello World程序</h2>
<p>在这个部分中我们将使用Express创建基本的Hello World程序：</p>
<pre><code class="language-js">const express = require("express");
const app = express();
app.get("/", (req, res) =&gt; {  
    res.send("hello world");
});
app.listen(3000, () =&gt; {  
    console.log("Server running on 3000");
});
</code></pre>
<p>输出如下：</p>
<p><img src="https://miro.medium.com/max/1060/1*uRqmENgESv8cdq-0oSaX8A.png" alt="1*uRqmENgESv8cdq-0oSaX8A" width="600" height="400" loading="lazy"></p>
<h2 id="express">如何在Express中渲染静态文件</h2>
<p>这部分介绍如何使用Express来渲染静态文件的概念。</p>
<p>首先，创建一个新的项目文件夹，并且使用 <code>npm init -y</code>来初始化npm。</p>
<p>使用 <code>npm i express</code>来安装Express，并创建一个名为app.js的文件。</p>
<p>创建一个app，并在端口3000监听：</p>
<pre><code class="language-js">const express = require("express);
const app = express();
app.listen(3000, () =&gt; {  
    console.log("Server running on 3000");
}
</code></pre>
<p>在根目录创建一个名为public的文件夹，来渲染静态web页面，如：HTML、CSS和JS。</p>
<p>由于本教程重点在后端，所有我们不会花时间在前端部分，在public文件夹中，我们仅创建HTML文件。</p>
<p><img src="https://miro.medium.com/max/1142/1*-OiGmKZaz7GKc3NdNVjZdg.png" alt="1*-OiGmKZaz7GKc3NdNVjZdg" width="600" height="400" loading="lazy"></p>
<p>我们将导入<strong>path</strong>模块，并将特定路径合并到一起：</p>
<pre><code class="language-js">const path = require(“path”);
</code></pre>
<p>并使用以下命令来渲染这些文件：</p>
<pre><code class="language-js">app.use(express.static(path.join(__dirname, “/public”)));
</code></pre>
<p><strong>__dirname →</strong>返回当前目录</p>
<pre><code class="language-js">const express = require("express");
const path = require("path");
const app = new express();
app.use(express.static(path.join(__dirname, "/public")));
app.listen(3000, () =&gt; {  
    console.log("Server running on 3000");
});
</code></pre>
<p>输出如下：</p>
<p><img src="https://miro.medium.com/max/1034/1*2U5Qi3XKOaNF0MjXSTo0tg.png" alt="1*2U5Qi3XKOaNF0MjXSTo0tg" width="600" height="400" loading="lazy"></p>
<h2 id="express">如何在Express中渲染动态文件</h2>
<p>在这个部分我们将学习如何使用一个输入对象的值来渲染动态文件。</p>
<p>有一些，如：pug、handlebars、ejs等模板用于动态页面的渲染。这些模板使得我们可以在运行时注入动态数据、if条件和循环。</p>
<p>在这里我们将讨论handlebars。</p>
<p>安装包（express和hbs）：</p>
<pre><code class="language-js">npm i hbs express
</code></pre>
<p>创建文件名为app.js的文件，并且导入包：</p>
<pre><code class="language-js">const express = require(“express”);
const hbs = require(“hbs”);
const path = require(“path”);
</code></pre>
<p>创建Express，并在端口3000监听：</p>
<pre><code class="language-js">const app = express();
app.listen(3000, (req,res) =&gt; {  
    console.log("Server running on 3000");
}
</code></pre>
<p>将视图引擎（view engine）设置为hbs，使得handlebars生效：</p>
<pre><code class="language-js">app.set(“view engine”, “hbs”);
</code></pre>
<p>视图引擎使得我们可以使用特定模板来渲染动态页面。</p>
<p>基本上，视图引擎会在根目录里寻找“视图（views）”文件夹。但为了避免报错，我们将“views”的路径包含在参数中：</p>
<pre><code class="language-js">app.set(“views”, path.join(__dirname,“/views”);
</code></pre>
<p>然后在根目录中创建 <strong>views</strong> 文件夹，并在文件夹中创建index.hbs文件（.hbs是handlebars的扩展名）并插入以下HTML代码：</p>
<h3 id="indexhbs">index.hbs</h3>
<pre><code class="language-html">&lt;html&gt;  
    &lt;head&gt; 
        &lt;title&gt;Dynamic Rendering&lt;/title&gt; 
    &lt;/head&gt;
    &lt;body&gt;  
      &lt;h1&gt;Dynamic Rendering&lt;/h1&gt;   
      &lt;p&gt;{{author}}&lt;/p&gt; &lt;!--由服务器接受到的动态数据--&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p><strong><code>{{author}}</code></strong> — 是插入动态数据的语法。</p>
<p>我们再创建一个app.get函数来处理路由"/"上的GET请求，并且发送动态数据<strong>author</strong>。</p>
<pre><code class="language-js">app.get("/", (req, res) =&gt; { 
    res.render("index", {    
        author: "Arash Arora", 
    });
});
</code></pre>
<p><strong><code>res.render</code></strong> 是一个渲染视图的函数，在这里我们传入了两个参数。第一个是去掉扩展名的文件名，第二个是本地变量对象，比方说<strong>author</strong>。</p>
<h3 id="appjs">app.js文件</h3>
<pre><code class="language-js">const express = require("express");
const hbs = require("hbs");
const path = require("path");
const app = express();
app.set("view engine", "hbs");
app.set("views", path.join(__dirname, "/views"));
app.get("/", (req, res) =&gt; {  
    res.render("index", {    
        author: "Arash Arora", 
    });
});
app.listen(3000, (req, res) =&gt; { 
    console.log("Server listening on 3000");
});
</code></pre>
<h3 id="">文件夹结构</h3>
<p><img src="https://miro.medium.com/max/502/1*7xz9Fj17mTS5pZhxzf2dvw.png" alt="1*7xz9Fj17mTS5pZhxzf2dvw" width="600" height="400" loading="lazy"></p>
<p>输出如下：</p>
<p><img src="https://miro.medium.com/max/824/1*JQt1mgjLTU-LJJ0XS7UH3A.png" alt="1*JQt1mgjLTU-LJJ0XS7UH3A" width="600" height="400" loading="lazy"></p>
<h1 id="handlebars">如何使用Handlebars创建高级模板</h1>
<p>在这一部分我们将学习可复用组件。在前面的章节我们给每一个页面的header和footer创建了相同的组件。</p>
<p>这里的重复性工作就可以通过高级模板来简化。也就是说我们创建一个组件，并在需要的地方反复使用。</p>
<h3 id="handlebarspartials">Handlebars引入部分（Partials）的概念</h3>
<p>Partials是可被其他模板调用的handlebar文件。Partials是一个被广泛应用的模板类概念，所以不仅限于Handlebars。</p>
<p>想要构建可以复用的模板，可以将它们单独放在同一个文件夹内（Partial），然后在不同的模板中使用。可以将Partial理解为模块化模板的一种简单技术。</p>
<p>可以通过以下步骤创建partial：</p>
<ul>
<li>初始化npm → <code>npm init -y</code></li>
<li>安装必要的包、Express以及hbs → <code>npm i express hbs</code></li>
<li>创建文件夹模板</li>
<li>在文件夹模板内部创建另外两个文件夹：<strong>partials和views</strong></li>
<li>创建文件<strong>app.js</strong></li>
</ul>
<p><img src="https://miro.medium.com/max/472/1*98jLDll1IWq-vd8H0ieNCg.png" alt="1*98jLDll1IWq-vd8H0ieNCg" width="600" height="400" loading="lazy"></p>
<p>文件结构类似</p>
<p>让我们创建两个partial文件：header.hbs和footer.hbs。同时也创建两个视图：index.hbs和about.hbs。</p>
<p><img src="https://miro.medium.com/max/422/1*E32yq-EHCLFfUFzbgIbJJg.png" alt="1*E32yq-EHCLFfUFzbgIbJJg" width="600" height="400" loading="lazy"></p>
<h3 id="indexhbs">index.hbs</h3>
<pre><code class="language-html">&lt;html lang="en"&gt;  
    &lt;head&gt;   
        &lt;title&gt;Advanced Templating&lt;/title&gt;  
    &lt;/head&gt;  
    &lt;body&gt;    
        {{&gt;header}} &lt;!--包含header组件--&gt;
        &lt;p&gt;I'm a savior&lt;/p&gt;    
        {{&gt;footer}} &lt;!-- 包含footer组件--&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h3 id="abouthbs">about.hbs</h3>
<pre><code class="language-html">&lt;html lang="en"&gt;  
    &lt;head&gt;    
        &lt;title&gt;Advanced Templating -- About&lt;/title&gt; 
    &lt;/head&gt;
    &lt;body&gt;   
        {{&gt;header}}   
        &lt;p&gt;Handlebars&lt;/p&gt;    
        {{&gt;footer}} 
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h3 id="headerhbs">header.hbs</h3>
<pre><code class="language-html">&lt;header&gt;  
    &lt;h1&gt;Advanced Templating&lt;/h1&gt; 
    &lt;h3&gt;{{title}}&lt;/h3&gt;&lt;!--服务器传来的动态数据--&gt;
    &lt;a href="/"&gt;Home&lt;/a&gt; 
    &lt;a href="/about"&gt;About&lt;/a&gt;
&lt;/header&gt;
</code></pre>
<h3 id="footerhbs">footer.hbs</h3>
<pre><code class="language-html">&lt;footer&gt;  
    &lt;p&gt;Created by {{name}}&lt;/p&gt; &lt;!--name -&gt; 动态数据 --&gt;
&lt;/footer&gt;
</code></pre>
<h3 id="appjs">app.js</h3>
<pre><code class="language-javascript">const express = require("express");
const hbs = require("hbs");
const path = require("path");
const app = express();
app.set("view engine", "hbs");
app.set("views", path.join(__dirname, "/templates/views"));
hbs.registerPartials(path.join(__dirname, "/templates/partials"));
app.get("/", (req, res) =&gt; {  
    res.render("index", {    
        title: "Home",    
        name: "Arash Arora",  
    });
});
app.get("/about", (req, res) =&gt; {  
    res.render("about", {    
        title: "About",    
        name: "Arash Arora",  
    });
});
app.listen(3000, () =&gt; {  
    console.log("Listening on port 3000");
});
</code></pre>
<p>这里基本和在Express中渲染动态数据章节类似，除了使用partial的时候我们需要 <strong>注册partials</strong>。</p>
<h3 id="partials">如何注册partials</h3>
<pre><code class="language-js">hbs.registerPartials(path_to_partials)
</code></pre>
<p>由于我们在模板文件夹中创建了partials目录，这里是 partials 的路径：</p>
<pre><code class="language-js">hbs.registerPartials(path.join(__dirname, "/templates/partials"));
</code></pre>
<h1 id="">总结</h1>
<p>在这篇文章中，我们从理论到实践讲解了Node.js。虽然我们不能从一篇简短的文章中习得Node.js所有内容，但是我已经尽我所能地在这篇文章中涵盖了重要的知识点，来辅助你开启Node.js之旅。</p>
<p>简言之，我们讨论了什么是Node.js，即一个非阻塞、事件驱动的JavaScript运行时环境，它是异步的、可以使用单线程来执行操作。我们还讨论了使用最广泛的短小、灵活的Node.js的web应用框架——Express。</p>
<p>我们还讲解了Node.js的NPM、 NPX以及静态和动态渲染。</p>
<p>总而言之，Node.js是一项令人惊叹的技术，而且由于其庞大的社区，其可能性是无穷无尽的。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何在 Node.js 和 npm 的 DotEnv 文件中使用 Node 环境变量 ]]>
                </title>
                <description>
                    <![CDATA[ 原文：How to Use Node Environment Variables with a DotEnv File for Node.js and npm [https://www.freecodecamp.org/news/how-to-use-node-environment-variables-with-a-dotenv-file-for-node-js-and-npm/] ，作者：Veronica Stork [https://www.freecodecamp.org/news/author/veronica/] 环境变量是在程序之外设置的变量，通常通过云服务提供商或操作系统设置。 在 Node 中，环境变量是一种很好的方式，可以安全、方便地配置那些不经常改变的东西，如 URL、认证密钥和密码。 如何创建环境变量 Node 开箱即支持环境变量，并且可以通过 env 对象（它是 process 全局对象的一个属性）访问。 要看到这一点，你可以在 Node REPL 中通过直接向 process.env 对象添加一个变量来创建你自己的环境变量。 例如，要创建一个环境变 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-use-node-environment-variables-with-a-dotenv-file-for-node-js-and-npm/</link>
                <guid isPermaLink="false">62568eb599ec7406219e6851</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Wed, 13 Apr 2022 10:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/04/node-env-variables.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/how-to-use-node-environment-variables-with-a-dotenv-file-for-node-js-and-npm/">How to Use Node Environment Variables with a DotEnv File for Node.js and npm</a>，作者：<a href="https://www.freecodecamp.org/news/author/veronica/">Veronica Stork</a></p><p>环境变量是在程序之外设置的变量，通常通过云服务提供商或操作系统设置。</p><p>在 Node 中，环境变量是一种很好的方式，可以安全、方便地配置那些不经常改变的东西，如 URL、认证密钥和密码。</p><h2 id="-">如何创建环境变量</h2><p>Node 开箱即支持环境变量，并且可以通过 <code>env</code> 对象（它是 <code>process</code> 全局对象的一个属性）访问。</p><p>要看到这一点，你可以在 Node REPL 中通过直接向 <code>process.env</code> 对象添加一个变量来创建你自己的环境变量。</p><p>例如，要创建一个环境变量来存储我行李箱上的密码，我可以这样分配变量：<code>process.env.LUGGAGE_COMBO=“12345”</code>。</p><p>（根据惯例，环境变量一般用大写字母书写）。</p><p>虽然这是一个很好的实验，但你不会在一个应用程序中这样使用 Node REPL。要在你的 Node 应用程序中创建环境变量，你可能想使用像 DotEnv 这样的包。</p><h2 id="-dotenv">如何使用 DotEnv</h2><p><a href="https://www.npmjs.com/package/dotenv">DotEnv</a> 是一个轻量级的 npm 包，它可以从 <code>.env</code> 文件中自动加载环境变量到 <code>process.env</code> 对象。</p><p>要使用 DotEnv，首先使用命令安装它：<code>npm i dotenv</code>。然后在你的应用程序中，像这样要求和配置这个包：<code>require('dotenv').config()</code>。</p><p>请注意，一些包，如 Create React App 已经包括 DotEnv，而云服务提供商可能有不同的设置环境变量的方法。因此，在你遵循本文的任何建议之前，请确保检查你正在使用的任何包或供应商的文档。</p><h2 id="-env-">如何创建一个 .env 文件</h2><p>在你安装并配置了 DotEnv 之后，在文件结构的顶层创建一个名为 <code>.env</code> 的文件，这是你创建所有环境变量的地方，以 <code>NAME=value</code> 格式书写。例如，你可以像这样设置一个端口变量为 3000：<code>PORT=3000</code>。</p><p>你可以在 <code>.env</code> 文件中声明多个变量。例如，你可以这样设置与数据库有关的环境变量：</p><pre><code>DB_HOST=localhost
DB_USER=admin
DB_PASSWORD=password</code></pre><p>没有必要用引号来包裹字符串。DotEnv 会自动为你做这个。</p><p>一旦你创建了这个文件，请记住，你不应该把它推送到 GitHub，因为它可能包含敏感数据，如认证密钥和密码。将该文件添加到 .gitignore 中，以避免不小心将其推送到公共仓库。</p><h2 id="--1">如何访问环境变量</h2><p>访问你的变量是非常容易的！它们被附在 <code>process.env</code> 对象上，所以你可以使用 <code>process.env.KEY</code> 模式访问它们。</p><p>如果你需要改变任何环境变量的值，你只需要修改 <code>.env</code> 文件。</p><h2 id="--2"><strong>总结</strong></h2><p>环境变量将使你的代码更容易维护和更安全。用 Dotenv 来设置它们很容易，并且可以在 Node 中直接使用它们。</p><p>现在你知道它是怎么做的了，你可以为你的 Node 应用程序创建环境变量了！</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ NodeJS 中的事件循环--理解同步和异步编程 ]]>
                </title>
                <description>
                    <![CDATA[ 原文：Event Loops in NodeJS – Beginner's Guide to Synchronous and Asynchronous Code [https://www.freecodecamp.org/news/nodejs-eventloop-tutorial/]，作者：Tejan Singh [https://www.freecodecamp.org/news/author/tejan/] NodeJS 是一个异步事件驱动的 JavaScript 运行环境，旨在建立可扩展的网络应用。 这里的异步指的是 JavaScript 中所有那些在后台处理的、而且不会阻塞任何其他请求的功能。 在这篇文章中，你将学习并理解 NodeJS 是如何工作的，如何处理发送到服务器的所有功能或请求，无论是 同步（synchronously）  还是  异步（asynchronously）。 什么是事件循环（Event Loop） 你可能已经猜对了--Node 在 NodeJS 环境中使用事件循环（Event loop）  处理请求。但首先，让我们了解一些基本术语，这将有助于我们 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/nodejs-eventloop-tutorial/</link>
                <guid isPermaLink="false">62183bd779a578061070ccee</guid>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Fri, 25 Feb 2022 02:35:52 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/02/oliver-hale-2cYueJxEDz8-unsplash.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/nodejs-eventloop-tutorial/">Event Loops in NodeJS – Beginner's Guide to Synchronous and Asynchronous Code</a>，作者：<a href="https://www.freecodecamp.org/news/author/tejan/">Tejan Singh</a></p><!--kg-card-begin: markdown--><p>NodeJS 是一个异步事件驱动的 JavaScript 运行环境，旨在建立可扩展的网络应用。</p>
<p>这里的异步指的是 JavaScript 中所有那些在后台处理的、而且不会阻塞任何其他请求的功能。</p>
<p>在这篇文章中，你将学习并理解 NodeJS 是如何工作的，如何处理发送到服务器的所有功能或请求，无论是 <em>同步（synchronously）</em> 还是 <em>异步（asynchronously）</em>。</p>
<h2 id="eventloop">什么是事件循环（Event Loop）</h2>
<p>你可能已经猜对了--Node 在 NodeJS 环境中使用<strong>事件循环（Event loop）</strong> 处理请求。但首先，让我们了解一些基本术语，这将有助于我们理解整个机制。</p>
<p>事件循环是一个<strong>事件监听器（event-listener）</strong>，它在 NodeJS 环境中发挥作用，并随时准备监听、处理和输出一个 <em>事件（event）</em>。</p>
<p>一个事件可以是任何东西，从鼠标点击到按键或超时。</p>
<h2 id="synchronousasynchronous">什么是同步（Synchronous）和异步（Asynchronous）编程</h2>
<p><strong>同步编程（Synchronous programming）</strong> 意味着代码按其定义的顺序运行。在一个同步程序中，当一个函数被调用并返回了一些值后，才会执行下一行。</p>
<p>让我们通过这个例子来理解:</p>
<pre><code class="language-js">const listItems = function(items) {
  items.forEach(function(item) {
    console.log(item)
  })
}

const items = ["Buy milk", "Buy coffee"]

listItems(items)
</code></pre>
<pre><code class="language-js">The output will look like this:

"Buy milk"
"Buy coffee"

</code></pre>
<p>在这个例子中，当<code>listItems(items)</code>函数被调用时，它将循环浏览数组中的项目。<code>console.log(item)</code>函数首先对数组的第一个项目被调用，并打印出<code>"Buy milk"</code>，然后<code>console.log(item)</code>再次被执行，这次它通过数组的第二项，并打印出<code>"Buy coffee"</code>。</p>
<p>所以你可以说这个函数是按照它被定义的<strong>顺序（sequence）</strong> 执行的。</p>
<p>另一方面，<strong>异步编程（Asynchronous programming）</strong> 是指不按顺序执行的代码。这些函数不是按照它们在程序中定义的顺序执行，而是只有在满足某些条件时才执行。</p>
<p>例如，<code>setTimeOut()</code>在延迟一定数量的毫秒后执行一项任务。</p>
<pre><code class="language-js">setTimeOut(function(){
    return( console.log("Hello World!") )
}, 3000)
</code></pre>
<p>这些函数并不逐行运行，而只是在需要运行的时候才运行，与函数的声明无关。在这种情况下，当所有的同步函数都被执行后，该函数会在3秒后自动运行。</p>
<p><em>注意：异步函数只有在所有同步函数被执行后才会运行和执行。在此之前，它们将在后台被处理。</em></p>
<p>如果你想了解更多关于 NodeJS 和异步编程的信息，你可以参考这篇<a href="https://www.freecodecamp.org/news/node-js-what-when-where-why-how-ab8424886e2/">文章</a></p>
<p>但是，NodeJS 如何在后台处理异步函数并先运行所有同步函数？所有这些机制都可以用 NodeJS 的事件循环轻松解释。</p>
<h2 id="eventloop">事件循环（Event Loop）是如何工作的</h2>
<p>现在让我们看看 NodeJS 事件循环如何使用 Nodejs 事件循环图来执行一个简单的同步程序。然后我们将检查 Node 是如何逐行执行程序的。</p>
<p>在接下来的内容里，你会逐步理解这张图：<br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/1.PNG" alt="1" width="600" height="400" loading="lazy"></p>
<p>在左上角，你有一个将要被执行的 Node 文件。在左下方，你有一个程序的输出终端。然后，你有 <em>调用堆栈（Call stack）、Node APIs 和回调队列（Callback queue）。</em> 所有这些共同构成了NodeJS 环境。</p>
<p>对于同步编程，你只需要关注调用栈（call stack）。这是 NodeJS 环境中唯一的一部分，将在这种情况下工作。</p>
<p>回调栈（callback stack）是一个数据结构（data structure），你用它来跟踪将在程序内部运行的所有函数的执行情况。这个数据结构只有一个开放端（open），用于添加或删除顶部项目（top items）。</p>
<p>当程序开始执行时，它首先被包裹在一个匿名（anonymous ）的<code>main()</code>函数中。这是由 NodeJS 自动定义的。所以<code>main()</code>首先被推送到回调栈中。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/2.PNG" alt="2" width="600" height="400" loading="lazy"></p>
<p>接下来，变量<code>a</code>和<code>b</code>被创建，它们的总和被存储在一个变量<code>sum</code>中。所有这些值都存储在内存中。</p>
<p>现在，<code>console.log()</code>是一个被调用并推到回调栈内（callback stack）的函数。它被执行，你可以在终端屏幕上看到输出。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/3.PNG" alt="3" width="600" height="400" loading="lazy"></p>
<p>在这个函数被执行后，它被从回调栈中删除。然后<code>main()</code>也被删除，因为程序中没有任何东西可以被调用。这就是一个同步程序的执行方式。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/4.PNG" alt="4" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/5.PNG" alt="5" width="600" height="400" loading="lazy"></p>
<p>现在，让我们看看异步函数或程序如何在 NodeJS 内部执行。我们需要回调栈（callback stack）、Node API 和回调队列（callback queue）一起处理一个异步函数。</p>
<p>让我们先看一下这个例子:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/1-1.PNG" alt="1-1" width="600" height="400" loading="lazy"></p>
<p>当程序开始执行时，首先<code>main()</code>函数被添加到回调栈（callback stack）中。然后<code>console.log("Start")</code>被调用并添加到回调栈（callback stack）中。在处理之后，输出在终端上是可见的，然后它被从回调栈中删除。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/2-1.PNG" alt="2-1" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/3-1.PNG" alt="3-1" width="600" height="400" loading="lazy"></p>
<p>接下来是<code>setTimeOut(...Zero...)</code>函数，它被添加到回调栈（callback stack）中。</p>
<p>由于这是一个异步函数，它<strong>不会</strong>在回调栈（callback stack）中得到处理。然后，它被从回调栈（callback stack）中添加到 Node APIs 中，在那里，一个事件被注册，一个回调函数被设置为在后台得到处理。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/4-1.PNG" alt="4-1" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/5-1.PNG" alt="5-1" width="600" height="400" loading="lazy"></p>
<p>接下来是<code>setTimeOut(...Two...)</code>，它也从回调栈（callback stack）中被添加到 Node API，因为它是一个异步函数。然后另一个回调函数被设置为在后台超时 2 秒后被处理。直到这一点，其他函数可以被执行。</p>
<p>这就是<strong>非阻塞</strong>行为，所有的同步函数首先被处理和执行，异步函数在后台处理，同时等待轮到自己被执行。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/6.PNG" alt="6" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/7.PNG" alt="7" width="600" height="400" loading="lazy"></p>
<p>接下来，<code>console.log("End")</code>函数在回调栈（callback stack）的最后被调用，并在此得到处理。你可以看到终端上的输出。现在，所有的同步函数都被处理了，<code>main()</code>被从回调栈（callback stack）中移除。</p>
<p>在后台，所有的异步函数被处理，它们的回调被存储在回调队列（callback queue）中。首先被处理的函数将被首先加入回调栈（callback stack）的执行队列中。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/8.PNG" alt="8" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/9.PNG" alt="9" width="600" height="400" loading="lazy"><br>
<img src="https://www.freecodecamp.org/news/content/images/2021/08/10.PNG" alt="10" width="600" height="400" loading="lazy"></p>
<p><em>注意：异步函数不能在回调栈（callback stack）内运行，直到它被清空。这意味着在<code>main()</code>被从调用栈（callback stack）中移除后，所有的异步函数才能开始执行。</em></p>
<p>现在，它们一个接一个地被推到回调栈（callback stack）中，使用<strong>事件循环（event loop）</strong>，最后被执行。每个回调函数都会打印值，每次都会调用<code>console.log()</code>函数。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/11.PNG" alt="11" width="600" height="400" loading="lazy"></p>
<p>最后，这些在被执行后也被移除，现在回调栈（callback stack）是空的。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/12.PNG" alt="12" width="600" height="400" loading="lazy"></p>
<p>这就是 NodeJS 如何在环境中执行同步和异步函数，以及事件循环如何管理调用异步函数。</p>
<h2 id="">总结</h2>
<p>在这篇文章中，你了解了 NodeJS 的内部工作，看到了异步程序是如何被执行的。</p>
<p>现在你应该明白为什么两秒的延时函数不会阻止程序的其他部分执行。你也知道为什么零秒延时函数在 “End” 打印后最后打印出数值。</p>
<p>我希望你喜欢阅读这篇文章，并学到一些新东西。如果你觉得这篇文章有用，请和朋友们分享它^_^</p>
<!--kg-card-end: markdown--><p></p><p></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何使用 Node 后端创建 React 应用程序：完整指南 ]]>
                </title>
                <description>
                    <![CDATA[ 原文：How to Create a React App with a Node Backend: The Complete Guide [https://www.freecodecamp.org/news/how-to-create-a-react-app-with-a-node-backend-the-complete-guide/] ，作者：Reed Barger [https://www.freecodecamp.org/news/author/reed/] React 前端与 Node 后端相配合，对于你想创建的任何应用程序来说都是一个坚如磐石的组合。 本指南旨在帮助你用 React 尽可能容易地创建一个全栈项目。让我们看看如何使用 React 和 Node 从头开始创建一个完整的项目，并将其部署到网络上。 > 想创建和部署你自己的 React 和 Node 应用程序吗？ 查看我的课程系列 [http://bit.ly/12-react-projects] ，它告诉你如何创建你自己的全栈 React 项目，比如这个项目。 你需要的工具  * 确保 Node 和 NP ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-create-a-react-app-with-a-node-backend-the-complete-guide/</link>
                <guid isPermaLink="false">620f81c823041306357608c1</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ luojiyin ]]>
                </dc:creator>
                <pubDate>Fri, 18 Feb 2022 10:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/02/how-to-build-a-react-app-with-a-node-backend-alt.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>原文：<a href="https://www.freecodecamp.org/news/how-to-create-a-react-app-with-a-node-backend-the-complete-guide/">How to Create a React App with a Node Backend: The Complete Guide</a>，作者：<a href="https://www.freecodecamp.org/news/author/reed/">Reed Barger</a></p><!--kg-card-begin: markdown--><p>React 前端与 Node 后端相配合，对于你想创建的任何应用程序来说都是一个坚如磐石的组合。</p>
<p>本指南旨在帮助你用 React 尽可能容易地创建一个全栈项目。让我们看看如何使用 React 和 Node 从头开始创建一个完整的项目，并将其部署到网络上。</p>
<blockquote>
<p>想创建和部署你自己的 React 和 Node 应用程序吗？ <a href="http://bit.ly/12-react-projects">查看我的课程系列</a>，它告诉你如何创建你自己的全栈 React 项目，比如这个项目。</p>
</blockquote>
<h2 id="">你需要的工具</h2>
<ul>
<li>确保 Node 和 NPM 已经安装在你的电脑上。你可以在这个网站下载这两样东西 <a href="https://nodejs.org">nodejs.org</a>（NPM 包含在你安装的 Node 中，不需要另外安装)。</li>
<li>使用你选择的代码编辑器。我正在使用并且个人推荐使用 VSCode。你可以在这个网站下载 VSCode：<a href="https://code.visualstudio.com">code.visualstudio.com</a>。</li>
<li>确保你的电脑上安装了 Git。这对于用 Heroku 部署我们的应用程序是必要的。你可以在这个网站上下载：<a href="https://git-scm.com">git-scm.com</a>。</li>
<li>一个在 <a href="https://heroku.com">heroku.com</a> 的账号。我们将使用 Heroku 将应用程序完全免费地发布到网上。</li>
</ul>
<h2 id="nodeexpress">第一步：创建你的 Node（Express）后端</h2>
<p>首先为你的项目创建一个文件夹，命名为<code>react-node-app</code>（示例名称）。</p>
<p>然后，将该文件夹拖入你的代码编辑器。</p>
<p>为了创建我们的 Node 项目，在你的终端运行以下命令：</p>
<pre><code class="language-bash">npm init -y
</code></pre>
<p>这将创建一个 package.json 文件，使我们能够跟踪所有的应用程序脚本，并管理我们的 Node 应用程序需要的任何依赖。</p>
<p>我们的服务器代码将放在一个同名的文件夹中：<code>server</code>。让我们来创建这个文件夹。</p>
<p>在这个文件夹中，我们将放置一个文件，从这个文件中运行服务。<code>index.js</code>。</p>
<p>我们将使用 Express 创建一个简单的 Web 服务器，如果环境变量<code>PORT</code>没有给定值，则运行在 3001 端口（Heroku 将在我们部署应用程序时设置这个值）。</p>
<pre><code class="language-js">// server/index.js

const express = require("express");

const PORT = process.env.PORT || 3001;

const app = express();

app.listen(PORT, () =&gt; {
  console.log(`Server listening on ${PORT}`);
});
</code></pre>
<p>然后在我们的终端安装 Express 作为一个依赖项来使用它。</p>
<pre><code class="language-bash">npm i express
</code></pre>
<p>之后，我们将在 package.json 中创建一个脚本，当我们用<code>npm start</code>运行它时，将启动我们的 Web 服务。</p>
<pre><code class="language-json">// server/package.json

...
"scripts": {
  "start": "node server/index.js"
},
...
</code></pre>
<p>最后，我们可以通过在终端运行 npm start 来运行应用程序，我们应该看到它正在 3001 端口上运行。</p>
<pre><code class="language-bash">npm start

&gt; node server/index.js

Server listening on 3001
</code></pre>
<p><img src="https://reedbarger.nyc3.digitaloceanspaces.com/how-to-create-a-react-app-with-a-node-backend/clip-1.gif" alt="代码片段  1" width="600" height="400" loading="lazy"></p>
<h2 id="api">第二步：创建一个 API</h2>
<p>我们想把我们的 Node 和 Express 服务器作为一个 API，这样它就可以给 React 应用提供数据，改变这些数据，或者做一些其他只有服务才能做的操作。</p>
<p>在这个例子中，我们将简单地给 React 应用发送一个 JSON 对象中的 "Hello from server!"消息。</p>
<p>下面的代码为路由<code>/api</code>创建了一个 endpoint。</p>
<p>如果我们的 React 应用向该路由发出一个 GET 请求，我们就会用 JSON 数据进行响应（使用<code>res</code>，代表响应）。</p>
<pre><code class="language-js">// server/index.js
...

app.get("/api", (req, res) =&gt; {
  res.json({ message: "Hello from server!" });
});

app.listen(PORT, () =&gt; {
  console.log(`Server listening on ${PORT}`);
});
</code></pre>
<p><em>注意：请确保将其放在<code>app.listen</code>函数之前。</em></p>
<p>由于我们已经对 Node 代码进行了修改，我们需要重新启动服务器。</p>
<p>要做到这一点，在终端按 Command/Ctrl+C 结束你的启动脚本，然后再次运行<code>npm start</code>重新启动它。</p>
<p>为了测试这一点，我们可以简单地在浏览器中访问<code>http://localhost:3001/api</code>，看看我们获得的信息。</p>
<p><img src="https://reedbarger.nyc3.digitaloceanspaces.com/how-to-create-a-react-app-with-a-node-backend/clip-2.gif" alt="代码片段 2" width="600" height="400" loading="lazy"></p>
<h2 id="react">第三步：创建 React 前端</h2>
<p>在创建了后端之后，让我们转到前端。</p>
<p>打开另一个终端标签，使用 create-react-app 创建一个新的 React 项目，名称为<code>client</code>。</p>
<pre><code class="language-bash">npx create-react-app client
</code></pre>
<p>之后，我们将拥有一个安装了所有依赖项的 React 应用。</p>
<p>我们要做的唯一改变是在 package.json 文件中添加一个名为<code>proxy</code>的属性（<code>client</code>文件夹下的 package.json 文件）。</p>
<p>这将允许我们向 Node 服务器发出请求，而不必在每次向它发出网络请求时提供它所运行的原点（<a href="http://localhost:3001">http://localhost:3001</a>）。</p>
<pre><code class="language-bash">// client/package.json

...
"proxy": "http://localhost:3001",
...
</code></pre>
<p>然后我们可以通过运行它的启动脚本来启动 React 应用，这和我们的 Node 服务器一样。首先确保<code>cd</code>进入新创建的<code>client</code>文件夹。</p>
<p>之后，将在<code>localhost:3000</code>上启动（其实启动两个 Node 的进程，一个是 React 开发使用，一个是 Express 开发使用）。</p>
<pre><code class="language-bash">cd client
npm start

Compiled successfully!

You can now view client in the browser.

Local:            http://localhost:3000
</code></pre>
<p><img src="https://reedbarger.nyc3.digitaloceanspaces.com/how-to-create-a-react-app-with-a-node-backend/clip-3.gif" alt="代码片段 3" width="600" height="400" loading="lazy"></p>
<h2 id="reactnodehttp">第四步：从 React 向 Node 发出 HTTP 请求</h2>
<p>现在我们有了一个工作的 React 应用，我们想用它来与我们的 API 进行交互。</p>
<p>让我们看看如何从我们之前创建的<code>/api</code>endpoint 获取数据。</p>
<p>要做到这一点，我们可以前往<code>src</code>文件夹中的<code>App.js</code>组件，使用<code>useEffect</code>进行 HTTP 请求。</p>
<p>我们将使用 Fetch API 向后端发出一个简单的 GET 请求，然后将我们的数据以 JSON 格式返回。</p>
<p>一旦我们得到了返回的数据，我们将得到消息属性（抓取从服务器发送的问候语），然后把它放在一个叫做<code>data</code>的状态变量中。</p>
<p>这将使我们能够在页面中显示该消息，如果我们有的话。我们在 JSX 中使用一个条件，如果数据还没有，就显示文本 <code>Loading...</code>。</p>
<pre><code class="language-js">// client/src/App.js

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
  const [data, setData] = React.useState(null);

  React.useEffect(() =&gt; {
    fetch("/api")
      .then((res) =&gt; res.json())
      .then((data) =&gt; setData(data.message));
  }, []);

  return (
    &lt;div className="App"&gt;
      &lt;header className="App-header"&gt;
        &lt;img src={logo} className="App-logo" alt="logo" /&gt;
        &lt;p&gt;{!data ? "Loading..." : data}&lt;/p&gt;
      &lt;/header&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre>
<p><img src="https://reedbarger.nyc3.digitaloceanspaces.com/how-to-create-a-react-app-with-a-node-backend/clip-4.gif" alt="代码片段 5" width="600" height="400" loading="lazy"></p>
<h2 id="heroku">用 Heroku 将你的应用程序部署到网上</h2>
<p>最后，让我们把应用程序部署到网络上。</p>
<p>首先，在我们的<code>client</code>文件夹中，确保删除由 create-react-app 自动初始化的 Git repo（rm -rf .git, <code>.git</code> 是隐藏文件夹，不能直接看到）。</p>
<p>这对部署我们的应用程序至关重要，因为我们要在项目的根文件夹（<code>react-node-app</code>）中创建 Git repo，而不是在<code>client</code>中。</p>
<pre><code class="language-bash">cd client
rm -rf .git
</code></pre>
<p>当我们部署时，Node 后端和 React 前端都将在同一个域名（即 mycoolapp.herokuapp.com）提供服务。</p>
<p>我们看到请求是如何被 Node API 处理的，所以我们需要写一些代码，当我们的 React 应用被用户请求时（例如，当我们进入应用的主页时）显示 React 应用。</p>
<p>我们可以在<code>server/index.js</code>中加入以下代码来完成这个工作。</p>
<pre><code class="language-js">// server/index.js
const path = require('path');
const express = require('express');

...

// 让 Node 为我们创建的 React 应用提供文件
app.use(express.static(path.resolve(__dirname, '../client/build')));

// 处理对/api 的 GET 请求
app.get("/api", (req, res) =&gt; {
  res.json({ message: "Hello from server!" });
});

// 所有之前未被处理的 GET 请求将返回我们的 React app
app.get('*', (req, res) =&gt; {
  res.sendFile(path.resolve(__dirname, '../client/build', 'index.html'));
});
</code></pre>
<p>这段代码将首先允许 Node 使用<code>express.static</code>函数来访问我们创建的 React 项目的静态文件。</p>
<p>如果有一个 GET 请求进来，而这个请求没有被我们的<code>/api</code>路由处理后，我们的服务器将用 React 应用来响应。</p>
<p><strong>这段代码允许我们的 React 和 Node 应用一起部署在同一个域名。</strong></p>
<p>然后我们可以告诉 Node App 如何做，在我们的服务器 package.json 文件中添加一个<code>build</code>脚本，为生产构建我们的 React 应用。</p>
<pre><code class="language-json">// server/package.json

...
"scripts": {
    "start": "node server/index.js",
    "build": "cd client &amp;&amp; npm install &amp;&amp; npm run build"
  },
...
</code></pre>
<p>我还建议提供一个名为<code>engines</code>的字段，在这里你要指定你用来构建项目的 Node 版本。这将被用于部署。</p>
<p>你可以通过运行<code>node -v</code>来获得你的 Node 版本，你可以把结果放在<code>engines</code>中（例如14.15.4）。</p>
<pre><code class="language-json">// server/package.json

"engines": {
  "node": "your-node-version"
}
</code></pre>
<p>在这之后，我们准备使用 Heroku 进行部署，所以请确保你在 <a href="https://heroku.com">Heroku.com</a> 有一个账户。</p>
<p>当你登录并查看你的仪表板（dashboard），你将选择新建（New）&gt;创建新的应用程序（Create New App），并提供一个唯一的应用程序名称。</p>
<pre><code class="language-bash">sudo npm i -g heroku
</code></pre>
<p>当安装完毕，你将通过 CLI 使用<code>heroku login</code>命令登录到 Heroku。</p>
<pre><code class="language-bash">heroku login

Press any key to login to Heroku
</code></pre>
<p>登录后，只需在 "Deploy "选项卡中为我们创建的应用程序遵循部署说明。</p>
<p>以下四个命令将为我们的项目初始化一个新的 Git repo，将我们的文件添加到其中，提交它们，并为 Heroku 添加一个 Git 远程。</p>
<pre><code>git init
heroku git:remote -a insert-your-app-name-here
git add .
git commit -am "Deploy app to Heroku"
</code></pre>
<p>然后，最后一步是通过推送我们刚刚添加的 Heroku Git 远程地址（heroku git:remote -a insert-your-app-name-here），来发布我们的应用程序。</p>
<pre><code class="language-bash">git push heroku master
</code></pre>
<p>恭喜！我们的全栈式 React 和 Node 应用已经上线。🎉</p>
<p><img src="https://reedbarger.nyc3.digitaloceanspaces.com/how-to-create-a-react-app-with-a-node-backend/clip-5.gif" alt="代码片段 5" width="600" height="400" loading="lazy"></p>
<p>当你想对你的应用程序进行修改时（并进行部署），你只需要用 Git 来添加你的文件（git add），提交它们（git commit），然后推送到我们的 Heroku 远程（git push）。</p>
<pre><code class="language-bash">git add .
git commit -m "my commit message"
git push heroku master
</code></pre>
<h3 id="reactyoutubeinstagramtwitter">想用 React 创建像 YouTube、Instagram 和 Twitter 这样的真实世界的应用程序吗？以上就是方法。</h3>
<p>在每个月的月底，我将发布一个独家课程，准确地告诉你如何复现从头到尾用 React 创建一个完整的应用程序。</p>
<p>想在下一个课程出现时得到通知吗？<strong><a href="http://bit.ly/12-react-projects">在这里加入等候名单</a></strong>。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 用 React 和 Node/Express 开发全栈应用入门 ]]>
                </title>
                <description>
                    <![CDATA[ 在这篇文章里，我将引导你创建简单的 React 应用和简单的 Node / Express API，并将两者连接起来。 这篇教程中提到的各种技术，我不会详细介绍如何使用它们。但是我会留下链接，你可以了解更多信息， 你可以在我为教程制作的仓库 [https://github.com/Joao-Henrique/React_Express_App_Medium_Tutorial]中找到所有代码。 教程的目的是为你提供有关如何设置和连接前端 client 和后端 API 的实用指南。 在开始之前，请确保你的电脑正在运行 Node.js。 创建主项目目录 在你的终端中，导航到你要保存项目的目录。现在为你的项目创建一个新目录，并导航到其中： mkdir my_awesome_project cd my_awesome_project 创建一个 React [https://reactjs.org/] App 这个过程真的很简单。 我将使用 Facebook 的 create-react-app [https://github.com/facebook/create-react-ap ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together/</link>
                <guid isPermaLink="false">6038bd05c354c605689ea910</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Node ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Express ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Chengjun.L ]]>
                </dc:creator>
                <pubDate>Fri, 26 Feb 2021 10:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2021/02/1614334666774.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>在这篇文章里，我将引导你创建简单的 React 应用和简单的 Node / Express API，并将两者连接起来。</p><p>这篇教程中提到的各种技术，我不会详细介绍如何使用它们。但是我会留下链接，你可以了解更多信息，</p><p>你可以在我为教程制作的<a href="https://github.com/Joao-Henrique/React_Express_App_Medium_Tutorial">仓库</a>中找到所有代码。</p><p>教程的目的是为你提供有关如何设置和连接<strong>前端 client </strong>和<strong>后端 API</strong> 的实用指南。<br>在开始之前，请确保你的电脑正在运行 Node.js。</p><h4 id="-"><strong><strong>创建主项目目录</strong></strong></h4><p>在你的终端中，导航到你要保存项目的目录。现在为你的项目创建一个新目录，并导航到其中：</p><pre><code class="language-bash">mkdir my_awesome_project
cd my_awesome_project</code></pre><h4 id="-react-app"><strong><strong>创建一个</strong> </strong><a href="https://reactjs.org/" rel="noopener"><strong><strong>React</strong></strong></a><strong><strong> App</strong></strong></h4><p>这个过程真的很简单。</p><p>我将使用 Facebook 的 <a href="https://github.com/facebook/create-react-app" rel="noopener">create-react-app</a> 来……你猜对了，轻松创建一个名为<strong> client</strong> 的 react 应用：</p><pre><code class="language-bash">npx create-react-app client
cd client
npm start</code></pre><p>让我们看看我做了什么：</p><ul><li>使用 npm 的 npx 来创建 react 应用并将其命名为 client。</li><li>cd（change directory 更改目录）进入 client 目录。</li><li>启动应用程序。</li></ul><p>在浏览器中，导航到 <a href="http://localhost:3000/" rel="noopener">http://localhost:3000/</a>。</p><p>如果一切正常，你将看到 react 欢迎页面。恭喜你！这意味着你现在已经在本地计算机上运行了一个基本的 react 应用程序。容易吧？</p><p>要停止运行你的 react 应用，只需在终端中按 <strong><strong><code>Ctrl + c</code></strong></strong>。</p><h4 id="-express-app"><strong><strong>创建一个 </strong></strong><a href="https://expressjs.com/" rel="noopener"><strong><strong>Express</strong></strong></a><strong><strong> App</strong></strong></h4><p>好的，这将与前面的示例一样简单。不要忘记导航到你的项目顶部文件夹。</p><p>我将使用 <a href="https://expressjs.com/en/starter/generator.html">Express 应用生成器</a>快速创建应用程序框架，并将其命名为 <strong>api</strong>：</p><pre><code class="language-bash">npx express-generator api
cd api
npm install
npm start</code></pre><p>让我们看看我做了什么：</p><ul><li>使用 npm 的 npx 来全局安装 express-generator。</li><li>使用 express-generator 创建一个 Express 应用并将其命名为 api。</li><li>cd 进入 API 目录。</li><li>安装所有依赖项。</li><li>启动应用程序。</li></ul><p>在浏览器中，导航到 <a href="http://localhost:3000/" rel="noopener">http://localhost:3000/</a>。</p><p>如果一切正常，你将看到 <a href="https://expressjs.com/" rel="noopener"><strong><strong>Express</strong></strong></a><strong> </strong>欢迎页面。恭喜你！ 这意味着你现在已经在本地计算机上运行了基本的 Express 应用程序。容易吧？</p><p>要停止运行你的 react 应用，只需在终端中按 <code><strong><strong>Ctrl + c</strong></strong></code>。</p><h4 id="-express-api-route">在 Express API 中配置新 <a href="https://expressjs.com/en/guide/routing.html" rel="noopener">route</a></h4><p>我们开始吧。打开你喜欢的代码编辑器（我正在使用 VS Code），导航到你的项目文件夹。</p><p>如果你<strong>将 react app 命名为 client</strong>，<strong>将 express app 命名为 api</strong>，则会找到两个主文件夹：<strong>client</strong> 和 <strong>api</strong>。</p><p>1、在 <strong>API</strong> 目录中，转到 <strong>bin/www</strong>，然后将第 15 行的端口号从 3000 更改为 9000。稍后我们将同时运行两个应用程序，因此这样做可以避免出现问题。结果应该是这样的：</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/m7e3LsFolz6988HgYjgdDuP3DPY1Ix3F8u5u" class="kg-image" alt="m7e3LsFolz6988HgYjgdDuP3DPY1Ix3F8u5u" width="600" height="400" loading="lazy"><figcaption>my_awesome_project/api/bin/www</figcaption></figure><p>2、在 <strong><strong>api/routes</strong> </strong>上，创建一个 <strong><strong>testAPI.js</strong></strong> 文件，粘贴以下代码：</p><pre><code class="language-js">var express = require(“express”);
var router = express.Router();

router.get(“/”, function(req, res, next) {
    res.send(“API is working properly”);
});

module.exports = router;</code></pre><p>3、在 <strong><strong>api/app.js</strong></strong> 文件中，在第 24 行插入新的 route：</p><pre><code class="language-js">app.use("/testAPI", testAPIRouter);</code></pre><p>4、你正在“告诉” express 使用该 rout。但是，你仍然要求它。让我们在第 9 行进行操作：</p><pre><code class="language-js">var testAPIRouter = require("./routes/testAPI");</code></pre><p>唯一的变化是在第 9 行和第 25 行。它应该是这样的：</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/hG-IcH7kyM8nj1VO43Mgo1nZGI0hsVhvAfFi" class="kg-image" alt="hG-IcH7kyM8nj1VO43Mgo1nZGI0hsVhvAfFi" width="600" height="400" loading="lazy"><figcaption>my_awesome_project/api/app.js</figcaption></figure><p>5、恭喜你！你已经创建了一个新的 <a href="https://expressjs.com/en/guide/routing.html" rel="noopener">route</a>。</p><p>如果你启动 API 应用程序（在终端中，导航到 API 目录并运行 “<strong>npm start</strong>”），然后在浏览器中访问 <a href="http://localhost:9000/testAPI" rel="noopener">http://localhost:9000/testAPI</a>，你将看到以下消息：<strong><strong><em><em>API is working properly</em></em></strong><em>（API 正常运行中）</em></strong>。</p><p><strong>将 React Client 连接到 Express API</strong></p><ul><li>在你的代码编辑器上，找到 <strong><strong>client</strong> </strong>目录，打开位于 <strong><strong>my_awesome_project/client/app.js</strong> </strong>中的 <strong><strong>app.js</strong> </strong>文件。</li><li>在这里，我将使用 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch" rel="noopener"><strong><strong>Fetch API</strong></strong></a><strong> </strong>从 <strong><strong>API</strong> </strong>检索数据。只需在 Class 声明之后和 render 方法之前粘贴以下代码：</li></ul><pre><code class="language-jsx">constructor(props) {
    super(props);
    this.state = { apiResponse: "" };
}

callAPI() {
    fetch("http://localhost:9000/testAPI")
        .then(res =&gt; res.text())
        .then(res =&gt; this.setState({ apiResponse: res }));
}

componentWillMount() {
    this.callAPI();
}</code></pre><ul><li>在 render 方法内部，你将找到一个 &lt;; p&gt; 标记。让我们对其进行更改，以使其渲染 apiResponse：</li></ul><pre><code class="language-jsx">&lt;p className="App-intro"&gt;;{this.state.apiResponse}&lt;/p&gt;</code></pre><p>最后，这个文件应该是这样的：</p><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/dswag4EEuA3vcVmZ9cs7rxJwOayb-SW6HiI8" class="kg-image" alt="dswag4EEuA3vcVmZ9cs7rxJwOayb-SW6HiI8" width="600" height="400" loading="lazy"></figure><p>我知道内容有点多！你可以复制粘贴代码，但是你必须了解自己在做什么。让我们看看我在这里做了什么：</p><ul><li>在第 6 至 9 行中，我们插入了一个构造函数，用于初始化默认状态。</li><li>在第 11 至 16 行，我们插入了方法 <em><em><strong><strong>callAPI()</strong></strong></em></em>，该方法将从 API 中获取数据并将响应存储在 <em><em><strong><strong>this.state.apiResponse</strong></strong></em><strong> </strong></em>上。</li><li>在第 18 至 20 行，我们插入了一个 react 生命周期方法 <em><em><strong><strong>componentDidMount()</strong></strong></em></em>，该方法将在组件安装后执行 <em><em><strong><strong>callAPI()</strong></strong></em><strong> </strong></em>方法。</li><li>最后，在第 29 行，我使用&lt;; p&gt;标记在 client 页面上显示了一个段落，其中包含我们从 API 中检索到的文本。</li></ul><h4 id="-cors-"><strong><strong>什么</strong>？<strong><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener">CORS</a></strong>？</strong></h4><p>我们快完成了！ 但是，如果我们同时启动应用程序（client 和 API），并导航至<a href="http://localhost:3000/">http：// localhost：3000 /</a>，页面仍然不会显示预期结果。如果你打开 chrome 开发工具，就会找到原因。在控制台中，你将看到此错误：</p><blockquote>Failed to load <a href="http://localhost:9000/testAPI" rel="noopener">http://localhost:9000/testAPI</a>: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘<a href="http://localhost:3000'/" rel="noopener">http://localhost:3000'</a> is therefore not allowed access. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.</blockquote><p>这很容易解决。我们只需将 CORS 添加到我们的 API 中，即可允许跨域请求。你可以在<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">此处</a>查看有关 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS" rel="noopener">CORS</a> 的更多信息。</p><ul><li>在你的终端中，导航到 API 目录，并安装 <strong><strong>CORS</strong> </strong>软件包：</li></ul><pre><code class="language-bash">npm install --save cors</code></pre><ul><li>在你的代码编辑器中，访问 API 目录，打开 <strong><strong>my_awesome_project/api/app.js</strong></strong> 文件。</li><li>在第 6 行，require <strong><strong>CORS</strong></strong>：</li></ul><pre><code class="language-js">var cors = require("cors");</code></pre><ul><li>在第 8 行，“告诉” express 使用 <strong><strong>CORS</strong></strong>：</li></ul><pre><code class="language-js">app.use(cors());</code></pre><p>现在，API <strong><strong>app.js</strong></strong> 文件应该是这样：</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-media-1.freecodecamp.org/images/NOuexIhM99Tn-eKYJ0wJjRJUCbIwww8Lyr61" class="kg-image" alt="NOuexIhM99Tn-eKYJ0wJjRJUCbIwww8Lyr61" width="600" height="400" loading="lazy"><figcaption>my_awesome_project/api/app.js</figcaption></figure><h4 id="--1"><strong><strong>很棒</strong>，我们完成了！</strong></h4><p>现在，使用 <strong><strong>npm start</strong> </strong>命令在两个不同的终端中启动你的应用程序（client 和 API）。</p><p>如果你在浏览器中导航到 <a href="http://localhost:3000/" rel="noopener">http://localhost:3000/</a>，则应该看到类似的内容：</p><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/Fwq4HE7hMM2Z5Um3U9xuwCVzlZSAeSvr9U1c" class="kg-image" alt="Fwq4HE7hMM2Z5Um3U9xuwCVzlZSAeSvr9U1c" width="600" height="400" loading="lazy"></figure><p>当然，这个项目没有实现很多，但它是全栈应用的开始。你可以在<a href="https://github.com/Joao-Henrique/React_Express_App_Medium_Tutorial">这个仓库</a>中找到我为教程创建的所有代码。</p><p>接下来，我将研究一些补充教程，例如如何将其连接到 MongoDB 数据库，甚至如何在 Docker 容器中运行它们。</p><p>正如我的一个好朋友说的：</p><blockquote>Be Strong and Code On!!!</blockquote><p>每天都要变得更好哦;)</p><p>原文：<a href="https://www.freecodecamp.org/news/create-a-react-frontend-a-node-express-backend-and-connect-them-together-c5798926047c/">How to create a React frontend and a Node/Express backend and connect them</a>，作者：João Henrique</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
