Nginx JavaScript (NJS): Using Node Modules
NJS lets you write JavaScript code that runs directly within Nginx. It's designed for speed and efficiency, offering a streamlined JavaScript environment tailored for server-side tasks. You get precise control over request handling and can perform non-blocking operations for optimal performance.
Since NJS doesn't fully support ES6, you'll need to transpile Node modules (libraries from npm) to ES5 before using them in your Nginx configuration.
To simplify using the uuid library in Nginx, we'll use a Dockerfile to create a compatible JavaScript file. This example focuses on generating GUIDs for a user_id cookie using the uuid.v4() function.
This article builds on the previous one (https://www.garudax.id/pulse/nginx-javascript-module-sanhapon-thadapradit-lza3c/), diving deeper into how to utilize npm libraries within Nginx JavaScript.
The Dockerfile below:
#Dockerfile.npm
FROM node:alpine
WORKDIR /tmp
COPY .babelrc .
RUN npm install -g npm
RUN npm install uuid @babel/core @babel/cli @babel/preset-env babelify
RUN printf "export default {};\n" > nginxify.uuid.js
RUN printf "global.uuid = require('uuid');\n" > tmp.js
RUN npx babel tmp.js --presets @babel/preset-env -o uuid_es5.js
RUN npx browserify uuid_es5.js -o browserify.uuid.js -t [ babelify --global --presets [ @babel/preset-env ] ]
RUN cat nginxify.uuid.js browserify.uuid.js > libs/uuidv4.js;
Note: Here is babel configuration
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "0.10"
}
}
]
],
"plugins": [
"@babel/plugin-transform-modules-commonjs"
]
}
In order to run docker from the dockerfile above, we use this batch script:
# build-npm.sh
#!/usr/bin/env bash
docker build -f Dockerfile.npm -t njs --progress=plain --no-cache .
ID=$(docker create njs)
docker cp $ID:/tmp/uuidv4.js $(pwd)/uuidv4.js
docker rm -v $ID
This script builds the Docker image, extracts the necessary file, and removes the temporary container, all in a single, streamlined command. You can run build-npm.sh in your terminal command and you will get uuidv4.js which is ready to be used in nginx.
The generated code (look at the bottom of uuidv4.js) ensures that you can use the uuid library in your Nginx JavaScript by attaching it to the global scope. This means you can directly call functions like uuid.v4() without any further imports in your NJS code
(function (global){(function (){
"use strict";
global.uuid = require('uuid');
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined"
Here's the code snippet where we call uuid : (https://www.garudax.id/pulse/nginx-javascript-module-sanhapon-thadapradit-lza3c/)
function userIdCookie(r) {
var uuid = global.uuid
...
var id = uuid.v4()
return id;
}
export default { userIdCookie };
Recap:
Given NJS's efficiency and tight integration with Nginx, it's a powerful tool for customizing request handling and adding server-side logic. By understanding its capabilities and limitations, you can leverage NJS to enhance your Nginx configurations and build more dynamic web applications.