Hi All I m working on g…

11 minute read

Hi All! I’m working on getting some serverless apps up and running in my nx repo. I’ve tried many different things to differing degress of success. I just need to create nodejs lambda functions using the serverless framework and be able to all the cool serverless framework stuff. Right now I have a “master” serverless.yml in the root of my workspace and when it builds the zip file to deploy it’s including all the dependencies in the root package.json.

Is there a way to prevent this or am I going to need to just drop down into a folder like apps/serverless and do all the serverless stuff from there?


Have you tried <https://www.npmjs.com/package/@flowaccount/nx-serverless? https://www.npmjs.com/package/@flowaccount/nx-serverless?> Written by

Yeah I was having issues with this. I don’t remember what any more. I can try again :slightly_smiling_face:

There is also nx-deploy-it <https://www.npmjs.com/package/@dev-thought/nx-deploy-it https://www.npmjs.com/package/@dev-thought/nx-deploy-it>


OK, I made good progress with nx-serverless. Just a different paradigm than I’ve been used to with using the sls cli.

One thing I haven’t figured out is now to invoke locally and feed it an event.json file

sls invoke local -f my-lambda -p event.json

something like that

, good morning :slightly_smiling_face: … glad you found some time looking at it, For the nx-serverless i have added an offline builder or if its just a node application, you can run it with nx serve &lt;app-name&gt; it is a wrapper for serverless-offline

in angular.json you can find the processEnvironmetFile parameter under the build section of the architect. You can specify the env.json file for your serverless application. It can be separated with the build configuration as usual like staging or production and the default is local

it will populate your environmentvariables in, run offline on port 7777 as default, you can change by specifying the port as parameter or configuration in the serve section

this should help you test the lambda invoke effect……

for the angular application that you want to deploy to lambda instead of serve you will have to use nx run app-name:offline instead and it does the typescript compile instead of webpack build

let me know which scenario you want to work with and would be glad to support, help out :smile: i want to add more features for GCP Azure but since covid-19 hit, i have been doing only business features lol

Thanks for the help! I’m working on it now. I’ll let you know how it works out and what things I run into.

At first glance, one thing that would be nice is to have all the sls cli commands available from the root. I have no idea how that would work yet or how difficult it would be though :slightly_smiling_face:

Hmm from what I understand its about setting the servicepath and the config file for the command to run in root path with designated projects, the reason i wrapped it is because • without these parameters it always create .serverless in the root • Cannot build before running sls command without wrapping it, have to rely on its plugin instead which have a lot of obscure behaviors when running in monorepo

What could be done should be • expose all commands through the wrapper without specifics • This should be easy since inside i am just initiaing it and setting a static command, do you thibk thays a good idea? Will create an issue and implement it in a jiffy :)

What do you mean “without specifics”?

Do you mean no sls command flags can be used or all of them can be used because you’re not setting a specific one?

Another thing I’ve found is that it doesn’t seem to respect the excludes in the serverless.yml file. It’s packaging everything and uploading it. When I run ng deploy I get a .zip file of 8.9MB. With sls package in the app folder the .zip is 4k.

• without specifics, means at the moment it’s specified so all commands and flags should go through • atm its writing its own package.json, skipping the plugin, i will open an issue and add in the exclude for node_modules :) would be great if you have a sample yml!

Here is a sample yml with the excludes ```service: hello-world frameworkVersion: “>=1.1.0 <2.0.0” plugins:

  • serverless-offline package: individually: true excludeDevDependencies: true exclude:
    • src/** include:
    • src/function/handler.js custom: enable_optimize: local: false provider: name: aws runtime: nodejs12.x stage: ${opt:stage, ‘dev’} functions: config: handler: src/handler.hello```

“without specifics, means at the moment it’s specified so all commands and flags should go through” awesome. I’ll try some things

Sure i will be up tonight so can chat along

The exclude, it excludes all the src files? Meaning dont compile them only the handler.hello

Or r I meaning the excludedevdependencies

I see what you did there….can i see the handler.js file?

Hey i dig into it a bit and saw that The exclude and include works similar to how tsconfig file would, Since i am building the app using webpack i think i can add the parameters in and make it work similar to how serverless would do it

For the sls part, best if i add an arg array to pass in any command!

You can checkout some changes in the pull request

Just finished with some scully stuff today will continue on tomorrow cheers :)

cool. sorry I missed your messaged earlier

do you still need to see the handler?

