大家好,欢迎来到IT知识分享网。
大家好,很高兴又见面了,我是”高级前端进阶”,由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发,您的支持是我不断创作的动力。

1.njs 宣布退出历史舞台
2025 年 7 月 10 日,njs 宣布自 v0.9.1 版本起引入了 QuickJS 引擎支持,其不仅兼容 ES2023,还为 NGINX 环境中的 JavaScript 脚本编写开辟了新的可能性。
按照官方的说法,njs 花费了大量时间维护和扩展为 Nginx 定制的 JavaScript 引擎,而没有更多精力专注在 JavaScript 和 NGINX 之间实现无缝集成的重要事项上。随着 Web 的发展以及开发者对现代 JavaScript 特性的依赖,局限性也愈发凸显:
- 语言本身的限制:ES5 基础架构以及有限的 ES6 扩展,开发者无法利用现代 JavaScript 模式或采用新语言标准的当代库生态
- 开发重点:维护定制的 JavaScript 引擎需要大量的资源,只能将有限的资源用来提升 NGINX 集成能力、优化性能和新功能
- 生态兼容性:许多现有的 JavaScript 库和工具都期望获得更全面的 ES6+ 支持,从而给希望在其 NGINX 配置中重用成熟解决方案的开发者带来了障碍
给开发者代码的弊端就是:njs 最初的设计目标与 JavaScript 开发社区不断变化的需求之间存在矛盾。
2. 为什么 Nginx 团队选择 QuickJS
njs 团队做了最新的战略决策,宣布集成 QuickJS 作为 Nginx 替代的 JavaScript 引擎,同时保留现有的 njs 引擎以实现向后兼容。
引入轻量级、可嵌入的 QuickJS 引擎具有以下几个显著优势:
- 完全兼容 ES2023 :支持完整的 ES2023 规范,包括 模块、异步生成器、Proxy 代理和 BigInt 等现代 JavaScript 开发的标准功能
import divide, {add, multiply} from "./mathUtils.js"; import {user, greet} from "./user.js"; // 模块化以前不支持 async function* myAsyncGenerator() { yield value; } // 异步生成器以前不支持 const proxy = new Proxy(target, handler); // Proxy 代理以前不支持 const a = 123n; const bigNum = 40991n; const b = BigInt(123); const c = BigInt("40991"); const negative = -456n; // BigInt 以前也不支持
- 体积优势 : 尽管 QuickJS 功能齐全,但体积非常小巧且易于嵌入,只需几个 C 文件,且无需任何外部依赖项。对于一个简单的程序来说,完整的 x86 代码占用 367 KB。
- 社区活跃 : 作为一个拥有更广泛社区参与的开源项目,QuickJS 受益于各种用例的持续开发和测试,从而减轻了 njs 团队的维护负担。同时,njs 团队还实现了 QuickJS 插入式替代,即现有 njs 脚本只需进行很少的修改或无需修改即可运行。
目前 QuickJS 在 Github 通过 MIT 协议开源,有超过 10k 的 star、1k 的 fork、妥妥的前端顶级开源项目。
3. 如何在 Nginx 中使用 QuickJS
3.1 如何自定义 QuickJS 构建
大多数 Linux 发行版都需要安装一些依赖项才能构建 NGINX 和 NGINX JavaScript。以下说明针对 apt 包管理器,该管理器在大多数 Ubuntu/Debian 发行版及其衍生版本中均可广泛使用。
sudo apt install gcc make // 安装编译器和 make 实用程序 sudo apt install libpcre3-dev zlib1g-dev libssl-dev libxml2-dev libxslt-dev // 安装依赖
如果要使用 QuickJS 进行构建,开发者还需要构建 QuickJS 库:
git clone https://github.com/bellard/quickjs cd quickjs CFLAGS='-fPIC' make libquickjs.a
下面使用 –with-cc-opt= 和 –with-ld-opt= 选项提供库路径:
auto/configure --add-dynamic-module=<NJS_SRC_ROOT_DIR>/nginx \ --with-cc-opt="-I<QUICKJS_SRC_ROOT_DIR>" \ --with-ld-opt="-L<QUICKJS_SRC_ROOT_DIR>"
3.2 如何在 Nginx 中使用 QuickJS
切换到 QuickJS 引擎非常简单,开发者只需一个配置指令即可。js_engine 指令适用于 HTTP 和流上下文,可让开发者指定要使用的 JavaScript 引擎。
下面是基础的 HTTP 配置:
// nginx.conf 配置 load_module modules/ngx_http_js_module.so; events {} http { js_import main from js/main.js; // 引入指定的文件 server { listen 8000; location /njs { js_content main.handler; } location /qjs { js_engine qjs; js_content main.handler; } } } // js/main.js 文件 function handler(r) { r.return(200, `Hello from ${njs.engine}`); } export default {handler};
下面是一个更复杂的示例,展示了 QuickJS 提供的现代 JavaScript 功能:
// nginx.conf 配置信息 http { js_engine qjs; js_import analytics from js/analytics.js; // 引入指定的文件 server { listen 8000; location /analytics { js_content analytics.processRequest; } } }
下面是 js/analytics.js 文件的内容:
class RequestAnalytics { // 使用生成器函数处理 HTTP 头部信息 *getHeaderMetrics(headers) { for (const [key, value] of Object.entries(headers)) { // 详细的头部信息 yield { header: key.toLowerCase(), size: key.length + value.length, type: key.startsWith("x-") ? "custom" : "standard", }; } } processRequest(r) { // 默认解构 const {method = "GET", uri = "/", httpVersion = "1.0"} = r; const headerStats = []; for (const metric of this.getHeaderMetrics(r.headersIn)) { headerStats.push(metric); } const timestamp = BigInt(Date.now()); // BigInt 保持详细时间 const headerCount = headerStats.length; const customHeaders = headerStats.filter( ({type}) => type === "custom" ).length; // 返回数据给客户端 r.return( 200, JSON.stringify( { message: `Request processed at ${timestamp}`, stats: {headerCount, customHeaders}, serverInfo: `${method} ${uri} HTTP/${httpVersion}`, }, null, 2 ) ); } } const analytics = new RequestAnalytics(); export default {processRequest: (r) => analytics.processRequest(r) };
3.3 在 Nginx 中使用 QuickJS 的权衡
在 Nginx 中引入 QuickJS 后,在实例创建、长时间运行的脚本、内存管理、上下文重用优化等方方面面都需要综合考量,例如:性能和内存占用之间的权衡:
- 更高的上下文重用率(默认值:128):由于上下文创建开销减少,性能更佳,但内存消耗更高
- 更低的上下文重用率(或使用 js_context_reuse 0 禁用):内存占用更低,但由于频繁创建上下文,延迟会增加
参考资料
https://github.com/nginx/njs
https://blog.nginx.org/blog/quickjs-engine-support-for-njs
https://github.com/bellard/quickjs
https://javascript.plainenglish.io/how-javascript-became-the-super-glue-inside-nginx-2ce57cb09686
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/186512.html