Skip to content

ES2015 Deployed Code Crashes -- Optimizer not observing strict mode #19

Open

Description

@n8sabes

The serverless-optimizer-plugin does not appear to be observing 'use strict’; Thus, not defining a variable with var is ignored and when the code is deployed, it crashes in the Lambda environment.

To reproduce this issue:

1). Setup fresh project with a single component and function.

  1. Add the optimizer for es6 as outlined in readme.
    "custom": {
        "optimize": {
            "exclude": [
                "aws-sdk"
            ],
            "includePaths": [
            ],
            "transforms": [
                {
                    "name": "babelify",
                    "opts": {
                        "presets": [
                            "es2015"
                        ]
                    }
                }
            ]
        }
    }
  1. Make sure 'use strict;' is at the top of the function file.

  2. Add the following line to the function handler

foo = 1;
  1. Deploy and run function in AWS Lambda environment.

sls function run component/function -s dev

Check CloudWatch for Crash ReferenceError: foo is not defined.*

  1. Add var ahead of the variable:
var foo = 1;
  1. Deploy and run function again.

sls function run [path]

Works fine now.

Serverless deployment process should catch this error (due to strict mode) and fail. Not catching these errors results in unstable code being deployed that is out of spec.

If possible, adding babel-plugin-transform-strict-mode might help. How can this plugin be added to the optimizer json? It really shouldn't be required when strict is declared at the top of the file, but it would be nice to know how to include plugins for babel.

Activity

  1. staceymoore commented on Feb 16, 2016

    @staceymoore
    Contributor

    @n8sabes try adding babel-plugin-transform-strict-mode to the transforms array in the same manner as babelify (see below for example and add opts if needed). That's what I did with my coffeeify transform and it worked fine. Be sure to install/save the package in the root node_modules of your sls project. Hope that helps.

    "custom": {
            "optimize": {
                "exclude": [
                    "aws-sdk"
                ],
                "includePaths": [
                ],
                "transforms": [
                    {
                        "name": "babelify",
                        "opts": {
                            "presets": [
                                "es2015"
                            ]
                        }
                    },
                    {
                        "name": "babel-plugin-transform-strict-mode"
                    }
                ]
            }
        }
    
  2. n8sabes commented on Feb 16, 2016

    @n8sabes
    Author

    Thanks @staceymoore. I added the package to the project root and included the plugin to the transforms. Still no love, getting the following error with --debug option and not finding a good solution example (some gulp references). Did you configure or install anything else?

    Serverless: | /Users/username/project/node_modules/serverless-optimizer-plugin/node_modules/browserify/node_modules/readable-stream/lib/_stream_readable.js:535
    dest.on('unpipe', onunpipe);
    ^
    
    TypeError: dest.on is not a function
    at DestroyableTransform.Readable.pipe (/Users/username/project/node_modules/serverless-optimizer-plugin/node_modules/browserify/node_modules/readable-stream/lib/_stream_readable.js:535:8)
    
  3. joostfarla commented on Feb 19, 2016

    @joostfarla
    Contributor

    Browserify doesn't seem to care about these kind of syntactic errors, at least it doesn't fail during the bundling process. However, it DOES include the "use strict" statement in the bundled package.

    Some things you could do:

    • Test the function using function run to find potential errors before deploying.
    • Use my brand new JSHint plugin to lint your code before deploying. This will also prevent you from deploying ES6 syntax by accident. 😄
  4. n8sabes commented on Feb 20, 2016

    @n8sabes
    Author

    Hey @joostfarla -- Thanks for the conversation on the problem, and for your time looking at it.

    Option 1: function run is not really practical because it requires 100% code coverage on execution to catch syntactic errors such as missing var. I have developed unit tests which are close to 100% code coverage, but sadly don't have every edge case. I also have the linter in WebStorm enabled so I can visually see syntactic errors, but this too is error prone for reliable deployments.

    Options 2: Your new JSHint plugin is a MUCH better idea to prevent bad deployments. Excited to try it and will let you know the outcome!

    @staceymoore, thanks to you for your help on this topic as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions