With NodeJS the crypto module can be used to generate the HMAC.
URL encoding is possible e.g. with encodeURIComponent(). Note that urllib.parse.quote() does not URL encode / by default, so only + and = are URL encoded in a Base64 encoded string. On the other hand, encodeURIComponent() encodes all three special characters.
If this behavior is to be maintained in the NodeJS code, / must be URL-decoded back when encodeURIComponent() is applied (e.g. via a regular expression).
Alternatively, instead of encodeURIComponent(), only + and = could be URL encoded directly using regular expressions.
const crypto = require('crypto');
var SECRETKEY = 'SECRETKEY'
var my_string = 'my_string';
var b64Hmac = crypto.createHmac('sha256', SECRETKEY).update(my_string).digest('base64');
var urlB64Hmac = encodeURIComponent(b64Hmac).replace(/%2F/g, "/"); // Remove replace() if / may also be URL-encoded...
console.log(urlB64Hmac); // aB3nu4l%2BN2jf2Z9ybad6vAPVEE8JbHlya/NYlKyJLsM%3D
Alternatively, the CryptoJS library can be used as in your sample code:
var CryptoJS = require('crypto-js')
var SECRETKEY = 'SECRETKEY'
var my_string = 'my_string';
var b64Hmac = CryptoJS.HmacSHA256(my_string, SECRETKEY).toString(CryptoJS.enc.Base64);
var urlB64Hmac = encodeURIComponent(b64Hmac).replace(/%2F/g, "/");
console.log(urlB64Hmac); // aB3nu4l%2BN2jf2Z9ybad6vAPVEE8JbHlya/NYlKyJLsM%3D
However, the advantage of the crypto module over the CryptoJS library is that no additional dependency is needed.