It’s super simple: ```import * as AWS from ‘aws-sdk’;

AWS.config.update({ region: ‘us-east-1’ }); const dynamoDb = new AWS.DynamoDB({ apiVersion: ‘2012-08-10’ });

interface ConfigRequest { table: string; id: string; field: string; ping: boolean; }

export const config = (event: ConfigRequest) => { if (event.ping) { return {}; } else { const params = { TableName: event.table, Key: { id: { S: event.id }, }, ProjectionExpression: event.field, };

return dynamoDb
  .then((res) =&gt; {
    return res;
  .catch((err) =&gt; err);   } };```


no worries, i am on today as well, maintaining system :slightly_smiling_face: … Was super sleepy last night and fiddling a lot with scully… I figured out that its the same as tsconfig files property and exclude property. I just have to find a way to seave it in,

I am preping the repo for a publish at the momment, probably will put it in and test it out…..might be by tomorrow late evening if thats not too late! :smile:

no worries at all. thanks for looking into it!

would be nice to have as well :smile: cheers …

are you developing in typescript? i see you include the file in .js in the yml

yes I’m using ts. I might have forgotten to change that in the yml :slightly_smiling_face:

also if you can send the dist package.json and the size of build output

reason for asking silly question is • In the plugin, i am not relying on serverless build mechanisms and it’s typescript or webpack plugin anymore because of its complexity • I am building using angular-webpack, bundle the script then use its stats to build package.json so i am thinking i will consolidae the tsconfig file before passing it into webpack then the excludes should work • the third question i have always have is, what dependencies i can ignore when building to lambda, like aws-sdk can i always exclude that, hence the package.json example :smile:

for the work-around at the moment, you can also use the files property, include property and exclude property in your tsconfig and run the deploy command again. It should work right away? And consolidating is a good solution to have so its more seamless

anyways, good night man, will get to it tomz :slightly_smiling_face:

cool. I’ll try the files section in the tsconfig.

Here is the package.json { "name": "my-nx-workspace", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "nx": "nx", "start": "ng serve", "build": "ng build", "build-prod": "ng build --prod --project=default-project", "test": "ng test", "lint": "nx workspace-lint &amp;&amp; ng lint", "e2e": "ng e2e", "affected:apps": "nx affected:apps", "affected:libs": "nx affected:libs", "affected:build": "nx affected:build", "affected:e2e": "nx affected:e2e", "affected:test": "nx affected:test", "affected:lint": "nx affected:lint", "affected:dep-graph": "nx affected:dep-graph", "affected": "nx affected", "format": "nx format:write", "format:write": "nx format:write", "format:check": "nx format:check", "update": "ng update @nrwl/workspace", "update:check": "ng update", "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", "api:dev": "./start-api.sh Development", "postinstall": "ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", "storybook": "ng run shared-storybook:storybook" }, "private": true, "dependencies": { "@angular/animations": "~9.1.0", "@angular/cdk": "~9.2.0", "@angular/common": "~9.1.0", "@angular/compiler": "~9.1.0", "@angular/core": "~9.1.0", "@angular/flex-layout": "^9.0.0-beta.29", "@angular/forms": "~9.1.0", "@angular/material": "^9.2.0", "@angular/platform-browser": "~9.1.0", "@angular/platform-browser-dynamic": "~9.1.0", "@angular/router": "~9.1.0", "@fortawesome/angular-fontawesome": "^0.6.1", "@fortawesome/fontawesome-svg-core": "^1.2.28", "@fortawesome/pro-duotone-svg-icons": "^5.13.0", "@fortawesome/pro-solid-svg-icons": "^5.13.0", "@nrwl/angular": "9.2.2", "angular2-text-mask": "^9.0.0", "core-js": "^3.6.5", "date-fns": "^2.12.0", "jwt-decode": "^2.2.0", "rxjs": "~6.5.5", "serverless-plugin-warmup": "^4.9.0", "tslib": "^1.11.1", "zone.js": "^0.10.3" }, "devDependencies": { "@angular-devkit/build-angular": "~0.901.0", "@angular/cli": "~9.1.0", "@angular/compiler-cli": "~9.1.0", "@angular/language-service": "~9.1.0", "@babel/core": "7.8.3", "@flowaccount/nx-serverless": "*", "@nrwl/cypress": "^9.2.2", "@nrwl/jest": "9.2.2", "@nrwl/storybook": "^9.2.4", "@nrwl/workspace": "9.2.2", "@storybook/addon-actions": "^5.3.18", "@storybook/addon-knobs": "^5.3.9", "@storybook/angular": "^5.3.9", "@storybook/react": "5.3.9", "@types/aws-lambda": "^8.10.40", "@types/jest": "^25.2.1", "@types/node": "^13.11.1", "babel-loader": "8.0.6", "codelyzer": "^5.2.2", "cypress": "^4.3.0", "dotenv": "^8.2.0", "eslint": "^6.8.0", "jest": "^25.3.0", "jest-preset-angular": "^8.1.3", "prettier": "^2.0.4", "serverless": "1.58.0", "serverless-offline": "^5.12.1", "storybook-addon-designs": "^5.2.1", "ts-jest": "^25.3.1", "ts-node": "^8.8.2", "tslint": "^6.1.1", "typescript": "~3.8.3" } }

