您的当前位置:首页>全部文章>文章详情

Nginx安装njs模块并启用 QuickJS 引擎

发表于:2026-11-04 13:54:20浏览:8次TAG: #nginx #njs #quickjs

一、背景与方案选择

已有 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

七、官方文档

官方文档仅有英文版,社区中文资料(如 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 中加指令

```