Conditional import/export when using different environment - node.js

I'm currently developing a Lambda function using node14 on AWS, but I have an issue when I want to develop it locally.
In my dev environment I have a corporate proxy needed to connect to AWS. In this case, I use aws-sdk-proxy library. However, I don't want to use this package while in production (as Lambda already has the aws-sdk injected in lambda core).
So, I created this snippet to perform the switch between the 2 environments:
// aws.js
import AWSPROD from 'aws-sdk'
import AWSDEV from 'aws-sdk-proxy'
import config from '../lib/Config.js'
import logger from './logger.js'
let AWS = null
if (config.get('ENVIRONMENT') === 'dev') {
logger.debug('[DEV] Using aws-sdk-proxy')
AWS = AWSDEV
} else {
AWS = AWSPROD
}
export default AWS
Not so clean, but it works. With this code, I can perform this:
import AWS from './aws.js'
Now the problem is that this code implies that I must provide aws-sdk-proxy into the "prod" dependencies of my package.json.
I think it breaks performance of the lambda as the code raised 9Mo (2Mo without), but I wish to keep this way of calling "AWS" SDK [the 2d code block].
I tried to use required or dynamic import but none of these solutions work.
Do you have any advice to improve my code?
PS:
The code is transpiled to ES5 using Babel to fit Lambda requirements
aws-sdk-proxy library must stay in devDependencies as it's a dev dependency

Related

Firebase docs reference unknown module

Firebase has this piece of information here at https://firebase.google.com/docs/functions/locations:
Client-side location selection for callable functions Regarding the callable function, client callable setups should follow the same guidelines as HTTP functions. The client can also specify a region, and must do so if the function runs in any region other than us-central1.
To set regions on the client, specify the desired region at
initialization:
var functions = firebase.app().functions('us-central1');
I've been trying to find which node module firebase is referring to but I have had no luck.
I know that it is not 'firebase-admin' or 'firebase-functions' but thats about it.
Anyone have any ideas what this might be referring to?
Edit:
I have now also tried using this with the imports require('firebase') and require('firebase/app') (as suggested) but neither of those seem to work. I also tried generating the app with const app = firebase.initializeApp({}); and then running app.functions("region") or app().functions("region") but i keep receiving TypeErrors saying functions is not a function and app is not a function respectively.
firebase.app().functions('us-central1'); is a part of the firebase-js-sdk. With source code documented on GitHub
NPM component is #firebase/functions, that is documented on the npmjs.com.
However, it is not intended for standalone usage, and should be used along with package Firebase.
You can install it using:
$ npm i firebase

Azure Functions use import instead of require