So if you’re not relying on the serverless build stuff is there a need for serverless at all?

the serverless helps compiles the cloud-formation template and deploys the stacks onto aws, the infrastrcture part

I also mean the package.json that is written into the dist/app/ folder, when you run deploy it will produce one minimal package.json which is compiled from either dep-check or webpack stats

it looks like it’s just not excluding the aws-sdk

Here’s the final package.json { "name": "smartshopper-config", "version": "1.0.0", "description": "Packaged externals for smartshopper-config", "private": true, "scripts": { "package-yarn": "yarn", "package-npm": "npm install" }, "dependencies": { "aws-sdk": "*" } }

I looked at the node modules and they’re all deps of aws-sdk

Ok so from what i see in handler file, i am not sure whats the ‘AWS.config.update’ is for if just to set the region for deployment you can do that in ‘env.json’ specifying the ‘region’ property and you would not need the import then it wont be bundle

And usually when importing aws libs in typescript it should be specifics like ‘@aws/lambda’ Etc.

It was some good feedback which is in the doing, i hope to get the sls working this week and also see to how seamless we can integrate the yml tags :)

<https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html>

According to this the sdk is already in the runtime, so best to import the typings instead :)

cool. I’ll check it out. Thanks!

“And usually when importing aws libs in typescript it should be specifics like ‘@aws/lambda’” Do you have an example of this with aws? I’m not finding any @aws/* things at all.

Oh, and we’re also using dynamodb and need to import the sdk for that. ```import * as AWS from ‘aws-sdk’;

const dynamoDb = new AWS.DynamoDB({ apiVersion: ‘2012-08-10’ });```

you are absolutely correct and whast aws lambda without dynamodb! … I think the best way out is force remove the dependecny when pacakging. I will test that out and get back to you! That will save us internally as well!

Awesome conversation :smile:

sweet thanks!

I can bring all these things to you when I encounter them. Thanks for working with me on it. :slightly_smiling_face:

most welcome :smile: ..please do .. it does help improve the workflow and the lib. Hope it helped you somewhere :slightly_smiling_face:

It has definitely helped! Thanks!

Do let me know when you think you’ve got the removing of dependencies working.

yes, thats currently next on the task list :smile:

having a SEO nightmare …

hi i created an issue and have some questions maybe we can clarify them … https://github.com/flowaccount/nx-plugins/issues/18

Hi i fixed the issue and added sls command as well. Writing some tests nd will publish in a day or so


I’ll try it out as soon as it’s published


Mean time i figured you can ass aws-sdk to your devDependencies and it automatically ignores when deploying

Will publish and update u! Cheers

just released 0.5.0, hope it fixes the issue. Also it forces exclude aws-sdk now. And can use sls as well

thankz for being patience :smile:

Thanks! I’ll give it a go today or tomorrow.

Sorry it took so long. Things have been crazy and I was traveling last week. So far this looks great! Thanks!

My zip file is now 28k rather than 8.9MB


That’s fantastic


I’ll let you know what else I run across as I move forward.

glad you figured it out!!!

one question so far, How exactly do I use the sls command. From root dir? from app dir?

asking for a friend :wink:

"sls": { "builder": "@flowaccount/nx-serverless:sls", "options": { "buildTarget": "api-lambda.customer-notes:build:production", "config": "apps/api/lambda.customer-notes/serverless.yml", "location": "dist/apps/api/lambda.customer-notes", "package": "dist/apps/api/lambda.customer-notes", "command": "package" }, "configurations": { "dev": { "buildTarget": "api-lambda.customer-notes:build:dev" }, "production": { "buildTarget": "api-lambda.customer-notes:build:production" } } }

here is an example config

its in the updated readme as well …


Ah now I see it in the readme. I looked for it earlier but missed it.

so this essentially uses nx run commands?

naah, not for this wrapper, i initialize the serverless instance and pass in the configurations through objects

i did not discover the magic of nx-commands back then, but since its working so i am leaving as is, there is one more bugs of including files inside the YML which i will be getting to next :slightly_smiling_face:

Also i had to switch the serverless.config.servicePath between the build and deploy process … so it follows the nx workspace structure

with command line i think it will be difficult to do so