Feature Proposal: Jovo typescript build with webpack for serverless (AWS)


#1

Feature Proposal: Conversational Components

In the last couple of weeks, I’ve experimented a lot with AWS serverless and with the serverless framework. I really love this approach and I would like to bring it to Jovo.

In my mind, I would like to create something that reduces the final bundle size (at the moment is more than 17mb with my project) and automates the deployment with serverless (Jovo CLI is doing a good thing but it’s not enough).

I’ve created a GitHub repo to test it out: https://github.com/StErMi/jovo-serverless-webpack/blob/master/serverless.yml

Option 1: serverless-bundle

One option would be to use serverless-bundle (look at the beta tree, they are adding the support to typescript). This serverless plugin is an extension of the serverless-webpack plugin. It bundles your Node.js Lambda functions with sensible defaults so you don’t have to maintain your own Webpack configs.

Issues

I still need to figure out why the output build is not working correctly. All the deployment process works like a charm, so as soon as we fixed it’s ready for production.

Option 2: ncc

Today I’ve exchanged some email with @jsmith6690 and suggested me to use ncc. This library compiles a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.

Issues

I still need to finish the final pipeline to deploy the code to the lambda.

Problems and TODO

serverless-bundle VS ncc

I’m not an expert on those tools so I don’t know which one has a better-optimized code in the final bundle. We should evaluate all the options but to be honest I would like to use something that is more deeply into the serverless framework pipeline. Or we could just create a serverless-ncc plugin to solve the issue if we think that we should use ncc.

Config

One common problem is how Jovo handles env config. They require the configuration to be at the same level of the index. It’s a problem because webpack/ncc uses tree shaking and they are not transpiling and packaging those files because they are not required anywhere.

Local Test

I would like to allow the current Jovo Web debugger to run on the compiled code.

Add support to DynamoDB in the serverless build

This is not a huge issue, I just need time to add it to the configuration


#2

Thanks a lot for this @StErMi! Will share more thoughts later, but first wanted to share an interesting LinkedIn post by @jsmith6690 about using ncc and other things to reduce the bundle size.


#3

My thoughts
This is a great discussion to have. I’ve had great success building an deploying with ncc. However, since serverless is a popular framework that fits well with the voice ecosystem, my take is:

  1. In a “plain” jovo experience, use ncc under-the-hood.
  2. In a serverless “managed” experience, prefer serverless bundle…“don’t fight the framework principle”.

I don’t have a good sense right now of how jovo projects are interacting with serverless. Are folks just using the serverless cli to create the gateway and deploy? If so, it would make integration easier.

I will try to create a proof-of-concept jovo cli pr this weekend for ncc bundle user; obviously it will be experimental, as there are lots of corner cases with voice.

Outline of using ncc in Jovo today
If you want to try ncc today, these are the steps to follow.

Build & Run

From project root:

  1. run tsc or tscw over src/**/*
  2. ncc ./src/index.ts -o ncc-build // works on *.js files as well!
  3. copy ./dist/config.js ./ncc-build // as Emanuel said, you have to manually copy config.ts
  4. cd ./ncc-build
  5. node ./index.js --webhook // no need for this in a Lambda setting

Package & Deploy

From project root:

  1. cd ./ncc-build && zip -r ../ncc-build.zip * && cd .. // probably a cleaner way to zip it!
  2. aws lambda update-function-code --function-name <lambda-func-name> --zip-file fileb://ncc-bundle.zip --profile <aws-profile>

One thing for the Jovo team to consider is an experimental version of Jovo where config.ts can be included in the build. Since we need it at run-time, I feel as though it makes sense to just include in the project instead of a stand-alone file.


#4

Awesome!

I haven’t worked with webpack and serverless a lot so far. I also haven’t tried ncc yet. But I’m willing to learn :slight_smile:

