教程的问题
2022 年 3 月 8 日,作者 Burke Holland, @burkeholland
编写出色的教程并非易事。我应该知道 - 我写过很多教程,但并非每个都大获成功。
事实证明,编写出色的教程不在于你写了什么,而在于开发者是否可以在不必阅读每个字的情况下获得成功。在本文中,我们将探讨开发容器如何减少用户可能遇到的错误,以及 Laravel PHP 项目如何在他们自己的教程中优雅地实现这一点并取得巨大成效。
没人阅读
我们自己关于如何在 Visual Studio Code 中使用 Dev Containers 的教程长期以来完成率都很低 - 大约 4 - 6%。
为了弄清楚人们在哪里放弃,我们进行了用户研究,并观察人们尝试完成我们的教程。这...很痛苦。
很快就清楚了人们为什么无法完成教程:没人阅读它。人们直接跳过说明,直接进入操作步骤。不可避免地,他们会卡住,因为他们犯了一个错误,如果他们阅读了说明就不会犯这个错误。
宾夕法尼亚州立大学教授 John M. Carroll 在他的开创性著作《纽伦堡漏斗 - 为实用计算机技能设计极简指令》中谈到了这一点。他写道:“[学习者]太忙于学习,以至于无法充分利用说明。这就是意义建构的悖论。”
我对此深有体会,您可能也是如此。当我在学习教程时,我的眼睛会扫描代码块,因为我试图通过实践来学习。我真的太忙于学习,以至于没空阅读说明。
人们不会阅读你的教程。或者至少不如你希望的那么多。你能做的最好的事情是尽可能消除读者在学习过程中可能出错的地方。一种方法是使用预配置的容器环境完全删除任何环境设置步骤。
容器化的开发环境
任何教程的很大一部分通常都用于列出长长的先决条件和环境设置。我清楚地记得尝试学习 Ruby on Rails,并将大部分时间花在尝试在 Windows 上正确安装 Ruby 上 - 想知道“gem”到底是什么,以及为什么它们都莫名其妙地丢失了。
容器化开发环境背后的理念是你在 Docker 容器内部进行开发。这使得拥有一个完全可移植、完全配置的开发环境成为可能,你可以随意启动或关闭它。然后,你可以将该环境以一组配置文件的形式提供给他人。
但是如何在容器内部进行开发呢?容器又不像拥有 UI,可以直接启动 VS Code。
Dev Containers 扩展正是为此而生。它既包含将 Docker 容器配置为开发环境的机制,也允许你从 VS Code 连接到该环境。它通过在容器内安装一个小型的服务器组件来实现这一点,你的本地 VS Code 与该组件通信。然后,你就可以像在本地一样进行开发,但 VS Code 连接的是容器环境,而不是你的本地环境。
为了创建容器化的开发环境,你通常需要了解一些关于 Docker 的知识。很多人了解,但也有很多人不了解(你看不到我,但我举手了),因此该扩展尝试尽可能地抽象化容器设置过程。我设置了一个新的 Python 容器。向导引导你选择基础镜像和 Python 版本。然后,它让你有机会通过选择器列表向镜像添加其他软件。在本例中,我添加了 Azure CLI、Dotnet CLI 和 PowerShell…
此过程会向此项目添加一个 .devcontainer
文件夹,其中包含必要的 Dockerfile
。它还会添加一个 devcontainer.json
文件,该文件是定义 dev container 方面的标准,例如应安装哪些扩展、容器构建后应运行哪些设置命令等。由于你可以完全控制环境及其设置,因此你可以自动化几乎所有内容 - 包括依赖项安装、库版本等。
这样,就可能真正地向某人提供一个完整的、即用型的环境,而无需额外的设置步骤或因 Ruby gem 而引发存在危机。
一些人已经在使用基于 dev container 的方法,以便让他们的用户能够快速启动并运行原本非常复杂的环境。Laravel PHP 框架就是一个很好的例子。
Laravel 解决方案
Laravel 是一个用于 PHP 的开源 MVC 框架。它非常全面,因为它还包括对象关系映射器 (ORM)、直接数据库访问、打包系统等。Laravel 功能强大。为了体验它,当你开始使用时,你真的至少需要一个数据库。通常,这将要求用户不仅安装 PHP,还要安装数据库 - 通常是 MySQL。当用户只是想试用你的框架时,这是一个很高的要求。
Laravel 通过容器化开发环境和一个名为 Sail 的工具来解决这个问题。要从头开始使用 Laravel、MySQL 服务器和 Redis 缓存,你只需运行一个命令...
curl -s "https://laravel.build/example-app?with=mysql,redis" | bash
这会创建一个包含 docker-compose
文件的新项目。此文件设置三个容器 - 一个应用程序容器、一个 MySQL 容器和一个 Redis 容器。你无需了解任何关于容器或这三项服务的知识。Sail 为你抽象化了所有这些。然后你执行 Sail 命令来启动环境...
./vendor/bin/sail up
示例应用程序直接运行。无需安装 PHP。无需 Laravel。无需依赖项解析步骤。只需立即获得成功。
我指定我们的项目具有 MySQL 服务器和 Redis 缓存,因此当项目启动时,我们实际上得到了三个容器。我们可以使用 VS Code 的 Docker 扩展来看到这一点。
这些容器通过网络连接在一起,以便我们可以从应用程序容器调用 MySQL 或 Redis 缓存容器。
如果你将交互式终端连接到 sail-8.1/app container
,你将在 /var/www/html
文件夹中看到你的项目。Docker 将项目从你的机器“挂载”到容器中,因此你在开发时所做的任何更改都会在刷新时反映在应用程序中。
添加 Dev Containers
还添加了对 Dev Containers 扩展的支持。要向此项目添加正确的 dev container 配置,你可以搭建相同的项目并添加 &devcontainer
标志。
curl -s "https://laravel.build/example-app?with=mysql,redis&devcontainer" | bash
请注意,如果你想向现有的 Sail/Laravel 项目添加 devcontainer,你可以通过运行
php artisan sail:install --devcontainer
来实现。
这将创建相同的项目配置,但会包含一个 .devcontainer
文件夹。VS Code 将自动检测到该文件夹,并提示你在容器中重新打开项目,从而跳过必需的 sail up
步骤。
VS Code 连接到容器,因此你在容器环境而不是本地环境中进行开发。你会知道这一点,因为 VS Code 左下角的远程指示器会告诉你...
在容器中开发而不是在容器外开发有一些明显的优势。
开发上下文镜像应用程序上下文
连接到容器后,你正在开发的上下文与应用程序运行的上下文相同。因此,你的终端变成了容器的终端...
Dev Containers 扩展还为你提供了更全面的视图,让你了解正在发生的事情,例如哪些端口被转发 - 以防你忘记你的应用程序在哪里运行。
Laravel 应用程序自动启动,应用程序日志被管道传输到容器日志。由于你可能想查看应用程序中正在发生的事情,因此 Dev Containers 扩展在 VS Code 中提供了一个新视图,你可以在其中查看所有正在运行的容器,以及连接以流式传输容器日志。
自动化开发环境设置
最佳的开发者体验将包括编辑器的自定义设置。这包括编辑器本身的设置,以及需要添加到开箱即用体验中的任何扩展或其他支持。
对于 VS Code 和 Laravel,扩展在 devcontainer.json
中被建议,但被注释掉,以便它们不会自动安装。这允许用户从一组已识别的扩展中进行选择,而不是必须去寻找配置编辑器的正确方法。
...
"extensions": [
// "mikestead.dotenv",
// "amiralizadeh9480.laravel-extra-intellisense",
// "ryannaddy.laravel-artisan",
// "onecentlin.laravel5-snippets",
// "onecentlin.laravel-blade"
],
少读多做
人们不阅读。这应该没问题。Laravel 的教程不一定比其他教程更短,但重要的是,如果你跳到代码并直接运行命令,它就可以工作。Dev container 使之成为可能。现在,如果我们可以弄清楚如何为我们自己的“使用 Docker 容器作为 Visual Studio Code 的开发环境”教程制作一个 dev container 就好了……
编码愉快!
Burke Holland (@burkeholland)