Aws-cdk: [aws-lambda-nodejs] SyntaxError: Support for the experimental syntax 'decorators-legacy' isn't currently enabled

Created on 3 Jul 2020  路  15Comments  路  Source: aws/aws-cdk

Solution

{
  "presets": [
    "@babel/preset-typescript"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ]
  ]
}

Original Issue

As of 1.48.0, lambda functions with decorators are broken.

Error: Failed to run bundling Docker image for asset cognito/customMessage/Code/Stage: Error: [Status 1] stdout: Building custom-message.ts...

SyntaxError: Support for the experimental syntax 'decorators-legacy' isn't currently enabled

Reproduction Steps

If it's not a repro, what the hell is repro?

  • custom-message.ts
import * as lambda from 'aws-lambda'
import { boundMethod } from 'autobind-decorator'

type TEvent = lambda.CognitoUserPoolTriggerEvent

/**
 * [UserPool Lambda Triggers](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-message.html)
 */
class CustomMessageHandler {
  constructor(/* ...dependencies */) {
    // ...
  }

  @boundMethod
  public async handle(event: TEvent): Promise<TEvent> {
    switch (event.triggerSource) {
      case 'CustomMessage_SignUp':
        return this.handleSignUp(event)
      case 'CustomMessage_ResendCode':
        return this.handleResendCode(event)
      case 'CustomMessage_ForgotPassword':
        return this.handleForgotPassword(event)
      default:
        throw new Error('Unhandled Trigger')
    }
  }

  ...

  @boundMethod
  protected async handleForgotPassword(event: TEvent): Promise<TEvent> {
    const givenName = event.request.userAttributes['given_name']
    const familyName = event.request.userAttributes['family_name']

    event.response = {
      ...event.response,
      emailSubject: 'Confirmation Code for Forgot Password',
      emailMessage: `
      <div>
        <p>Dear ${givenName} ${familyName},</p>
        <br/>
        <p>Confirmation Code is:</p>
        <p>${event.request.codeParameter}</p>
        <br/>
        <p>Thank you!</p>
      </div>
      `,
    }
    return event
  }
}

export const handle = new CustomMessageHandler(/* ...dependencies */).handle
  • stack.ts
import * as cognito from '@aws-cdk/aws-cognito'
import * as lambda from '@aws-cdk/aws-lambda-nodejs'
import * as path from 'path'