What is the configuration requirements to use import instead of require?
I'm using function runtime v2.
I tried upgrading node to v10.12.0 but still get this error when it hits the imports
Worker was unable to load function store: 'SyntaxError: Unexpected token {'
I have node version set to 10.12.0 in local.settings and in package.json.
my function is setup like this ...
module.exports = async function(context, queueMessage) {
import { cosmos } from "#azure/cosmos";
import { updateChat } from "./channels/chat/newChatMessage";
import { updateAttributeStatus } from
"./channels/attribute/updateAttributeStatus";
import { documentRequest } from "./channels/document/documentRequest";
...
Which version of node is supported by Azure Functions and is import supported? If so, how do I set it up?
Thanks,
Donnie
According to the docs these versions are supported for V2:
Active LTS and Current Node.js versions (8.11.1 and 10.6.0
recommended). Set the version by using the
WEBSITE_NODE_DEFAULT_VERSION app setting.
So the node version has to be set in the Application Settings as explained here.
Regarding the use of import vs require, this is still an experimental feature in Node, therefore I don't think it's possible to use this in Azure Functions yet.
I'd probably go with TypeScript instead and transpile it before uploading (you can find some examples on how to get started with that on GitHub).

Using a Node.js class in Cloud Functions for Firebase

I am a new to Node.js and Firebase.
I have successfully tried to deploy some Cloud Functions to test them a bit.
I have a Node.js project in which I have a class defined as:
import * as Api from './api';
export default class MyClass {
constructor(props) {[...]}
someFunction(props) {
return Api.someOtherFunction(props.arg1).then([..]).catch([..]);
}
}
In the Api code I use the firebase admin SDK and I work with the real time database.Ex.:
ref.child(`users/${userId}`).set({
id: userId,
arg1: arg1,
arg2: arg2
});
Now, the problem is that I would like to use MyClass in a cloud function.
I have read a lot about ES6 in Cloud Functions, too (ex.: here), but I am not able to get rid of the error message
SyntaxError: Unexpected token import
I have tried to convert to require statements but I am not able to require my local module where MyClass is.
I don't care if it will be a Node.js local module or simply some classes in clear hierarchical structure.
What I would like to ask is if there is a specific documentation about this situation (I have searched a lot for it) and/or if I am following the right way to structure my project.
If the answer is "NO", please give me some tips on how to structure it.
Cloud Functions (node.js) currently does not support the ES6 import syntax, you have to use require().
The examples in the article you linked are using Babel to convert ES6 to ES5. Even if you convert your import statements to require() you're going to encounter the fact that ES5 does not support the class syntax. If you want to do what the article it doing, follow the steps to get Babel converting your ES6 script to ES5 before sending it to Firebase Cloud.

AWS Lambda function to connect to a Postgresql database

Does anyone know how I can connect to a PostgreSQL database through an AWS Lambda function. I searched it up online but I couldn't find anything about it. If you could tell me how to go about it that would be great.
If you can find something wrong with my code (node.js) that would be great otherwise can you tell me how to go about it?
exports.handler = (event, context, callback) => {
"use strict"
const pg = require('pg');
const connectionStr =
"postgres://username:password#host:port/db_name";
var client = new pg.Client(connectionStr);
client.connect(function(err){
if(err) {
callback(err)
}
callback(null, 'Connection established');
});
context.callbackWaitsForEmptyEventLoop = false;
};
The code throws an error:
cannot find module 'pg'
I wrote it directly on AWS Lambda and didn't upload anything if that makes a difference.
I wrote it directly on AWS Lambda and didn't upload anything if that makes a difference.
Yes this makes the difference! Lambda doesnt provide 3rd party libraries out of the box. As soon as you have a dependency on a 3rd party library you need to zip and upload your Lambda code manually or with the use of the API.
Fore more informations: Lambda Execution Environment and Available Libraries
You need to refer Creating a Deployment Package (Node.js)
Simple scenario – If your custom code requires only the AWS SDK library, then you can use the inline editor in the AWS Lambda console. Using the console, you can edit and upload your code to AWS Lambda. The console will zip up your code with the relevant configuration information into a deployment package that the Lambda service can run.
and
Advanced scenario – If you are writing code that uses other resources, such as a graphics library for image processing, or you want to use the AWS CLI instead of the console, you need to first create the Lambda function deployment package, and then use the console or the CLI to upload the package.
Your case like mine falls under Advanced scenario. So we need to create a deployment package and then upload it. Here what I did -
mkdir deployment
cd deployment
vi index.js
write your lambda code in this file. Make sure your handler name is index.handler when you create it.
npm install pg
You should see node_modules directory created in deployment directory which has multiple modules in it
Package the deployment directory into a zip file and upload to Lambda.
You should be good then
NOTE : npm install will install node modules in same directory under node_modules directory unless it sees a node_module directory in parent directory. To be same first do npm init followed by npm install to ensure modules are installed in same directory for deployment.

Serverless Framework with Azure functions

I am writing services with Serverless Framework & Azure Functions. Examples out there are very simple. But when I try to take a step further, I run into problem. Currently learning from AWS Lambda and then trying to implement it on Azure Functions.
The goal of doing so is:
1) Implement functions as es6 classes and then building the project with webpack.
2) Find a right project structure, which makes more sense.
3) Follow SoC pattern.
I have created a github project https://github.com/GeekOnGadgets/serverless-azure-settings and when I try to build this project serverless package it creates .serverless folder and inside it there is .zip file (the compiled version). Which I understand gets deployed to azure when you run serverless deploy. But when I check on Azure the function is just development code and not the compiled one (please refer to the code below).
Can someone please help with this. Any suggestions is appreciated.
import Settings from './src/Settings/Settings'
module.exports.settings = (event, context, callback) => {
let settings = new Settings();
const response = {
statusCode: 200,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(settings.dev()),
};
callback(null, response);
}
Indeed javascript azure functions run on nodejs so commonjs modules are the natural format. Node also natively supports much of ES6, though the Functions version of node might not be the latest.
however, there is a current speed issue with loading all the dependencies in node_modules. This is due to file access so a workaround exists to bundle everything into a single script which package.json -> main points to.
I cant comment on how that fits in with serverless, but perhaps this will help clarify.
As far as I know, Node.js still does not support import/export ES6 syntax for modules. See also here.
Try a new deploy changing from
import Settings from './src/Settings/Settings'
to
const Settings = require('./src/Settings/Settings')

Resources