我如何用 Windows 开发 —— 2021 我的开发环境

由于搭载 macOS 的设备越来越昂贵且槽点颇多,加上微软近些年开始发力开发者体验,我的工作环境已经从 MacBook 切换到了运行 Windows 系统的非苹果机器。这是多方面因素决定的:平时玩的游戏需要在 Windows 上运行,桌面环境也是 Windows 的比较舒适耐用。

使用 Windows 进行开发工作虽说并不像在 macOS 上那样可以使用诸多 POSIX 标准的工具,但鉴于硬件性能的提升和虚拟化技术的成熟,使用虚拟机或者 WSL2 也未必是不可接受的方案。此外,随着 Visual Studio Code 的 Remote 功能越发完善,在 Windows 的窗口环境下享受和 Linux 一样的开发体验也并非不可能。

当然,使用 Windows 开发完全是个人选择;本文并不打算讨论 Windows 对比其它操作系统的优劣,只是在此简单介绍我如何在 Windows 桌面上进行我的开发工作,希望对因为种种原因选择使用 Windows 工作的读者能有所启发。

需求

在讨论开发环境之前,我们首先得讨论开发的需求是什么。我个人写的东西还挺杂的,大部分时候使用 Visual Studio Code 写 TypeScript, JavaScript 和 PHP。除此之外,我有时候会使用 Android Studio 写 Java/Kotlin,或者用 Goland 写 Go,又或者使用 Visual Studio 2019 写 C#。此外,我还需要运行 DataGrip 之类的数据库管理软件、kubectl 之类的集群管理软件,还需要使用 ssh 登录数台远程主机。我的个人项目几乎都使用 docker 进行部署,因此 docker 也必不可少。

总体来说,我需要:

  • Visual Studio Code
  • Visual Studio
  • JetBrains IDE,包括:
    • Android Studio
    • Goland
    • DataGrip
  • 终端、zsh
  • docker

了解了自己的需求之后,就能根据自己的需求来考察选项。

OS

如标题所述,我的宿主机基本上是 Windows 操作系统,一般是最新的 Release 或者 Beta 版本,比如在写作文章的时候是 Windows 11 (Pro) Insider Beta。这目前是为了使用 wslg,在 Windows 11 正式发布之后我多半会切换到稳定版上。

鉴于平日打交道的服务器多半是 Debian 或者 Ubuntu 这类 Linux 发行版,本地开发环境上有一个 Linux 的机器很重要,我称之为 Linux dev box。在这个 Linux dev box 内的操作系统上,我选择使用 ArchWSL 提供的 ArchLinux 镜像作为日常的 dev box 使用,这主要是考虑到 ArchLinux 的软件包比较新,而且 AUR 上有很多方便的包可以选择使用。在非生产环境下,使用 ArchLinux 的体验还是不错的。

虚拟化

Linux dev box – WSL2

在 Windows 宿主机上运行 Linux box 是很简单的事情,而且你有诸多选择:以 VirtualBox 为代表的虚拟机方案;WSL1;WSL2。我的选项是 WSL2,你可能觉得 WSL2 和虚拟机也没什么区别,事实上几乎如此,只是省去了不少自己对虚拟机做的集成配置。WSL1 曾经是我梦想中的方案,但 WSL1 作为日常使用的子系统还是有其种种问题,其环境和物理或者 KVM 虚拟化的 Linux 还是有所区别,IO 也令人发指。

一个比较常见的问题是 systemd,众所周知 WSL 不管是 1 还是 2 都不支持直接启用 systemd,大概是因为微软自己启动的缘故。虽然没有官方的支持,但使用 genie 提供的 bottled 方案也并不是一个很难接受的选择,事实上体验基本与 systemd 一致——当然如果你需要的某些复杂高级功能工作不正常,那当我没说。听说 wsl2-hacks 也是个办法,但我没有尝试过。

另外,由于微软的奇葩设计,在每次 Windows 启动的时候 WSL2 都会被随机分配到完全随机的网段,这会导致不少问题。我遇到的主要是 Windows 下的防火墙难以配置WSL2 内连宿主机 IP 不稳定;还有选到和 docker 等虚拟环境冲突的网段导致路由错乱。前两个问题我通过一些脚本来解决,我把他们放到了 GitHub 的 oott123/work-on-windows 上供读者参考;而最后一个问题我也通过了一些办法解决,后文提到 docker 的时候再仔细说。

用上 WSL2 之后,wslg 也变得很简单,只需要 export DISPLAY=:0 并且 export WAYLAND_DISPLAY=wayland-0 就可以让 Linux 桌面程序显示成 Windows 窗口了。不过在我这边,wslg 的剪贴板不一定工作,我找到了一个 issue,但看起来没什么帮助的样子。之后也许要尝试自己去做剪贴板同步了。

如果你不想使用 Insider 系统来启用 wslg,也可以试试第三方方案 X410 。X410 ( X for 10 ) 是一款商业化的 X Server,相比 VcXserv 有更好的 HiDPI 支持,同时体验也更加流畅。官网有一些非常详尽的教程,例如和 WSL2 配合使用的和 Hyper-V 配合使用的,都可以看看。