const userPool = new cognito.UserPool(this, 'userPool', {
  ...,
  lambdaTriggers: {
    customMessage: new lambda.NodejsFunction(this, 'customMessage', {
      entry: path.resolve(__dirname, 'custom-message.ts'),
      handler: 'handle',
    }),
  },
}

Error Log

$ cdk synth

Error: Failed to run bundling Docker image for asset cognito/customMessage/Code/Stage: Error: [Status 1] stdout: Building custom-message.ts...
馃毃 Build failed.


stderr: @parcel/transformer-babel: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (11:3):
SyntaxError: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (11:3):
    at Object._raise (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:757:17)
    at Object.raiseWithData (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:750:17)
    at Object.expectOnePlugin (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:8849:18)
    at Object.parseDecorator (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11385:10)
    at /usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11995:32
    at Object.withTopicForbiddingContext (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11078:14)
    at Object.parseClassBody (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11984:10)
    at Object.parseClass (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11958:22)
    at Object.parseStatementContent (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:11245:21)
    at Object.parseStatementContent (/usr/local/share/.config/yarn/global/node_modules/@babel/parser/lib/index.js:6585:18)
/asset-input/packages/.../lib/cognito/custom-message.ts:11:2
  10 | class CustomMessageHandler {
> 11 |   @boundMethod
>    |  ^
  12 |   public async handle(event: TEvent): Promise<TEvent> {
  13 |     switch (event.triggerSource) {
    at AssetStaging.bundle (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/core/lib/asset-staging.ts:182:13)
    at new AssetStaging (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/core/lib/asset-staging.ts:92:29)
    at new Asset (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/aws-s3-assets/lib/asset.ts:117:21)
    at AssetCode.bind (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/aws-lambda/lib/code.ts:180:20)
    at new Function (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/aws-lambda/lib/function.ts:502:29)
    at new NodejsFunction (/Users/civilizeddev/GitHub/.../node_modules/@aws-cdk/aws-lambda-nodejs/lib/function.ts:62:7)
    at CognitoStack.get userPool (/Users/civilizeddev/GitHub/.../lib/cognito/index.ts:23:24)
Subprocess exited with error 1
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Environment

  • CLI Version : aws-cli/2.0.27 Python/3.8.3 Darwin/19.5.0 botocore/2.0.0dev31
  • Framework Version: 1.49.1, 1.49.0, 1.48.0
  • Node.js Version: 14.5.0
  • OS : macos 10.15.5
  • Language (Version): TypeScript (3.9.6)

Other


This is :bug: Bug Report

@aws-cdaws-lambda-nodejs bug

Most helpful comment

@civilizeddev I won't go about your rude comments and false accusations here...

If it's not a repro, what the hell is repro?

This is a repro: https://github.com/jogold/decorator-cdk. Did this out of personal curiosity and because I do care about the NodejsFunction construct being functional and offering a good developer experience (even though the discussion here didn't make me want to do it). And luckily for you it works with decorators and a Babel config.

My feedbacks as a user were ignored by you second time #8181

Don't know what you're talking about... you opened the issue and I almost immediately asked for clarification in order to fix it at some point. Not fixing it as fast as you would like it doesn't mean ignoring it... Again, it's not my job, I devote part of my free time to it, this is how open source works...

I hope we can return to a more respectful discussion.

All 15 comments

Please help me @jogold

Looks like you need the right babel plugin and config (.babelrc) to support decorators.

Not really something for the NodejsFunction construct.

I have been using it without any extra configuration.

We now use Parcel v2... can you try to see if it works with a proper Babel config?

No luck.

  "babel": {
    "presets": [
      "@parcel/babel-preset-env",
      "@babel/preset-typescript"
    ],
    "plugins": [
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ],
      [
        "@babel/plugin-proposal-class-properties",
        {
          "loose": true
        }
      ]
    ]
  },
  "cdk-lambda": "/asset-output/index.js",
  "targets": {
    "cdk-lambda": {
      "context": "node",
      "includeNodeModules": {
        "aws-sdk": false
      },
      "sourceMap": false,
      "minify": false,
      "engines": {
        "node": ">= 12"
      }
    }
  },
  "devDependencies": {
    "@parcel/babel-preset-env": "^2.0.0-alpha.3",
    "@babel/preset-typescript": "^7.10.4",
    "@babel/plugin-proposal-decorators": "^7.10.4",
    "@babel/plugin-proposal-class-properties": "^7.10.4"
  }

I will give up using it in this terrible configuration.

If you can get it to build with Parcel v2 then it should work with the NodejsFunction construct. This is more something for https://github.com/parcel-bundler/parcel or StackOverflow.

Really?

I want you to pay more attention to end user experience on your work.

I hope you wouldn't think that I'm the just one having trouble with this.

I don't want to blame on you even though I wasted all day because of this. (What the hell with parcel2?)

I just want to get this fixed.

Can you share a minimal repro of the problem in a repo? I will try to have a look at it to see if the issue comes from CDK or Parcel.

You didn't catch the point.

Just Imagine a user facing a breaking change and how he feels like.

If I were you, I wouldn't say 'it's not my job.'

Just Imagine a user facing a breaking change and how he feels like.

Of course I understand this frustration

I want you to pay more attention to end user experience on your work.

I think that all my contributions to the CDK prove that I attach a lot of importance to this... the whole point of the NodejsFunction construct is to offer the best possible developer experience.

If I were you, I wouldn't say 'it's not my job.'

Never said that... just think is not CDK related. Anyway, I spend a lot of my free time here...

I'm not resentful... if you still want me to have a look please provide a repro.

You just do what you want to do, and that's it.

You don't like to listen to the user's opinion.

My feedbacks as a user were ignored by you second time #8181

I won't force you anymore if you don't want to.

@civilizeddev I won't go about your rude comments and false accusations here...

If it's not a repro, what the hell is repro?

This is a repro: https://github.com/jogold/decorator-cdk. Did this out of personal curiosity and because I do care about the NodejsFunction construct being functional and offering a good developer experience (even though the discussion here didn't make me want to do it). And luckily for you it works with decorators and a Babel config.

My feedbacks as a user were ignored by you second time #8181

Don't know what you're talking about... you opened the issue and I almost immediately asked for clarification in order to fix it at some point. Not fixing it as fast as you would like it doesn't mean ignoring it... Again, it's not my job, I devote part of my free time to it, this is how open source works...

I hope we can return to a more respectful discussion.

I apologize.

Thank you for your effort. @jogold

Just give me a good review in my work later.

@jogold thanks so much for looking at this.

Just to summarize, is this the Config that worked?

{
  "presets": [
    "@babel/preset-typescript"
  ],
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "legacy": true
      }
    ]
  ]
}

Just to summarize, is this the Config that worked?

Yes, exactly.

Was this page helpful?
0 / 5 - 0 ratings