Nginx 的配置文件层级深、块多,一个站点拆出几十行 location 很常见。编辑器没有语法高亮时,引号没闭合、大括号不配对这类低级错误很难一眼看出来,nginx -t 报错还得回头逐行找。这篇按编辑器给出开启高亮的具体做法:VS Code 走扩展市场一键装;Vim 先做 30 秒识别体检——近年版本的 Vim 已把 Nginx 识别收进自带运行时,开箱即用,体检不过关再从 Nginx 源码包拷官方语法文件(两步都有完整实测)。

按你用的编辑器跳转:

  • 用 VS Code → 看第 1 节,两分钟搞定;
  • 用 Vim → 看第 2 节,先体检再决定装不装,附对照组实测和两个真实的坑。

VS Code:装一个扩展

VS Code 内置的语言支持里没有 Nginx 配置,需要装扩展补上。打开扩展市场(Ctrl+Shift+X),搜索 nginx.conf,选择安装量高的那个装上即可。挑扩展时看两点:一是更新时间,Nginx 指令逐年增加(如 grpc_pass、http2 相关),久不更新的扩展会把这些新指令标成”未知”;二是安装量,百万级安装的扩展基本不存在乱标关键字的问题。

装完后不需要额外配置:打开任意 .conf 文件或 nginx 配置路径下的文件,右下角状态栏的语言模式显示 nginx 就说明生效了。如果 .conf 文件没有被自动识别,点击状态栏的语言模式手动选一次 nginx,VS Code 会记住这个关联。

配置文件名不固定、又想一劳永逸的项目,用工作区的 files.associations 把文件名模式批量关联到 nginx 语言:

1
2
3
4
5
6
{
"files.associations": {
"*.conf": "nginx",
"**/nginx/**": "nginx"
}
}

放在 .vscode/settings.json 里,团队共用仓库时随仓库提交,所有协作者打开就是高亮就绪的状态,省去各自手选语言模式的步骤。

Vim:先做 30 秒识别体检

先别急着装东西。近年版本的 Vim 已经自带 Nginx 语法、缩进和文件类型识别,实测 Alpine 3.20 的 vim 9.1(未拷贝任何语法文件):nginx.conf、app.nginx、/etc/nginx/ 下的配置文件打开都是 filetype=nginx,语法、缩进、文件类型插件在 /usr/share/vim/vim91/ 里三件套齐全。

体检只需一步——用 Vim 打开任意一个 nginx 配置,看文件类型:

1
2
vim /etc/nginx/nginx.conf
# 底部命令 :set ft? 应输出 filetype=nginx

输出 filetype=nginx 说明内置识别在工作,后面两小节可以整段跳过;输出为空或 conf 才需要往下走。想看得更全,可以做一组对照实验:同一份 server 块存成三种文件名,逐一问 :set ft?,实测结果如下。

vim 9.1 内置识别对照实测

文件名 :set ft? 结果 说明
nginx.conf nginx 主配置名默认命中
app.nginx nginx *.nginx 后缀是通用兜底
app.conf conf 随意命名不识别,规则设计使然
/etc/nginx/real.conf nginx 系统配置路径优先命中

对照表里最实用的是第二行:自己拆出来的零散配置片段想获得高亮,改个 .nginx 后缀就行;放进 /etc/nginx/ 目录下同样有效。app.conf 识别为 conf 不是 bug——识别规则按文件名和路径匹配,不读文件内容猜语言。

Vim:内置识别缺失时,拷 Nginx 源码包自带的语法文件

体检不过关的多半是老版本 Vim。这种情况的正规补救一直是 Nginx 源码包 contrib/vim/ 目录——Nginx 官方维护、随每个发行版更新,语法规则跟着 nginx 新指令走,比第三方脚本可靠。

先把源码包拿到手:

1
2
3
curl -LO https://nginx.org/download/nginx-1.28.0.tar.gz
tar xzf nginx-1.28.0.tar.gz
cd nginx-1.28.0

contrib/vim/ 下有四个目录,各管一件事:

