1
+ const path = require ( 'path' )
1
2
const aws = require ( 'aws-sdk' )
2
3
const { mergeDeepRight, pick } = require ( 'ramda' )
3
4
const { Component, hashFile } = require ( '@serverless/components' )
@@ -10,7 +11,7 @@ const {
10
11
pack
11
12
} = require ( './utils' )
12
13
13
- const outputMask = [
14
+ const outputsList = [
14
15
'name' ,
15
16
'description' ,
16
17
'memory' ,
@@ -22,16 +23,17 @@ const outputMask = [
22
23
'runtime' ,
23
24
'env' ,
24
25
'role' ,
26
+ 'layer' ,
25
27
'arn'
26
28
]
27
29
28
30
const defaults = {
29
- name : 'serverless' ,
31
+ name : 'serverless-layered ' ,
30
32
description : 'AWS Lambda Component' ,
31
33
memory : 512 ,
32
34
timeout : 10 ,
33
35
code : process . cwd ( ) ,
34
- bucket : null ,
36
+ bucket : undefined ,
35
37
shims : [ ] ,
36
38
handler : 'handler.hello' ,
37
39
runtime : 'nodejs8.10' ,
@@ -54,33 +56,52 @@ class AwsLambda extends Component {
54
56
55
57
config . role = config . role || ( await awsIamRole ( config ) )
56
58
57
- this . cli . status ( `Packaging` )
59
+ if ( config . bucket && config . runtime === 'nodejs8.10' ) {
60
+ const layer = await this . load ( '@serverless/aws-lambda-layer' )
61
+
62
+ const layerInputs = {
63
+ name : `${ config . name } -dependencies` ,
64
+ description : `${ config . name } Dependencies Layer` ,
65
+ code : path . join ( config . code , 'node_modules' ) ,
66
+ runtimes : [ 'nodejs8.10' ] ,
67
+ prefix : 'nodejs/node_modules' ,
68
+ bucket : config . bucket ,
69
+ region : config . region
70
+ }
71
+
72
+ this . cli . status ( 'Deploying Dependencies' )
73
+ const promises = [ pack ( config . code , config . shims , false ) , layer ( layerInputs ) ]
74
+ const res = await Promise . all ( promises )
75
+ config . zipPath = res [ 0 ]
76
+ config . layer = res [ 1 ]
77
+ } else {
78
+ this . cli . status ( 'Packaging' )
79
+ config . zipPath = await pack ( config . code , config . shims )
80
+ }
58
81
59
- config . zipPath = await pack ( config . code , config . shims )
60
82
config . hash = await hashFile ( config . zipPath )
61
83
62
84
let deploymentBucket
63
85
if ( config . bucket ) {
64
86
deploymentBucket = await this . load ( '@serverless/aws-s3' )
65
- await deploymentBucket ( { name : config . bucket } )
66
87
}
67
88
68
89
const prevLambda = await getLambda ( { lambda, ...config } )
69
90
70
91
if ( ! prevLambda ) {
71
92
if ( config . bucket ) {
72
93
this . cli . status ( `Uploading` )
73
- await deploymentBucket . upload ( { file : config . zipPath } )
94
+ await deploymentBucket . upload ( { name : config . bucket , file : config . zipPath } )
74
95
}
75
96
76
97
this . cli . status ( `Creating` )
77
98
config . arn = await createLambda ( { lambda, ...config } )
78
99
} else {
79
100
config . arn = prevLambda . arn
80
101
if ( configChanged ( prevLambda , config ) ) {
81
- if ( config . bucket ) {
102
+ if ( config . bucket && prevLambda . hash !== config . hash ) {
82
103
this . cli . status ( `Uploading` )
83
- await deploymentBucket . upload ( { file : config . zipPath } )
104
+ await deploymentBucket . upload ( { name : config . bucket , file : config . zipPath } )
84
105
}
85
106
86
107
this . cli . status ( `Updating` )
@@ -97,14 +118,15 @@ class AwsLambda extends Component {
97
118
this . state . arn = config . arn
98
119
await this . save ( )
99
120
100
- const outputs = pick ( outputMask , config )
121
+ const outputs = pick ( outputsList , config )
101
122
this . cli . outputs ( outputs )
102
123
return outputs
103
124
}
104
125
105
126
async remove ( inputs = { } ) {
106
127
const config = mergeDeepRight ( defaults , inputs )
107
128
config . name = inputs . name || this . state . name || defaults . name
129
+
108
130
const lambda = new aws . Lambda ( {
109
131
region : config . region ,
110
132
credentials : this . context . credentials . aws
@@ -113,12 +135,12 @@ class AwsLambda extends Component {
113
135
this . cli . status ( `Removing` )
114
136
115
137
const awsIamRole = await this . load ( '@serverless/aws-iam-role' )
116
- const deploymentBucket = await this . load ( '@serverless/aws-s3 ' )
138
+ const layer = await this . load ( '@serverless/aws-lambda-layer ' )
117
139
118
140
// there's no need to pass names as input
119
141
// since it's saved in the child component state
120
142
await awsIamRole . remove ( )
121
- await deploymentBucket . remove ( )
143
+ await layer . remove ( )
122
144
123
145
await deleteLambda ( { lambda, name : config . name } )
124
146
0 commit comments