One thing for the Jovo team to consider is an experimental version of Jovo where config.ts can be included in the build. Since we need it at run-time, I feel as though it makes sense to just include in the project instead of a stand-alone file.

Do you have something in mind?

This should work with "esModuleInterop": "true"

import config from './config';
const app = new App(config);

#5

Wow. Just tried ncc. This is really cool.

It reduced the bundle size of the plain hello-world template from 2470 kb to 423 kb

It seems to work with. I didn’t have to move the config.js from /dist to /ncc-build

import config from './config';
const app = new App(config);

I have to make more tests on this. I just ran a LAUNCH request…


#6

Hi Alex, how this approach would work with env config? Does it automatically embed the correct config based on the env stage value?

Another cool improvement (because of tree shaking) would be to have a dev index and a prod index because I think that at the moment in the final build Express will be present because of how the current index.ts is made.


#7

I like the idea of having serverless be the way to deploy a lambda instead of (or as an addtional option to) the current jovo deploy -t lambda. Also like the idea of webpack and tree shaking for smaller Lambda sizes.

Other things to consider are:

  1. Lambda - want to be able to deploy the same lambda to regions: Default, North America, Europe & India, and Far East.
    What to do about lambda versions and aliases and configured endpoints?
    Also, want an option to deploy .env values as envrionment variables with the lambda but no overwrite existing env vars for the lambda.

  2. API Gateway - ability to deploy an API Gateway for use by Google Actions and Bixby Capsules. Use newer HTTP APIs instead of original REST APIs.

  3. DynamoDB - ability to specify the creation of the DynamoDB table. Standard users table or single-table approach.

  4. S3 - A public bucket for icons, images, and audio files. Sets up CORS access. Optional CloudFront CDN creation.

Integrate with project.js, config.js, and stages.


#8

Tomorrow I will provide a working Jovo example with NCC and Jovo deployable on your lambda + API gateway for Google Assistant. As far as I get NCC is using a webpack under the hood.

I still need to understand which would be a better fit between serverless-bundle and raw NCC for a better output. I could think to also create a serverless-ncc plugin or evaluate something already out there.


#9

What you are asking for is already supported by the serverless framework :wink:
I don’t know if they currently override env variables you din’t provide with the yml configuration but it should work like a charm.


#10

I know that it is supported in serverless which I have used some outside of Jovo app deployment. Just want to get a wish list out there. Especially looking for integration with config.js and project.js values and multiple lambda deployment to handle deployment to different counties.

Thank you!


#11

@jan @AlexSwe I’ve got another problem :frowning:

With NCC JSON files are not included in the build (as far as I know) and so Jovo is failing to load them. Would it be possible to include them in another way?


#12

In which specific case do you need JSON files? i18n?


#13

At the moment the problem is the i18n file yes. I’ve already filed an issue on NCC but I don’t know when and how it will be handled.


#14

Can you confirm the problem persists when you add the following lines to compilerOptions in your tsconfig.json

"resolveJsonModule": true,
"esModuleInterop": true

#15

Hi, @jsmith6690 those options were already true before the issue because all my projects are already TS native. NCC is (at least as far as I can see) ignoring them anyway and I think that’s the same issue as the config.ts.

You should force them because they are not actively used inside the code (but required passively by Jovo) so tree shaking mechanism are not importing them in the final build.


#16

Hi @StErMi,

did you manage to sort out the nnc issues?
I have a working serverless build flow so i can contribute there if you like.

Best,
Dominik.


#17

On a side note: I did not manage to get my project compiled with webpack.

There were several issues like these:

WARNING in ./node_modules/jovo-platform-alexa/dist/src/core/AlexaRequestBuilder.js 97:43-90
Critical dependency: the request of a dependency is an expression
 @ ./node_modules/jovo-platform-alexa/dist/src/index.js
 @ ./src/app.js
 @ ./src/index.js
 @ multi ./src/index.js

I am no webpack expert so i dont know how to solve these.