Nginx安装njs模块并启用 QuickJS 引擎
发表于:2026-11-04 13:54:20浏览:8次
一、背景与方案选择
已有 Nginx 1.25.0,无需重新编译整个 Nginx,采用编译动态模块的方式安装 njs:
- 确认 Nginx 支持动态模块:
nginx -V 2>&1 | grep -o 'with-compat' # 输出 with-compat 即支持
预编译包 apt install nginx-module-njs 因依赖 libreadline7 在新系统不可用而失败,故改用源码编译。
二、准备源码
1. 下载与当前 Nginx 完全一致的源码
cd /data
wget http://nginx.org/download/nginx-1.25.0.tar.gz
tar -zxvf nginx-1.25.0.tar.gz
2. 获取 njs 源码
cd /data
git clone https://github.com/nginx/njs.git
目录结构应为 /data/njs/nginx/config(这是给 Nginx 用的模块配置)。
3. 获取 QuickJS 源码并编译静态库
cd /data
git clone https://github.com/bellard/quickjs
cd quickjs
CFLAGS='-fPIC' make libquickjs.a
生成 libquickjs.a,供 njs 模块链接。
三、编译 njs 动态模块
1. 配置
sudo apt install libxml2-dev libxslt1-dev
cd /data/nginx-1.25.0
make clean
./configure --with-compat \
--add-dynamic-module=/data/njs/nginx \
--with-cc-opt="-I/usr/include -I/data/quickjs" \
--with-ld-opt="-L/usr/lib/x86_64-linux-gnu -L/data/quickjs -lssl -lcrypto"
关键点说明:
| 参数 | 作用 |
|---|---|
--with-compat |
允许动态模块与当前 Nginx 二进制兼容 |
--add-dynamic-module=/data/njs/nginx |
指定 njs 模块源码路径(用绝对路径避免找不到 config) |
--with-cc-opt="-I/usr/include -I/data/quickjs" |
指定 OpenSSL 与 QuickJS 头文件路径 |
--with-ld-opt="-L/usr/lib/x86_64-linux-gnu -L/data/quickjs -lssl -lcrypto" |
指定 OpenSSL 与 QuickJS 库路径 |
注意:
--with-ld-opt里不要手动加-lquickjs,njs 的构建脚本会自行链接 QuickJS;这里只需提供库搜索路径-L/data/quickjs。
2. 编译并安装模块
make modules
sudo cp objs/ngx_http_js_module.so /usr/lib/nginx/modules/
# 如需 stream 模块:
# sudo cp objs/ngx_stream_js_module.so /usr/lib/nginx/modules/
3. 加载模块
编辑 /etc/nginx/nginx.conf,在文件最顶部(events 块之前)添加:
load_module modules/ngx_http_js_module.so;
4. 验证链接的 OpenSSL 与 Nginx 一致
ldd $(which nginx) | grep -E 'ssl|crypto'
ldd /usr/lib/nginx/modules/ngx_http_js_module.so | grep -E 'ssl|crypto'
两者都应指向 /lib/x86_64-linux-gnu/libssl.so.1.1 与 libcrypto.so.1.1,否则会出现 undefined symbol: EVP_PKEY_CTX_set1_hkdf_salt 之类的错误。
四、njs 基本使用与测试
1. 测试脚本 /etc/nginx/njs/test.js
function hello(r) {
r.headersOut['Content-Type'] = 'text/plain; charset=utf-8';
r.return(200, "njs is working!\n");
}
export default {hello};
不设置
Content-Type时浏览器可能触发下载而非直接显示文字。
2. Nginx 配置
http {
js_import test from /etc/nginx/njs/test.js;
server {
listen 80;
server_name localhost;
location /njs-test {
js_content test.hello;
}
}
}
3. 测试
sudo nginx -t
sudo nginx -s reload
curl http://localhost/njs-test
# 输出:njs is working!
五、启用 QuickJS 新引擎
njs 自带的旧引擎自 1.0.0 起被标记为弃用,推荐使用 QuickJS 引擎(完整支持 ES2023)。
1. 在配置中用 js_engine 指令启用
js_engine 从 njs 0.8.6 开始支持,可放在 http、server 或 location 块中。
http {
js_import test from /etc/nginx/njs/test.js;
server {
listen 80;
location /njs-test {
js_content test.hello; # 默认旧引擎
}
location /qjs-test {
js_engine qjs; # 启用 QuickJS
js_content test.hello;
}
}
}
2. 验证引擎
修改测试脚本,打印当前引擎名:
function hello(r) {
r.headersOut['Content-Type'] = 'text/plain; charset=utf-8';
r.return(200, "Engine: " + njs.engine + "\n");
}
export default {hello};
重新加载后访问:
sudo nginx -s reload
curl http://localhost/njs-test # Engine: njs
curl http://localhost/qjs-test # Engine: QuickJS
六、js_import 指令要点
| 语法 | 说明 |
|---|---|
js_import module.js; |
以文件名(去 .js)作为命名空间,如 module.func |
js_import name from module.js; |
自定义命名空间,如 name.func |
示例:
js_import test from /etc/nginx/njs/test.js;
# 调用:test.hello
七、官方文档
- njs 总览:https://nginx.org/en/docs/njs/
- HTTP 模块指令(含
js_import、js_engine):https://nginx.org/en/docs/http/ngx_http_js_module.html
官方文档仅有英文版,社区中文资料(如 nginx101.com、掘金/CSDN 博客)可作辅助,但配置应以官方文档为准。
八、常见问题排查
| 现象 | 原因 | 解决 |
|---|---|---|
no ../njs/nginx/config was found |
相对路径不对 | 用绝对路径 --add-dynamic-module=/data/njs/nginx |
the HTTP XSLT module requires the libxml2/libxslt libraries |
缺少 XSLT 开发库 | 加 --without-http_xslt_module,或安装 libxml2-dev libxslt1-dev |
undefined symbol: EVP_PKEY_CTX_set1_hkdf_salt |
模块与 Nginx 的 OpenSSL 版本不一致 | 用 --with-cc-opt/--with-ld-opt 锁定系统 OpenSSL 路径后重编 |
| 访问时触发下载 | 未设置 Content-Type |
JS 中设置 r.headersOut['Content-Type'] = 'text/plain; charset=utf-8' |
返回 Engine: njs 而非 QuickJS |
模块未链接 QuickJS,或未加 js_engine qjs |
重编时加入 QuickJS 头/库路径,并在 location 中加指令 |
```