Windows dev box – Windows 10

基于某种“不想在宿主机上安装开发环境”的奇怪洁癖矫情,我没有在我的宿主机器上安装 Visual Studio 、Android Studio 等开发环境,而是选择使用 VMWare 创建了一个虚拟机,并在虚拟机内安装。这台虚拟机里安装了 Visual Studio、Windows SDK、Android Studio 和 Visual Studio Code 等等 IDE 或编辑器。

因为使用频率比较低,所以也没咋配置,直接用 VMWare 开干了。实际体验只能说尚可接受,操作起来还是偶有迟滞的感觉,反正用得不多,懒得管了。

开发环境

IDE / SDK

鉴于我有两个 dev box ,那么某个 IDE 或者环境该在哪个 box 里安装无疑成了需要选择的事情。目前,我的基本准则是,能在 WSL2 里安装的,都在 WSL2 里安装:

  • Visual Studio – 宇宙第一 IDE 只支持 Windows,所以在 Windows box 里安装
  • Android Studio – WSL2 连实体机不方便,所以在 Windows box 里安装
  • Goland / DataGrip – WSL2 里安装,wslg 使用
  • Sublime Merge – WSL2 里安装,wslg 使用
  • nodejs, yarn, php 等命令行开发环境 – WSL2 里安装

Visual Studio Code

Visual Studio Code 的 Remote 功能是本世纪以来最伟大的发明。
—— 三三・自己说的

早在 coder 发布 code-server 的时候,我就搭建了一套用于日常开发;后来 vscode 发布了官方支持的 Remote 功能之后,我也就随之迁移到了 Remote 上进行开发。之前还需要通勤的时候,无论在公司还是在家里,都可以用 vscode remote 连接到自己的服务器摸一些东西;现在的话主要用于在 Windows 上连接 WSL 开发。

显然,我的 Visual Studio Code 是安装在宿主机上的;但使用体验和安装在 Linux 上并没有什么分别,一切都很顺滑。

Windows Terminal

我平时使用 Windows Terminal 作为我的 shell,大概配置成这个样子:

这张图片展示了使用 Windows Terminal 连接 WSL2 运行 neofetch 的结果。

在 Windows Terminal 中,为 WSL2 的 Profile 设置开始路径为 \\wsl$\Arch\home\oott123 这样的目录,就可以实现打开新标签的时候切换到 WSL 的家目录了,在这里就可以方便地存放自己的代码和开发环境了。注意不要把代码放到 /mnt/c/ 之类的地方去,否则你的 IO 会很惨。我平时使用 zsh 作为默认 shell,在 WSL2 里也是能直接使用的,就和普通的 Linux 系统没什么区别了。

另外,我使用了修改过的 zsh-notify 插件,配合 BurntToast实现命令错误/长时间任务完成推送 Windows 通知的功能。虽然由于偷懒,没有去检测当前焦点窗口是否在 shell 中导致命令报错的时候稍微有点吵之外,其实还挺好用的。

Docker

在 WSL2 里安装 docker 也是一件有两个选择的事情:使用 Docker Desktop,或者直接安装 docker daemon。我曾经选择了前者,还用上了非常酷炫和魔法的 WSL2 daemon,直到它出现了不少问题,最后由于我的 Arch 内核太新出现了一个我修不好的问题,一气之下就把它整个删掉了,安装了正常的 docker daemon。

前文提到过,WSL2 启动的时候会随机选择网段,有时候会选到和 docker 等虚拟环境冲突的网段导致路由错乱。后来我在 Windows 内创建一个和 docker 同网段的虚拟网卡之后,Hyper-V 似乎就很聪明地避开了这个网段,问题得以解决。

打开设备管理器,选择操作-添加过时硬件,依次选择安装手动从列表选择的硬件、网络适配器、Microsoft、Microsoft KM-TEST,并确认即可
使用设备管理器添加 KM-TEST 虚拟网卡

体验

在 Microsoft 大力拥抱开源社区的今天,使用 Windows 作为开发环境已经不是令人难以接受的事情了——当然前提是你使用 WSL2,我不会真的在 Windows 这样的 OS 上做开发的。微软的 Windows 虽然从来都广受诟病,但它的桌面环境体验不是其它竞争者(是的,我是说 Linux。你说什么 m 什么 OS 是啥,我听不见)可以比拟的。如果说曾经基于 BSD 内核的 macOS 拥有类似 UNIX 的开发体验,那么 WSL2 则是 99.9% 的 Linux 开发体验,这对于我来说是非常重要且舒适的。是的,绝对不是因为我要用 Windows 打游戏。

因为基于虚拟机的 dev box 使得备份和迁移变得异常方便,全虚拟化环境的拟真也能带来许多优势,而 WSL2 和 Windows 的集成也足够顺滑,所以我想,在可以预见的将来,我的开发环境仍然会首选宿主机 Windows + Linux / Windows dev box 的模式来配置。