Path error with SLS 1.18 when package individually is set
kikar opened this issue · comments
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?
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
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.
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 ;-)
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.