serverless-heaven / serverless-webpack

Serverless plugin to bundle your lambdas with Webpack

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Path error with SLS 1.18 when package individually is set

kikar opened this issue · comments

commented

This is a Bug Report

Description

I have a few services in the same project, so I made a script to gather the and deploy them one by one. On my machine everything goes fine, but when I run it on AWS CodeBuild, our CI, it fails.

projects.forEach(project => {
  console.info('Deploying', project);
  child_process.exec(`sls deploy`, { cwd: join(srcFolder, project) }, (err, stdout, stderr) => {
    if (err) {
      console.log('Error!', err);
    } else {
      console.log('STDOUT:', stdout);
      console.log('STDERR:', stderr);
      console.info('Finished', project);
    }
  });
});

And here is the error:

TypeError: Path must be a string. Received undefined
at assertPath (path.js:7:11)
at Object.basename (path.js:1357:5)
at functionNames.forEach.name (/codebuild/output/src838467009/src/node_modules/serverless-webpack/lib/cleanup.js:27:28)
at Array.forEach (native)
at fse.copy (/codebuild/output/src838467009/src/node_modules/serverless-webpack/lib/cleanup.js:23:31)
at doneOne (/codebuild/output/src838467009/src/node_modules/fs-extra/lib/copy/ncp.js:237:40)
at /codebuild/output/src838467009/src/node_modules/fs-extra/lib/copy/ncp.js:122:11
at /codebuild/output/src838467009/src/node_modules/graceful-fs/polyfills.js:239:18
at FSReqWrap.oncomplete (fs.js:123:15)

at ChildProcess.exithandler (child_process.js:202:12)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:852:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5) killed: false, code: 1, signal: null, cmd: 'sls deploy' }
  • Serverless-Webpack Version you're using: ^2.0.0
  • Webpack version you're using: ^3.3.0
  • Serverless Framework Version you're using: ^1.17.0
  • Operating System: Should be Ubuntu

Hi @kikar . Thanks for the report 👍 . Does this only happen when you try to run the "batched" deployments with the for loop, or does it also happen if you try to deploy a single project with CodeBuild?

commented

Happening on local as well, even with single project.
My webpack.config.js:

const { join } = require('path');

module.exports = {
  entry: {
    getUsers: './getUsers.ts'
  },
  target: 'node',
  module: {
    loaders: [
      { test: /\.ts(x?)$/, loader: 'ts-loader' }
    ]
  },
  resolve: {
    extensions: ['.ts', '.js']
  },
  output: {
    path: join(__dirname, '.webpack'),
    libraryTarget: 'commonjs',
    filename: '[name].js'
  }
}

Output of sls package:

Serverless: Bundling with Webpack...
ts-loader: Using typescript@2.4.2 and /Users/user/Documents/my-project/tsconfig.json
Time: 1839ms
      Asset     Size  Chunks             Chunk Names
getUsers.js  3.19 kB       0  [emitted]  getUsers
   [0] ./getUsers.ts 311 bytes {0} [built]
   [1] ../lib/lambdaUtils.ts 252 bytes {0} [built]
Serverless: Packaging service...
path.js:7
    throw new TypeError('Path must be a string. Received ' + inspect(path));
    ^

TypeError: Path must be a string. Received undefined
    at assertPath (path.js:7:11)
    at Object.basename (path.js:1355:5)
    at functionNames.forEach.name (/Users/user/Documents/my-project/node_modules/serverless-webpack/lib/cleanup.js:28:28)
    at Array.forEach (native)
    at fse.copy (/Users/user/Documents/my-project/node_modules/serverless-webpack/lib/cleanup.js:23:31)
    at doneOne (/Users/user/Documents/my-project/node_modules/fs-extra/lib/copy/ncp.js:237:40)
    at /Users/user/Documents/my-project/node_modules/fs-extra/lib/copy/ncp.js:122:11
    at /Users/user/Documents/my-project/node_modules/graceful-fs/polyfills.js:239:18
    at FSReqWrap.oncomplete (fs.js:111:15)

My serverless.yml

# For full config options, check the docs:
#    docs.serverless.com

service: secondTest

frameworkVersion: ">=1.0.0 <2.0.0" # Serverless version

provider:
  name: aws
  runtime: nodejs6.10
  region: eu-west-1
  memorySize: 128 # RAM of function
  stage: dev
  timeout: 3 # Max number of seconds the function can run for

plugins:
  - serverless-webpack # Compile functions with Webpack

package:
  individually: true # Package each function separately

functions:
  getUsers:
    handler: getUsers.handler
    events:
      - http:
          path: users
          method: get
          cors: true

Also, I changed the script to a bash one, easier to write and manage:

#!/bin/bash

cd src

for d in */ ; do
    if [ "$d" != "lib/" ]; then
        cd $d
        echo "Deploying $d"
        sls package
        cd ..
    fi
done

The error happens in the cleanup when package.individually has been set. See cleanup.js.

This maybe related to #120 - individual packaging does not work properly.
According to the source, the function's artifact property must be unset.

We should try to setup a simple project where it can be reproduced locally and then it should be solved together with #120.

I'm having this problem as well. I don't think it's a CodeBuild issue. Can we rename the issue?

I don't know if this is going to help. My project was working well on serverless v1.17.0 but it gave me this exact error in this issue after I updated to serverless v1.18.0.

@dashmug Oh. Then it might be something related to changes in Serverless 1.18. Regarding a proper name for the issue, I'd first want to clarify with the Serverless team if it is known there.

@pmuens Is there anything known on the Serverless side about such an issue? If yes, could you please post a reference here?

@HyperBrain thanks for asking. 🤔 the only thing I can think of right now is the problem with the dev dependency exclusion which has a known bug. Don't know if it's related here though (serverless/serverless#3972).

Other than that there's serverless/serverless#3978 you've already linked to.

I am not sure if I am having the same issue but I can't seem to create multiple entry points.

  Type Error ---------------------------------------------
 
  Path must be a string. Received { first: './handlers/first.js', second: './handlers/second.js' }
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.1.4
     Serverless Version:     1.18.0

My webpack 2 config is:

module.exports = {
  entry: {
    first: "./handlers/first.js",
    second: "./handlers/second.js",
  },
  target: "node",
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loader: "babel-loader",
        exclude: /node_modules/,
      },
    ]
  },
};

Based on webpack docs I should be able to pass an object as the entry and the keys will be used to name the files.

Turns out I was missing the output section

commented

I might have found the issue at line 24 and 27.
You reference this.serverless.service.functions[name].artifact but what you want instead is this.serverless.service.functions[name].package.artifact
Issued a Pull Request

Hey @kikar , thanks for the PR 👍 . I will check it tomorrow - and target it for 2.1.0, so that we can get it out asap.

@kikar Did you check if the fix also works with Serverless 1.17? @dashmug mentioned above that he had the problem after upgrading to 1.18. We should just make sure that the function artifact did not change between the Serverless versions and we have to check for both locations in case it did.

commented

I didn't try my fix for earlier version, but I checked the bug was present on both versions.
How can I target it for 2.1.0?

I already added the 2.1.0 milestone to the issue. You do not have to do anything on your side ;-)

commented

Nice. When do you think is it gonna get published?

as soon as I merged #130 I will prepare the release. Think it will be tomorrow.