You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Use scratch dir. Read props from options
* Docstrings and black reformat
* Add tests
* Add logic for accepting implicit entry points
* Uncomment feature flag
* Black reformat
* Address comments
* Fix integration test
Co-authored-by: Mehmet Nuri Deveci <[email protected]>
The general algorithm for preparing a node package for use on AWS Lambda
@@ -226,158 +220,3 @@ _(out of scope for the current version)_
226
220
To fully support dependencies that download or compile binaries for a target platform, this step
227
221
needs to be executed inside a Docker image compatible with AWS Lambda.
228
222
_(out of scope for the current version)_
229
-
230
-
### Implementation with a bundler
231
-
232
-
The general algorithm for preparing a node package for use on AWS Lambda
233
-
with a bundler (`esbuild` or `webpack`) is as follows.
234
-
235
-
#### Step 1: ensure production dependencies are installed
236
-
237
-
If the directory contains `package-lock.json` or `npm-shrinkwrap.json`,
238
-
execute [`npm ci`](https://docs.npmjs.com/cli/v7/commands/npm-ci). This
239
-
operation is designed to be faster than installing dependencies using `npm install`
240
-
in automated CI environments.
241
-
242
-
If the directory does not contain lockfiles, but contains `package.json`,
243
-
execute [`npm install --production`] to download production dependencies.
244
-
245
-
#### Step 2: bundle the main Lambda file
246
-
247
-
Execute `esbuild` to produce a single JavaScript file by recursively resolving
248
-
included dependencies, and optionally a source map.
249
-
250
-
Ensure that the target file name is the same as the entry point of the Lambda
251
-
function, so that there is no impact on the CloudFormation template.
252
-
253
-
254
-
### Activating the bundler workflow
255
-
256
-
Because there are advantages and disadvantages to both approaches (with and
257
-
without a bundler), the user should be able to choose between them. The default
258
-
is not to use a bundler (both because it's universally applicable and for
259
-
backwards compatibility). Node.js pakage manifests (`package.json`) allow for
260
-
custom properties, so a user can activate the bundler process by providing an
261
-
`aws_sam` configuration property in the package manifest. If this property is
262
-
present in the package manifest, and the sub-property `bundler` equals
263
-
`esbuild`, the Node.js NPM Lambda builder activates the bundler process.
264
-
265
-
Because the Lambda builder workflow is not aware of the main lambda function
266
-
definition, (the file containing the Lambda handler function) the user must
267
-
also specify the main entry point for bundling . This is a bit of an
268
-
unfortunate duplication with SAM Cloudformation template, but with the current
269
-
workflow design there is no way around it.
270
-
271
-
In addition, as a single JavaScript source package can contain multiple functions,
272
-
and can be included multiple times in a single CloudFormation template, it's possible
273
-
that there may be multiple entry points for bundling. SAM build executes the build
274
-
only once for the function in this case, so all entry points have to be bundled
275
-
at once.
276
-
277
-
The following example is a minimal `package.json` to activate the `esbuild` bundler
278
-
on a javascript file, starting from `lambda.js`. It will produce a bundled `lambda.js`
279
-
in the artifacts folder.
280
-
281
-
```json
282
-
{
283
-
"name": "nodeps-esbuild",
284
-
"version": "1.0.0",
285
-
"license": "APACHE2.0",
286
-
"aws_sam": {
287
-
"bundler": "esbuild",
288
-
"entry_points": ["lambda.js"]
289
-
}
290
-
}
291
-
```
292
-
293
-
#### Locating the esbuild binary
294
-
295
-
`esbuild` supports platform-independent binary distribution using NPM, by
296
-
including the `esbuild` package as a dependency. The Lambda builder should
297
-
first try to locate the binary in the Lambda code repository (allowing the
298
-
user to include a specific version). Failing that, the Lambda builder should
299
-
try to locate the `esbuild` binary in the `executable_search_paths` configured
300
-
for the workflow, then the operating system `PATH` environment variable.
301
-
302
-
The Lambda builder **should not** bring its own `esbuild` binary, but it should
303
-
clearly point to the error when one is not found, to allow users to configure the
304
-
build correctly.
305
-
306
-
In the previous example, the esbuild binary is not included in the package dependencies,
307
-
so the Lambda builder will use the system executable paths to search for it. In the
308
-
example below, `esbuild` is included in the package, so the Lambda builder should use it
309
-
directly.
310
-
311
-
```json
312
-
{
313
-
"name": "with-deps-esbuild",
314
-
"version": "1.0.0",
315
-
"license": "APACHE2.0",
316
-
"aws_sam": {
317
-
"bundler": "esbuild",
318
-
"entry_points": ["lambda.js"]
319
-
},
320
-
"devDependencies": {
321
-
"esbuild": "^0.11.23"
322
-
}
323
-
}
324
-
```
325
-
326
-
For a full example, see the [`with-deps-esbuild`](../../../tests/integration/workflows/nodejs_npm_esbuild/testdata/with-deps-esbuild/) test project.
327
-
328
-
#### Building typescript
329
-
330
-
`esbuild` supports bundling typescript out of the box and transpiling it to plain
331
-
javascript. The user just needs to point to a typescript file as the main entry point,
332
-
as in the example below. There is no transpiling process needed upfront.
333
-
334
-
335
-
```js
336
-
{
337
-
"name":"with-deps-esbuild-typescript",
338
-
"version":"1.0.0",
339
-
"license":"APACHE2.0",
340
-
"aws_sam": {
341
-
"bundler":"esbuild",
342
-
"entry_points": ["included.ts"]
343
-
},
344
-
"dependencies": {
345
-
"@types/aws-lambda":"^8.10.76"
346
-
},
347
-
"devDependencies": {
348
-
"esbuild":"^0.11.23"
349
-
}
350
-
}
351
-
```
352
-
353
-
For a full example, see the [`with-deps-esbuild-typescript`](../../../tests/integration/workflows/nodejs_npm_esbuild/testdata/with-deps-esbuild-typescript/) test project.
354
-
355
-
**important note:** esbuild does not perform type checking, so users wanting to ensure type-checks need to run the `tsc` process as part of their
356
-
testing flow before invoking `sam build`. For additional typescript caveats with esbuild, check out <https://esbuild.github.io/content-types/#typescript>.
357
-
358
-
#### Configuring the bundler
359
-
360
-
The Lambda builder invokes `esbuild` with sensible defaults that will work for the majority of cases. Importantly, the following three parameters are set by default
361
-
362
-
*`--minify`, as it [produces a smaller runtime package](https://esbuild.github.io/api/#minify)
363
-
*`--sourcemap`, as it generates a [source map that allows for correct stack trace reporting](https://esbuild.github.io/api/#sourcemap) in case of errors (see the [Error reporting](#error-reporting) section above)
364
-
*`--target es2020`, as it allows for javascript features present in Node 14
365
-
366
-
Users might want to tweak some of these runtime arguments for a specific project, for example not including the source map to further reduce the package size, or restricting javascript features to an older version. The Lambda builder allows this with optional sub-properties of the `aws_sam` configuration property.
367
-
368
-
*`target`: string, corresponding to a supported [esbuild target](https://esbuild.github.io/api/#target) property
369
-
*`minify`: boolean, defaulting to `true`
370
-
*`sourcemap`: boolean, defaulting to `true`
371
-
372
-
Here is an example that deactivates minification and source maps, and supports JavaScript features compatible with Node.js version 10.
directory containing customer code, including a valid `package.json` manifest
7
+
specifying third-party dependencies. The builder will use NPM to include
8
+
production dependencies and exclude test resources in a way that makes them
9
+
deployable to AWS Lambda. It will then bundle the code using `esbuild` with the properties
10
+
passed in through the builder options field.
11
+
12
+
### Additional Tools
13
+
14
+
Packaging with a bundler requires installing additional tools (eg `esbuild`).
15
+
16
+
### Implementation with a bundler
17
+
18
+
The general algorithm for preparing a node package for use on AWS Lambda
19
+
with a bundler (`esbuild` or `webpack`) is as follows.
20
+
21
+
#### Step 1: ensure production dependencies are installed
22
+
23
+
If the directory contains `package-lock.json` or `npm-shrinkwrap.json`,
24
+
execute [`npm ci`](https://docs.npmjs.com/cli/v7/commands/npm-ci). This
25
+
operation is designed to be faster than installing dependencies using `npm install`
26
+
in automated CI environments.
27
+
28
+
If the directory does not contain lockfiles, but contains `package.json`,
29
+
execute [`npm install --production`] to download production dependencies.
30
+
31
+
#### Step 2: bundle the main Lambda file
32
+
33
+
Execute `esbuild` to produce a single JavaScript file by recursively resolving
34
+
included dependencies, and optionally a source map.
35
+
36
+
Ensure that the target file name is the same as the entry point of the Lambda
37
+
function.
38
+
39
+
### Activating the bundler workflow
40
+
41
+
The workflow can be activated by using the `("nodejs", "npm-esbuild", None)` Capability.
42
+
The distinguishing factor being the `npm-esbuild` dependency-manager property of the builder.
43
+
44
+
An entrypoint or entrypoints array must be included in the options passed
45
+
to Lambda Builders for this workflow to succeed.
46
+
47
+
The following example is a minimal options object that can be passed to
48
+
the esbuild workflow, starting from `lambda.js`. It will produce a bundled `lambda.js`
49
+
in the artifacts folder.
50
+
51
+
```json
52
+
{
53
+
"options": {
54
+
"entry_points": ["lambda.js"]
55
+
}
56
+
}
57
+
```
58
+
59
+
#### Locating the esbuild binary
60
+
61
+
`esbuild` supports platform-independent binary distribution using NPM, by
62
+
including the `esbuild` package as a dependency. The Lambda builder should
63
+
first try to locate the binary in the Lambda code repository (allowing the
64
+
user to include a specific version). Failing that, the Lambda builder should
65
+
try to locate the `esbuild` binary in the `executable_search_paths` configured
66
+
for the workflow, then the operating system `PATH` environment variable.
67
+
68
+
The Lambda builder **should not** bring its own `esbuild` binary, but it should
69
+
clearly point to the error when one is not found, to allow users to configure the
70
+
build correctly.
71
+
72
+
In the previous example, the esbuild binary is not included in the package dependencies,
73
+
so the Lambda builder will use the system executable paths to search for it. In the
74
+
example below, `esbuild` is included in the package, so the Lambda builder should use it
75
+
directly.
76
+
77
+
```json
78
+
{
79
+
"name": "with-deps-esbuild",
80
+
"version": "1.0.0",
81
+
"license": "APACHE2.0",
82
+
"devDependencies": {
83
+
"esbuild": "^0.11.23"
84
+
}
85
+
}
86
+
```
87
+
88
+
For a full example, see the [`with-deps-esbuild`](../../../tests/integration/workflows/nodejs_npm_esbuild/testdata/with-deps-esbuild/) test project.
89
+
90
+
#### Building typescript
91
+
92
+
`esbuild` supports bundling typescript out of the box and transpiling it to plain
93
+
javascript. The user just needs to point to a typescript file as the main entry point,
94
+
as in the example below. There is no transpiling process needed upfront.
95
+
96
+
If no file type is provided for the entrypoint, esbuild will first look for a
97
+
TypeScript file, and the a JavaScript file with the given filename.
98
+
99
+
```js
100
+
{
101
+
"name":"with-deps-esbuild-typescript",
102
+
"version":"1.0.0",
103
+
"license":"APACHE2.0",
104
+
"dependencies": {
105
+
"@types/aws-lambda":"^8.10.76"
106
+
},
107
+
"devDependencies": {
108
+
"esbuild":"^0.11.23"
109
+
}
110
+
}
111
+
```
112
+
113
+
For a full example, see the [`with-deps-esbuild-typescript`](../../../tests/integration/workflows/nodejs_npm_esbuild/testdata/with-deps-esbuild-typescript/) test project.
114
+
115
+
**important note:** esbuild does not perform type checking, so users wanting to ensure type-checks need to run the `tsc` process as part of their
116
+
testing flow before invoking `sam build`. For additional typescript caveats with esbuild, check out <https://esbuild.github.io/content-types/#typescript>.
117
+
118
+
#### Configuring the bundler
119
+
120
+
The Lambda builder invokes `esbuild` with sensible defaults that will work for the majority of cases. Importantly, the following three parameters are set by default
121
+
122
+
*`--minify`, as it [produces a smaller runtime package](https://esbuild.github.io/api/#minify)
123
+
*`--sourcemap`, as it generates a [source map that allows for correct stack trace reporting](https://esbuild.github.io/api/#sourcemap) in case of errors (see the [Error reporting](#error-reporting) section above)
124
+
*`--target es2020`, as it allows for javascript features present in Node 14
125
+
126
+
Users might want to tweak some of these runtime arguments for a specific project, for example not including the source map to further reduce the package size, or restricting javascript features to an older version. The Lambda builder allows this with optional sub-properties of the `aws_sam` configuration property.
127
+
128
+
*`target`: string, corresponding to a supported [esbuild target](https://esbuild.github.io/api/#target) property
129
+
*`minify`: boolean, defaulting to `true`
130
+
*`sourcemap`: boolean, defaulting to `true`
131
+
132
+
Here is an example that deactivates minification and source maps, and supports JavaScript features compatible with Node.js version 10.
0 commit comments