傳統上 Windows 開發者若需要使用 Linux 環境,通常只有兩種選擇:安裝雙系統或使用虛擬機器。雙系統需要重新開機切換,嚴重影響工作流程的連續性。虛擬機器雖然能同時執行兩個系統,但會佔用大量的系統資源,而且 Windows 與 Linux 之間的檔案共享與整合相當複雜。這些限制讓許多開發者在 Windows 上開發 Linux 應用程式時面臨諸多不便。
Windows Subsystem for Linux(WSL)的出現徹底改變了這個局面。WSL 讓開發者能夠在 Windows 上直接執行 Linux 二進位執行檔,無需虛擬機器的額外負擔,也不需要重新開機切換系統。特別是 WSL 2 採用了完整的 Linux 核心,大幅提升了系統呼叫的相容性與檔案系統的效能。開發者可以在熟悉的 Windows 環境中使用 Visual Studio Code,同時在 WSL 中執行 Linux 工具鏈,實現真正的無縫整合。
然而要充分發揮 WSL 的潛力,需要正確的配置與調校。WSL 2 雖然效能優異,但預設的資源限制可能不適合所有開發場景。Docker Desktop 與 WSL 的整合雖然方便,但需要理解其架構才能避免常見的陷阱。Visual Studio Code 的 Remote-WSL 擴充套件功能強大,但需要適當的配置才能獲得最佳體驗。
本文將帶領讀者從零開始建構一個高效的 WSL 開發環境。我們將深入探討 WSL 2 的安裝與配置,解說如何整合 Docker Desktop 進行容器化開發,分享效能調校的實務技巧,並示範如何使用 Visual Studio Code 建立流暢的開發工作流程。透過詳細的步驟說明與程式碼範例,讀者將能夠建構一個媲美原生 Linux 的開發環境。
WSL 2 安裝與核心配置
WSL 有兩個主要版本:WSL 1 與 WSL 2。WSL 1 使用轉譯層將 Linux 系統呼叫轉換為 Windows NT 核心呼叫,雖然啟動速度快,但系統呼叫的相容性與檔案 I/O 效能有限。WSL 2 則採用了輕量級虛擬機器技術,執行完整的 Linux 核心,提供了接近原生 Linux 的效能與相容性。對於現代開發工作,強烈建議使用 WSL 2。
# 以系統管理員權限開啟 PowerShell
# 啟用 WSL 功能
# 這個命令會啟用 Windows Subsystem for Linux 功能
# 需要重新啟動電腦才能生效
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
# 啟用虛擬機器平台
# WSL 2 需要虛擬機器平台支援
# 這是 WSL 2 運作的基礎
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
# 重新啟動電腦
# 必須重新啟動才能使上述功能生效
Restart-Computer
# 重新開機後,設定 WSL 2 為預設版本
# 這樣之後安裝的 Linux 發行版都會使用 WSL 2
wsl --set-default-version 2
# 列出可用的 Linux 發行版
# 顯示 Microsoft Store 中所有可安裝的 Linux 發行版
wsl --list --online
# 安裝 Ubuntu 22.04 LTS
# 這是目前最穩定且廣泛使用的發行版之一
# 安裝過程會要求設定使用者名稱與密碼
wsl --install -d Ubuntu-22.04
# 驗證安裝
# 列出所有已安裝的 WSL 發行版
# -v 參數會顯示詳細資訊,包括版本號
wsl --list --verbose
# 更新 WSL 核心
# 確保使用最新的 WSL 核心版本
# 這能獲得最新的功能與安全性修復
wsl --update
# 檢查 WSL 版本
# 顯示 WSL 的版本資訊與已安裝的發行版
wsl --status
安裝完成後,需要進入 WSL 環境進行初始配置。這包括更新套件管理器、安裝常用開發工具與配置環境變數。以下是一個完整的初始化腳本。
#!/bin/bash
# WSL Ubuntu 初始化配置腳本
#
# 這個腳本會執行以下操作:
# 1. 更新系統套件
# 2. 安裝常用開發工具
# 3. 配置 Git
# 4. 安裝 Node.js 與 Python
# 5. 配置 shell 環境
# 更新套件索引
# 確保套件管理器有最新的套件清單
echo "更新套件索引..."
sudo apt update
# 升級所有已安裝的套件
# 將系統中所有套件更新到最新版本
echo "升級系統套件..."
sudo apt upgrade -y
# 安裝基礎開發工具
# build-essential 包含 gcc、g++、make 等編譯工具
# curl 與 wget 用於下載檔案
# git 用於版本控制
# vim 是文字編輯器
echo "安裝基礎開發工具..."
sudo apt install -y \
build-essential \
curl \
wget \
git \
vim \
tree \
htop \
net-tools
# 配置 Git
# 設定全域的使用者名稱與電子郵件
# 這些資訊會出現在 Git 提交記錄中
echo "配置 Git..."
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
# 設定 Git 的預設編輯器為 vim
git config --global core.editor vim
# 設定 Git 的換行符處理
# input 表示在提交時將 CRLF 轉換為 LF
# 這對於跨平台開發很重要
git config --global core.autocrlf input
# 安裝 Node.js 使用 nvm
# nvm 是 Node.js 版本管理器,可以輕鬆切換不同版本
echo "安裝 Node.js 版本管理器 (nvm)..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# 載入 nvm
# 執行 nvm 的初始化腳本
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# 安裝最新的 LTS 版本 Node.js
# LTS (Long Term Support) 版本更穩定
echo "安裝 Node.js LTS..."
nvm install --lts
nvm use --lts
# 驗證 Node.js 與 npm 安裝
node --version
npm --version
# 安裝 Python 開發環境
# Python 3 與 pip 套件管理器
echo "安裝 Python 開發環境..."
sudo apt install -y \
python3 \
python3-pip \
python3-venv
# 升級 pip 到最新版本
python3 -m pip install --upgrade pip
# 配置 shell 環境
# 在 .bashrc 中加入自訂配置
echo "配置 shell 環境..."
# 加入自訂的 alias
cat >> ~/.bashrc << 'EOF'
# 自訂 alias
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
# 設定彩色提示符
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
# Node.js 路徑
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
EOF
# 重新載入 .bashrc
source ~/.bashrc
echo "WSL 初始化完成!"
echo "請執行 'source ~/.bashrc' 來載入新的環境設定"
WSL 2 的一個重要特性是可以透過 .wslconfig 檔案配置虛擬機器的資源限制。這個檔案位於 Windows 使用者目錄下,可以控制 WSL 2 使用的記憶體、處理器與交換空間。
# .wslconfig 檔案
# 位置:C:\Users\<YourUsername>\.wslconfig
#
# 這個檔案用於配置 WSL 2 虛擬機器的全域設定
# 修改後需要執行 wsl --shutdown 重新啟動 WSL 才能生效
[wsl2]
# 記憶體限制
# 設定 WSL 2 可以使用的最大記憶體
# 預設是系統記憶體的 50% 或 8GB(取較小值)
# 範例:限制為 8GB
memory=8GB
# 處理器核心數
# 設定 WSL 2 可以使用的處理器核心數
# 預設使用所有可用的核心
# 範例:限制為 4 個核心
processors=4
# 交換空間大小
# 設定 WSL 2 的虛擬記憶體大小
# 預設是實體記憶體的 25%
# 設定為 0 可以停用交換空間
# 範例:設定為 2GB
swap=2GB
# 交換檔案路徑
# 指定交換檔案的儲存位置
# 預設在 %USERPROFILE%\AppData\Local\Temp\swap.vhdx
swapfile=C:\\temp\\wsl-swap.vhdx
# 本地主機轉發
# 啟用後可以從 Windows 存取 WSL 中監聽的埠
# 預設為 true
localhostforwarding=true
# 巢狀虛擬化
# 允許在 WSL 2 中執行虛擬機器
# 某些容器化工作負載可能需要這個功能
# 預設為 false
nestedVirtualization=true
# 核心命令列參數
# 傳遞給 Linux 核心的額外參數
# 可以用於啟用特定的核心功能
# kernelCommandLine = vsyscall=emulate
# 安全啟動
# 是否啟用安全啟動
# 預設為 true
# safeMode=true
# 除錯控制台
# 啟用核心除錯控制台輸出
# 用於診斷核心問題
# debugConsole=false
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
|Windows 使用者|
start
:執行 wsl --install;
|Windows PowerShell|
:檢查系統需求;
if (支援虛擬化?) then (是)
:啟用 WSL 功能;
:啟用虛擬機器平台;
:提示重新啟動;
|Windows 使用者|
:重新啟動電腦;
|Windows PowerShell|
:下載 Linux 核心更新;
:安裝 Linux 核心;
:下載 Ubuntu 映像檔;
|Hyper-V|
:建立 WSL 2 虛擬機器;
:配置虛擬硬碟;
:載入 Linux 核心;
|Ubuntu|
:初始化檔案系統;
:啟動 init 程序;
:提示建立使用者;
|Windows 使用者|
:輸入使用者名稱與密碼;
|Ubuntu|
:建立使用者帳號;
:配置 sudo 權限;
:啟動 shell;
|Windows 使用者|
:執行初始化腳本;
:更新套件;
:安裝開發工具;
:配置環境變數;
:安裝完成;
stop
else (否)
:顯示錯誤訊息;
|Windows 使用者|
:檢查 BIOS 設定;
stop
endif
@enduml
Docker Desktop 與 WSL 2 深度整合
Docker Desktop 是 Windows 上最流行的容器化平台,它與 WSL 2 的整合提供了卓越的效能與開發體驗。相較於傳統的 Hyper-V 後端,WSL 2 後端啟動更快,資源使用更有效率,且能與 WSL 發行版無縫整合。開發者可以在 WSL 中使用 docker 命令列工具,同時享受 Docker Desktop 的圖形介面管理功能。
# 在 Windows 上下載並安裝 Docker Desktop
# 從官方網站下載:https://www.docker.com/products/docker-desktop
# 安裝後,在 Docker Desktop 設定中:
# 1. 進入 Settings -> General
# 2. 勾選 "Use the WSL 2 based engine"
# 3. 進入 Settings -> Resources -> WSL Integration
# 4. 啟用想要使用 Docker 的 WSL 發行版
# 驗證 Docker 是否正確安裝(在 WSL 中執行)
docker --version
docker-compose --version
# 測試 Docker 執行
# 執行一個簡單的 hello-world 容器
docker run hello-world
在 WSL 環境中,Docker 的使用與原生 Linux 幾乎完全相同。以下範例展示如何建立一個完整的開發環境,包括資料庫、快取與應用程式伺服器。
# docker-compose.yml
# 定義一個完整的 Web 應用程式開發環境
# 包含 PostgreSQL 資料庫、Redis 快取與 Node.js 應用程式
version: '3.8'
# 定義服務
services:
# PostgreSQL 資料庫服務
postgres:
# 使用官方的 PostgreSQL 14 映像檔
image: postgres:14-alpine
# 容器名稱
container_name: dev_postgres
# 環境變數配置
environment:
# 資料庫超級使用者密碼
POSTGRES_PASSWORD: devpassword
# 預設資料庫名稱
POSTGRES_DB: appdb
# 預設使用者名稱(預設為 postgres)
POSTGRES_USER: devuser
# 埠號映射
# 將容器的 5432 埠映射到主機的 5432 埠
ports:
- "5432:5432"
# 資料卷掛載
# 持久化資料庫資料
volumes:
# 將資料庫資料儲存在 Docker 管理的卷中
- postgres_data:/var/lib/postgresql/data
# 掛載初始化 SQL 腳本
# 容器啟動時會自動執行這個目錄中的 .sql 檔案
- ./init-scripts:/docker-entrypoint-initdb.d
# 健康檢查
# 確保資料庫服務正常運作
healthcheck:
test: ["CMD-SHELL", "pg_isready -U devuser -d appdb"]
interval: 10s
timeout: 5s
retries: 5
# 網路配置
networks:
- dev_network
# Redis 快取服務
redis:
# 使用官方的 Redis Alpine 映像檔
image: redis:7-alpine
container_name: dev_redis
# 埠號映射
ports:
- "6379:6379"
# 啟動命令
# 啟用 AOF 持久化
command: redis-server --appendonly yes
# 資料卷掛載
volumes:
- redis_data:/data
# 健康檢查
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- dev_network
# Node.js 應用程式服務
app:
# 使用 Node.js 18 Alpine 映像檔
image: node:18-alpine
container_name: dev_app
# 工作目錄
working_dir: /app
# 環境變數
environment:
# Node.js 環境
NODE_ENV: development
# 資料庫連線字串
DATABASE_URL: postgresql://devuser:devpassword@postgres:5432/appdb
# Redis 連線字串
REDIS_URL: redis://redis:6379
# 埠號映射
ports:
- "3000:3000"
# 資料卷掛載
volumes:
# 掛載當前目錄到容器的 /app
# 這樣可以即時反映程式碼變更
- .:/app
# 使用匿名卷避免 node_modules 被覆蓋
# WSL 與 Windows 之間的 node_modules 可能不相容
- /app/node_modules
# 啟動命令
# 使用 nodemon 監視檔案變更並自動重啟
command: sh -c "npm install && npm run dev"
# 依賴關係
# 等待資料庫與快取服務啟動
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- dev_network
# 定義資料卷
# 用於持久化資料
volumes:
# PostgreSQL 資料卷
postgres_data:
driver: local
# Redis 資料卷
redis_data:
driver: local
# 定義網路
# 所有服務在同一個網路中可以互相通訊
networks:
dev_network:
driver: bridge
Docker 在 WSL 中的使用還包括一些效能最佳化技巧。由於 WSL 2 使用虛擬檔案系統,跨 Windows 與 Linux 檔案系統的操作會有效能損失。因此建議將專案檔案存放在 WSL 檔案系統中(例如 /home/username/projects)而非 Windows 檔案系統(例如 /mnt/c/Users/...)。
# 在 WSL 中管理 Docker 的常用命令
# 啟動所有服務
# -d 參數表示在背景執行
docker-compose up -d
# 查看服務狀態
# 顯示所有容器的狀態、埠號映射等資訊
docker-compose ps
# 查看服務日誌
# -f 參數表示持續追蹤日誌輸出
docker-compose logs -f
# 查看特定服務的日誌
docker-compose logs -f app
# 進入容器的 shell
# 用於除錯或執行命令
docker-compose exec app sh
# 停止所有服務
# 容器會被停止但不會被刪除
docker-compose stop
# 停止並刪除所有容器
# -v 參數會同時刪除匿名卷
docker-compose down -v
# 重新建構映像檔
# 當 Dockerfile 或依賴項變更時使用
docker-compose build
# 重新建構並啟動服務
docker-compose up -d --build
# 清理未使用的資源
# 刪除停止的容器、未使用的網路與映像檔
docker system prune -a
# 查看 Docker 磁碟使用情況
docker system df
Visual Studio Code Remote-WSL 開發環境
Visual Studio Code 的 Remote-WSL 擴充套件讓開發者能夠在 Windows 中使用 VS Code 的圖形介面,同時在 WSL 中執行所有的開發工具與執行環境。這種架構結合了兩個系統的優勢:Windows 的熟悉介面與 Linux 的強大工具鏈。
# 在 WSL 中安裝 VS Code 伺服器元件
# 實際上不需要手動安裝,Remote-WSL 會自動處理
# 從 WSL 中開啟 VS Code
# 這個命令會在 Windows 中啟動 VS Code
# 並自動連接到 WSL 環境
code .
# 如果這是第一次執行,VS Code 會自動安裝 WSL 伺服器元件
# 之後的啟動會更快
在 VS Code 中配置 WSL 開發環境需要安裝適當的擴充套件,並設定工作區的配置。以下是一個完整的 Node.js 專案配置範例。
// .vscode/settings.json
// VS Code 工作區設定檔
{
// 整合終端機設定
"terminal.integrated.defaultProfile.linux": "bash",
// 檔案監視排除
// 排除不需要監視的目錄以提升效能
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/dist/**": true
},
// 檔案搜尋排除
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/.git": true
},
// ESLint 配置
"eslint.enable": true,
"eslint.validate": [
"javascript",
"typescript"
],
// Prettier 配置
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
// TypeScript 配置
"typescript.updateImportsOnFileMove.enabled": "always",
// Git 配置
"git.autofetch": true,
"git.confirmSync": false,
// 編輯器配置
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.rulers": [80, 120],
// 遠端開發設定
// 指定在 WSL 中安裝的擴充套件
"remote.extensionKind": {
"ms-vscode.cpptools": ["workspace"]
}
}
// .vscode/launch.json
// VS Code 除錯配置檔
{
"version": "0.2.0",
"configurations": [
{
// Node.js 應用程式除錯配置
"type": "node",
"request": "launch",
"name": "Launch Program",
// 要執行的程式進入點
"program": "${workspaceFolder}/src/index.js",
// 執行前先編譯 TypeScript(如果使用 TS)
"preLaunchTask": "tsc: build - tsconfig.json",
// 輸出配置
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
// 環境變數
"env": {
"NODE_ENV": "development"
},
// 控制台配置
"console": "integratedTerminal",
// 自動附加子程序
"autoAttachChildProcesses": true
},
{
// Docker 容器中的應用程式除錯配置
"type": "node",
"request": "attach",
"name": "Attach to Docker",
// 連接埠號(容器需要開放除錯埠)
"port": 9229,
// 本地檔案與遠端檔案的路徑映射
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app",
// 重啟時自動重新附加
"restart": true,
// 跳過不需要除錯的檔案
"skipFiles": [
"<node_internals>/**"
]
}
]
}
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 14
skinparam minClassWidth 100
|開發者|
start
:在 WSL 中開啟專案目錄;
:執行 code .;
|VS Code (Windows)|
:啟動 VS Code 視窗;
if (已安裝 Remote-WSL?) then (是)
:檢查 WSL 伺服器元件;
if (伺服器已安裝?) then (是)
:連接到 WSL;
else (否)
:下載並安裝伺服器元件;
|WSL|
:安裝 VS Code Server;
:啟動伺服器程序;
|VS Code (Windows)|
:建立連線;
endif
else (否)
:提示安裝 Remote-WSL 擴充套件;
|開發者|
:安裝擴充套件;
|VS Code (Windows)|
:重新連接;
endif
:載入工作區設定;
:掃描專案檔案;
|WSL|
:執行檔案系統操作;
:回傳檔案清單;
|VS Code (Windows)|
:顯示專案結構;
|開發者|
:編輯程式碼;
|VS Code (Windows)|
:傳送變更到 WSL;
|WSL|
:更新檔案;
:觸發 nodemon 重新載入;
|Docker Container|
:重新啟動應用程式;
|開發者|
:在瀏覽器測試;
if (需要除錯?) then (是)
:設定中斷點;
:啟動除錯器;
|VS Code (Windows)|
:連接到 Node.js 除錯埠;
|WSL / Docker|
:暫停於中斷點;
:回傳變數狀態;
|VS Code (Windows)|
:顯示除錯資訊;
|開發者|
:檢查變數;
:繼續執行;
endif
stop
@enduml
從實務角度來看,WSL 2 已經成為 Windows 開發者不可或缺的工具。它消除了傳統跨平台開發的諸多障礙,讓開發者能夠在 Windows 上享受接近原生 Linux 的開發體驗。Docker Desktop 與 WSL 2 的整合更是將容器化開發帶入了新的境界,啟動速度與資源效率都遠超傳統的虛擬機器方案。
效能調校是充分發揮 WSL 潛力的關鍵。透過 .wslconfig 適當配置記憶體與處理器資源,可以在效能與系統穩定性之間找到平衡。將專案檔案存放在 WSL 檔案系統而非 Windows 檔案系統,能夠顯著提升檔案 I/O 效能。理解 WSL 與 Windows 之間的檔案系統互動機制,有助於避免常見的效能陷阱。
Visual Studio Code 的 Remote-WSL 擴充套件完美地整合了兩個系統。開發者可以使用熟悉的 Windows 圖形介面,同時在 WSL 中執行所有的建構工具、測試框架與除錯器。這種架構不僅提升了生產力,也讓多人協作更加順暢,因為整個團隊可以使用相同的 Linux 環境,而不必擔心 Windows 與 macOS 或 Linux 之間的差異。
展望未來,WSL 的發展將繼續深化 Windows 與 Linux 的整合。WSLg 已經為圖形應用程式提供了良好的支援,未來可能會看到更多的系統層級整合。對於開發者而言,掌握 WSL 不僅是一個技術選擇,更是提升開發效率與擴展技術能力的重要途徑。