部署我们的应用
在本系列的最后一篇文章中,我们将利用上一篇文章中构建的示例工具链,并在此基础上进行扩展,以便部署我们的示例应用程序。我们将代码推送到 GitHub,使用 GitHub Pages 进行部署,甚至向你展示如何在过程中添加一个简单的测试。
预备知识 | 熟悉核心 HTML、CSS 和 JavaScript 语言。 |
---|---|
目标 | 完成我们完整的工具链案例研究,重点关注应用程序的部署。 |
开发后
在项目生命周期的这一部分,可能需要解决大量问题。因此,创建能够以尽可能少的人工干预方式处理这些问题的工具链非常重要。
以下是此特定项目需要考虑的一些事项
- 生成生产版本:确保文件被最小化、分块、应用了摇树优化,并且版本“缓存失效”。
- 运行测试:这些测试可以从“此代码格式是否正确?”到“此功能是否按我预期工作?”,并确保失败的测试会阻止部署。
- 实际将更新后的代码部署到实时 URL:或者可能是一个暂存 URL,以便首先进行审核。
注意: 缓存失效是我们在模块中以前没有遇到过的新术语。这是一种破坏浏览器自身缓存机制的策略,它会强制浏览器下载一份新的代码副本。Vite(以及许多其他工具)将生成每个新构建都独一无二的文件名。这个独一无二的文件名会“破坏”浏览器的缓存,从而确保每次部署的代码更新时,浏览器都会下载最新的代码。
上述任务还可以分解为更多任务;请注意,大多数 Web 开发团队至少在开发后阶段的某些部分有自己的术语和流程。
对于这个项目,我们将使用 GitHub Pages 的免费静态托管服务来托管我们的项目。它不仅可以在互联网上提供我们的网站,还为我们提供了一个网站 URL。这很棒——许多 MDN 示例网站都托管在 GitHub Pages 上。
部署到托管通常处于项目生命周期的末端,但随着 GitHub Pages 等服务降低了部署成本(无论是财务方面还是实际部署所需的时间),在开发过程中进行部署以共享进行中的工作或为其他目的提供预发布版本成为可能。
GitHub 提供了一个流畅的工作流程,将新代码转化为实时网站
- 你将代码推送到 GitHub。
- 你定义一个 GitHub Action,当主分支有新推送时会触发它,该 Action 会构建代码并将其放置在特定位置。
- 然后 GitHub Pages 会在特定 URL 提供代码。
正是这些类型的互联服务,我们鼓励你在决定自己的构建工具链时寻找。我们可以提交代码并推送到 GitHub,更新后的代码将自动触发整个构建例程。如果一切顺利,我们就会自动部署实时更改。我们唯一需要执行的操作就是最初的“推送”。
但是,我们确实必须设置这些步骤,现在我们将对此进行研究。
构建过程
同样,因为我们使用 Vite 进行开发,所以构建选项非常容易添加。正如我们之前看到的,我们已经有一个自定义脚本 npm run build
,它将让 Vite 为生产环境构建所有内容,而不仅仅是为开发和测试目的运行它。这包括对代码进行 最小化 和 摇树优化,以及文件名的缓存失效。
在项目中始终定义 `build` 脚本是一个很好的最佳实践,这样我们就可以依赖 `npm run build` 始终完成完整的构建步骤,而无需记住每个项目的特定构建命令参数。
新创建的生产代码放置在一个名为 `dist` 的新目录中,其中包含运行网站所需的所有文件,随时可以上传到服务器。
然而,手动执行此步骤并非我们的最终目标——我们希望构建能够自动进行,并且 `dist` 目录的结果能够实时部署到我们的网站上。
向 GitHub 提交更改
本节将帮助你将代码存储在 Git 仓库中,但这远非 Git 教程。网上有许多优秀的教程和书籍可供查阅,我们的 Git 和 GitHub 页面是一个很好的起点。
我们之前已经将工作目录初始化为 Git 工作目录。一个快速验证方法是运行以下命令
git status
你应该会看到一份状态报告,其中包含哪些文件正在被跟踪、哪些文件已暂存等等——所有这些术语都是 Git 语法的一部分。如果你收到错误 `fatal: not a git repository`,则工作目录不是 Git 工作目录,你需要使用 `git init` 初始化 Git。
现在我们有三项任务
- 将我们所做的任何更改添加到暂存区(Git 将从中提交文件的特殊位置)。
- 将更改提交到仓库。
- 将更改推送到 GitHub。
-
要添加更改,请运行以下命令
bashgit add .
注意末尾的句号,它表示“此目录中的所有内容”。`git add .` 命令有点像一把大锤——它会一次性添加你所有本地的工作更改。如果你想更精细地控制要添加的内容,那么使用 `git add -p` 进行交互式处理,或者使用 `git add path/to/file` 添加单个文件。
-
现在所有代码都已暂存,我们可以提交了;运行以下命令
bashgit commit -m 'committing initial code'
注意: 尽管你可以随意在提交消息中编写任何内容,但网上有一些关于良好提交消息的有用提示。保持它们简短、简洁和描述性,这样它们就能清晰地描述更改做了什么。
-
最后,代码需要推送到你在 GitHub 上托管的仓库。我们现在就来做。
在 GitHub 上,访问 https://github.com/new 并创建你自己的仓库来托管此代码。
-
为你的仓库取一个简短、易记的名称,不要包含空格(使用连字符分隔单词),并添加描述,然后点击页面底部的“创建仓库”。
你现在应该拥有一个指向你的新 GitHub 仓库的“远程”URL。
-
在将此远程位置推送到 GitHub 之前,我们需要将其添加到本地 Git 仓库,否则它将无法找到该位置。你需要运行一个具有以下结构的命令(暂时使用提供的 HTTPS 选项——尤其是如果你是 GitHub 新手——而不是 SSH 选项)
bashgit remote add origin https://github.com/your-name/repo-name.git
因此,如果你的远程 URL 是 `https://github.com/remy/super-website.git`,如上图所示,你的命令将是
bashgit remote add origin https://github.com/remy/super-website.git
将 URL 更改为你自己的仓库,并立即运行它。
注意: 选择仓库名称后,请确保 `vite.config.js` 中的 `base` 选项反映此名称,如 上一章 所述。否则,JavaScript 和 CSS 资产将无法正确链接。
-
现在我们准备将代码推送到 GitHub;现在运行以下命令
bashgit push origin main
此时,系统会提示你输入用户名和密码,然后 Git 才会允许推送。这是因为我们使用的是 HTTPS 选项而不是 SSH 选项,如前面截图中所示。为此,你需要你的 GitHub 用户名,然后——如果你没有启用双重身份验证 (2FA)——你的 GitHub 密码。我们始终鼓励你尽可能使用 2FA,但请记住,如果你使用 2FA,你还需要使用“个人访问令牌”。GitHub 帮助页面提供了一个出色而简单的教程,涵盖了如何获取一个。
注意: 如果你有兴趣使用 SSH 选项,从而避免每次推送到 GitHub 时都需要输入用户名和密码,本教程将引导你完成操作。
这个最终命令指示 Git 将代码推送到我们称为 `origin` 的“远程”位置(那是托管在 github.com 上的仓库——我们可以随意命名),使用 `main` 分支。我们还没有遇到过分支,但“main”分支是我们工作的默认位置,也是 Git 开始的位置。当我们定义触发构建网站的 action 时,我们还会让它监视“main”分支上的更改。
注意: 直到 2020 年 10 月,GitHub 上的默认分支是 `master`,出于各种社会原因,它被切换为 `main`。你应该意识到,这个旧的默认分支可能会出现在你遇到的各种项目中,但我们建议你自己的项目使用 `main`。
因此,我们的项目已在 Git 中提交并推送到 GitHub 仓库,工具链的下一步是定义一个构建操作,以便我们的项目可以实时部署到 Web 上!
使用 GitHub Actions 进行部署
GitHub Actions,就像 ESLint 配置一样,是另一个可以深入研究的“兔子洞”。第一次尝试时很难做到正确,但对于“构建静态网站并将其部署到 GitHub Pages”等常见任务,有许多示例可以复制和粘贴。你可以按照 使用自定义 GitHub Actions 工作流程发布 中的说明进行操作。你可以查看 我们的 GitHub Action 文件 以获取一个可用的示例。(文件名无关紧要。)
将此文件提交到主分支后,您应该会在提交标题旁边看到一个小绿色的勾
如果你看到一个黄色圆点,表示 action 正在运行;如果你看到一个红色叉号,表示 action 失败。点击图标,你可以查看你自己的构建 action(在我们的例子中名为“Deploy build”)的状态和日志。
再等几分钟后,你可以访问你的 GitHub Pages URL,查看你的网站在网络上的实时情况。链接类似于 `https://
现在,我们的工具链中还有最后一个环节:一个测试,以确保我们的代码正常工作。
测试
测试本身是一个庞大的主题,即使在前端开发领域也是如此。我将向你展示如何向项目添加初始测试,以及如何使用该测试来阻止或允许项目部署发生。
在处理测试时,有许多方法可以解决问题
- 端到端测试,包括访问者点击某个东西并发生其他事情。
- 集成测试,它基本上是说“当一段代码连接到另一段代码时,它是否仍然工作?”
- 单元测试,测试小型和特定的功能片段,看它们是否做它们应该做的事情。
- 还有更多类型。此外,请参阅我们的 跨浏览器测试模块,以获取大量有用的测试信息。
还要记住,测试不仅限于 JavaScript;测试可以针对渲染的 DOM、用户交互、CSS,甚至页面外观运行。
然而,对于这个项目,我们将创建一个小测试,检查 GitHub API 数据格式是否正确。如果不正确,测试将失败并阻止项目上线。做其他任何事情都超出了本模块的范围——测试是一个巨大的主题,确实需要单独的模块。我们希望本节至少能让你意识到测试的必要性,并播下启发你进一步学习的种子。
测试本身并不重要。重要的是如何处理失败或成功。因为我们已经在编写自定义构建操作,所以我们可以在构建之前添加一个运行测试的步骤。如果测试失败,构建将失败,并且部署将不会发生。
好消息是:因为我们使用的是 Vite,Vite 已经提供了一个很好的集成测试工具:Vitest。
我们开始吧。
-
安装 Vitest
bashnpm install --save-dev vitest
-
在你的 package.json 中,找到 `scripts` 成员,并更新它,使其包含以下测试和构建命令
json{ "scripts": { // … "test": "vitest" } }
注意: 这就是将 Vite 与 Vitest 结合使用的好处:如果您使用其他测试框架,则需要添加另一个配置来描述测试文件如何转换,但 Vitest 将自动使用 Vite 配置。
-
现在,我们当然需要将测试添加到我们的代码库中。通常,如果您正在测试一个文件的功能,比如 `App.jsx`,您会在它旁边添加一个名为 `App.test.jsx` 的文件。在这种情况下,我们只是在测试数据,所以让我们创建另一个目录来存放我们的测试。您可以打开上一章中下载的示例存储库,然后复制 `tests` 文件夹。
-
现在要手动运行测试,我们可以从命令行运行
bashnpm run test
你应该会看到这样的输出
> client-toolchain-example@1.0.0 test > vitest DEV v1.6.0 /Users/joshcena/Desktop/work/Tech/projects/mdn/client-toolchain-example ✓ tests/api.test.js (1) 896ms ✓ GitHub API returns the right response 896ms Test Files 1 passed (1) Tests 1 passed (1) Start at 23:12:25 Duration 1.03s (transform 15ms, setup 0ms, collect 5ms, tests 896ms, environment 0ms, prepare 38ms) PASS Waiting for file changes... press h to show help, press q to quit
这意味着测试通过了。与 Vite 类似,它会监视更改并在你保存文件时重新运行测试。我们可以通过按 q 退出。
-
我们仍然需要将测试连接到我们的构建操作,以便在测试失败时阻止构建。打开 `_github/workflows/github-pages.yml` 文件(或你为构建操作指定的任何文件名),并在运行 `npm run build` 的步骤之前添加以下步骤
yaml- name: Install deps run: npm ci # Add this - name: Run tests run: npm run test - name: Build run: npm run build
这将在构建步骤之前运行测试。如果测试失败,构建将失败,并且部署将不会发生。
-
现在让我们使用与之前类似的命令将新代码上传到 GitHub
bashgit add . git commit -m 'adding test' git push origin main
在某些情况下,你可能希望测试构建代码的结果(因为这并非我们编写的原始代码),因此测试可能需要在构建命令之后运行。在开发自己的项目时,你需要考虑所有这些单独的方面。
最后,推送后大约一分钟,GitHub Pages 将部署项目更新。但前提是它通过了引入的测试。
总结
我们的案例研究和本模块到此结束!我们希望你觉得它有用。尽管你离成为客户端工具向导还有很长的路要走,但我们希望本模块已经为你迈出了理解客户端工具的第一步,并让你有信心学习更多新事物并尝试它们。
让我们总结一下工具链的所有部分
- 代码质量和维护由 ESLint 和 Prettier 执行。这些工具通过 `npm install --dev eslint prettier eslint-plugin-react ...` 作为 `devDependencies` 添加到项目中(因为这个特定项目使用 React,所以需要 ESLint 插件)。
- 代码质量工具会读取两个配置文件:`eslint.config.js` 和 `.prettierrc`。
- 在开发过程中,我们继续使用 npm 添加依赖项。Vite 开发服务器在后台运行,用于监视更改并自动构建我们的源代码。
- 部署通过将更改推送到 GitHub(到“main”分支)来处理,这会触发使用 GitHub Actions 构建和部署项目。在我们的示例中,此 URL 是 https://mdn.github.io/client-toolchain-example/;你将拥有自己唯一的 URL。
- 我们还有一个简单的测试,如果 GitHub API 源没有提供正确的数据格式,该测试将阻止网站的构建和部署。
对于那些寻求挑战的人,请思考是否可以优化此工具链的某些部分。一些需要问自己的问题