Workflow for Typescript with Jest

Hello,

I have a pretty straightforward pipeline to do the following:
Checkout branch → run jest tests → package → deploy to AWS lambda staging → manual approval → deploy to AWS lambda production

My question is about best practices or other usecases that would fit this scenario regarding the following:

The package I deploy to lambda should be production only, without the devDependencies, but I need to run the tests before.

What is the best approach? Save into the workspace the node_modules fully, and to generate the package I do a prune before zipping the package file?

Could someone share some references or examples that would fit this better?

Hey @hctizi ,

There are definitely a few different options but it can depend on a few things, especially such as which framework you are working with.

Ignoring the fact it is a lamda for simplicity, your package.json should include a script for both testing a building for production.

example:

"scripts": {
    "test": "jest",
    "lint": "npx eslint --fix --ext .js,.jsx,.ts,.tsx .",
    "build": "npm run lint && npx webpack",
  },

In this example, webpack is configured to output our packaged code to /dist as directed by webpack.config.ts, and you can build the production version of your orb via npm run build.

In this case if you were to publish, you would be packaging/publishing only the content in your /dist directory which should ideally only contain a single .js file.

If you can share more about your project and the specifics of the issues you are facing we might be able to dive a little deeper.

Since you are talking about Lambda it might be a little different, especially if you are using the Serverless Framework or AWS’s SAM Serverless Framework.

Hi @KyleTryon ,

Thanks for the response. As I’m working with typescript + jest for a lambda deployment without the serverless framework and also webpack (takes too long), I have to do things manually.

Bsically what I do is:

  • install
  • run linter
  • run ci tests (jest)
  • pack (this part I have some questions)
  • deploy staging
  • hold for approval
  • deploy production

Basically, on the pack part, I’m copying the package.json to a different folder, installing only production packages (npm i --production) and the rest is pretty straightforward.
As I’m using save_cache/node_modules, I was thinking if there is another approach that is more intelligent regarding CircleCI (like pruning to production instead of reinstalling everything from node_modules, as I need to zip it (only production packages) to send for AWS Lambda in this job “pack”.

Can you give me some insights? I can attach the current config if it helps, but basically the structure is like I’ve described above. The critical parts are below:

install part and pack part (in this I need to save a lambda.zip with the compiled code + node_modules with only production packages):

Thanks!

I would recommend breaking this out into two separate jobs. One job for testing, another for deploying.

This way you aren’t copying anything, you are just running the job two times, but one for production and one for testing.

You can then also do things like have a workflow that tests on every commit, but builds and deploys on your main branch.

Check out the Node orb, it handles caching automatically too.
https://circleci.com/developer/orbs/orb/circleci/node

version: '2.1'
orbs:
   node: circleci/node@4.2
jobs:
  deploy:
    executor: node/default
    steps:
      - checkout
// handles cache automatically
      - node/install-packages:
          override-ci-command: npm i --production
      - run: Some Commands Here
workflows:
  test-and-deploy:
    jobs:
// Should work out of the box, cache is automatic
      - node/test
// deploy runs after test and only on the main branch
      - deploy:
          requires:
            - node/test
          filters:
            branches:
              only: main