目录 作用
syntax 语法高亮规则(指令、字符串、注释的配色)
indent 按 server/location 块自动缩进
ftdetect 决定哪些文件按 nginx 语法处理
ftplugin nginx 文件专属的编辑行为(注释符等)

然后把它们整体拷贝到 Vim 的运行时目录:

1
2
mkdir -p /usr/share/vim/vimfiles/
cp -r contrib/vim/* /usr/share/vim/vimfiles/

先 mkdir 再拷贝,别省。实测在 Alpine 容器里直接执行 cp -r 报错 cp: can't create directory '/usr/share/vim/vimfiles/ftdetect': No such file or directory——vimfiles 目录在不少精简系统里并不预建,rpath 里声明了它不等于它存在。Debian、CentOS 这类发行版的 vim 包通常会预建该目录,但加上 mkdir -p 在任何系统上都不会错。从踩坑到装好的完整实跑记录:

contrib/vim 拷贝与 mkdir 坑实测

装完再跑一遍上面的体检命令,:set ft? 变成 filetype=nginx 才算收工。contrib/vim 的 ftdetect 规则比新版 Vim 内置的窄——实测 1.28.0 源码包里只有四条:*.nginx 后缀、文件名恰为 nginx.conf、/etc/nginx/ 与 /usr/local/nginx/conf/ 路径;内置规则额外把 nginx*.conf、*/nginx/*.conf 这类变体也收了。拷完之后再遇到 app.conf 不识别,要么改名 .nginx,要么挪进 /etc/nginx/。

headless 场景的一个坑

识别的触发依赖 Vim 的 filetype 机制。交互使用时主流发行版都会把它打开——Alpine 的默认 vimrc 里虽然没有显式的 filetype on 一行,实测交互模式打开上表三种文件照样识别。真正的坑在 headless:脚本里常用的静默 ex 模式 vim -es 不加载任何 vimrc,filetype 机制不启动,:set ft? 输出为空;给命令串显式加上 filetype detect 即可恢复(体检实测用的就是 vim -es -c "filetype detect" -c "set ft?" -c q 文件名 这个形态)。用脚本批量检查文件类型的读者,记住这个开关能省下大半排查时间。

装好之后能立刻感受到两处变化。一是结构可读:server、location、upstream 这些块级指令带色之后,嵌套层级一眼可辨,丢一个大括号当场就能看到后半段全部”变色错乱”;二是缩进自动化:indent 脚本让新增的 location 块自动对齐父级,手工敲空格对齐的时间全省下来。改完配置照旧 nginx -t,高亮负责把低级错误挡在第一步。

装完却还是黑白的,按顺序查三处:一看文件名是否撞上识别规则(最常见,改名 .nginx 立验);二查 filetype 机制是否被自己的 vimrc 关掉;三确认拷贝目标和 set rtp? 输出的路径是同一个目录——路径对不上,文件拷了也等于没拷。

注意事项

  • 插件和语法文件只影响编辑器显示,配置写得对不对它管不了。改动落盘后、reload 之前,nginx -t 仍然是不可省的验证步骤。
  • contrib/vim/ 来自 Nginx 源码包,执行拷贝前确认当前目录是解包后的源码根目录;Nginx 升级后语法文件不会自动更新,重要版本变更时可重新拷贝一次。新版 Vim 已内置识别的环境,这一步可以整个省掉。
  • Vim 运行时目录因系统和编译选项而异,vim -es -c 'set rtp?' -c q 可以列出本机实际的查找路径,拷贝目标从输出里挑一个写权限齐全的即可。
  • 服务器上临时改配置没有条件装语法文件时,nginx -t 的报错自带定位——实测把 server 块放到 http 外面(单行文件 /tmp/bad2.conf),报错是 nginx: [emerg] "server" directive is not allowed here in /tmp/bad2.conf:1,文件名行号都在末尾,先看行号再定位,别裸眼数括号。

本文由作者 2020-2024 年间的 CSDN 博客文章重构而来,原发布于 CSDN。