Skip to content

Commit dca2a47

Browse files
authored
Merge branch 'master' into feature/ignore-test-in-lambda-folder
2 parents 3795dcd + 4db2434 commit dca2a47

File tree

5 files changed

+1445
-1039
lines changed

5 files changed

+1445
-1039
lines changed

README.md

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ The goal is to make it easy to write Lambda's with transpiled JS/TypeScript feat
66

77
## Installation
88

9-
**We recommend installing locally** rather than globally:
9+
**We recommend installing locally** rather than globally:
1010

1111
```bash
1212
yarn add -D netlify-lambda
1313
```
1414

1515
This will ensure your build scripts don't assume a global install which is better for your CI/CD (for example with Netlify's buildbot).
1616

17-
If you don't have a [`netlify.toml`](https://www.netlify.com/docs/netlify-toml-reference/) file, you'll need one ([example](https://github.com/netlify/create-react-app-lambda/blob/master/netlify.toml)). Define the `functions` field where the functions will be built to and served from, e.g.
17+
If you don't have a [`netlify.toml`](https://www.netlify.com/docs/netlify-toml-reference/) file, you'll need one ([example](https://github.com/netlify/create-react-app-lambda/blob/master/netlify.toml)). Define the `functions` field where the functions will be built to and served from, e.g.
1818

1919
```toml
2020
# example netlify.toml
@@ -45,13 +45,21 @@ folder/hello.js -> http://localhost:9000/.netlify/functions/hello
4545

4646
It also watches your files and restarts the dev server on change. Note: if you add a new file you should kill and restart the process to pick up the new file.
4747

48-
**IMPORTANT**:
48+
**IMPORTANT**:
4949

5050
- You need a [`netlify.toml`](https://www.netlify.com/docs/netlify-toml-reference/) file with a `functions` field.
5151
- Every function needs to be a top-level js/ts/mjs file. You can have subfolders inside the `netlify-lambda` folder, but those are only for supporting files to be imported by your top level function.
5252
- Function signatures follow the [AWS event handler](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html) syntax but must be named `handler`. [We use Node v8](https://www.netlify.com/blog/2018/04/03/node.js-8.10-now-available-in-netlify-functions/) so `async` functions **are** supported ([beware common mistakes](https://serverless.com/blog/common-node8-mistakes-in-lambda/)!). Read [Netlify Functions docs](https://www.netlify.com/docs/functions/#javascript-lambda-functions) for more info.
5353

5454
<details>
55+
<summary><b>Environment variables in build and branch contextx</b>
56+
57+
Read Netlify's [documentation on environment variables](https://www.netlify.com/docs/continuous-deployment/#build-environment-variables).
58+
`netlify-lambda` should respect the env variables you supply in `netlify.toml` accordingly (except for deploy previews, which make no sense to locally emulate).
59+
60+
However, this is a [relatively new feature](https://github.com/netlify/netlify-lambda/issues/59), so if you encounter issues, file one.
61+
62+
</details>
5563
<summary>
5664
<b>Lambda function examples</b>
5765
</summary>
@@ -106,7 +114,7 @@ When your function is deployed on Netlify, it will be available at `/.netlify/fu
106114

107115
Say you are running `webpack-serve` on port 8080 and `netlify-lambda serve` on port 9000. Mounting `localhost:9000` to `/.netlify/functions/` on your `webpack-serve` server (`localhost:8080/.netlify/functions/`) will closely replicate what the final production environment will look like during development, and will allow you to assume the same function url path in development and in production.
108116

109-
- If you are using with `create-react-app`, see [netlify/create-react-app-lambda](https://github.com/netlify/create-react-app-lambda/blob/f0e94f1d5a42992a2b894bfeae5b8c039a177dd9/src/setupProxy.js) for an example of how to do this with `create-react-app`. [setupProxy is partially documented in the CRA docs](https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development#configuring-the-proxy-manually). You can also learn how to do this from scratch in a video: https://www.youtube.com/watch?v=3ldSM98nCHI
117+
- If you are using with `create-react-app`, see [netlify/create-react-app-lambda](https://github.com/netlify/create-react-app-lambda/blob/f0e94f1d5a42992a2b894bfeae5b8c039a177dd9/src/setupProxy.js) for an example of how to do this with `create-react-app`. [setupProxy is partially documented in the CRA docs](https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development#configuring-the-proxy-manually). You can also learn how to do this from scratch in a video: https://www.youtube.com/watch?v=3ldSM98nCHI
110118
- If you are using Gatsby, see [their Advanced Proxying docs](https://www.gatsbyjs.org/docs/api-proxy/#advanced-proxying). This is implemented in the [JAMstack Hackathon Starter](https://github.com/sw-yx/jamstack-hackathon-starter), and here is an accompanying blogpost: [Turning the Static Dynamic: Gatsby + Netlify Functions + Netlify Identity](https://www.gatsbyjs.org/blog/2018-12-17-turning-the-static-dynamic/).
111119
- If you are using Next.js, see [this issue for how to proxy](https://github.com/netlify/netlify-lambda/pull/28#issuecomment-439675503).
112120
- If you are using Vue CLI, you may just use https://github.com/netlify/vue-cli-plugin-netlify-lambda/.
@@ -116,12 +124,12 @@ Say you are running `webpack-serve` on port 8080 and `netlify-lambda serve` on p
116124

117125
```js
118126
module.exports = {
119-
mode: "development",
127+
mode: 'development',
120128
devServer: {
121129
proxy: {
122-
"/.netlify": {
123-
target: "http://localhost:9000",
124-
pathRewrite: { "^/.netlify/functions": "" }
130+
'/.netlify': {
131+
target: 'http://localhost:9000',
132+
pathRewrite: { '^/.netlify/functions': '' }
125133
}
126134
}
127135
}
@@ -138,7 +146,7 @@ CORS issues when trying to use netlify-lambdas locally with angular? you need to
138146
Firstly make sure you are using relative paths in your app to ensure that your app will work locally and on Netlify, example below...
139147

140148
```js
141-
this.http.get('/.netlify/functions/jokeTypescript')
149+
this.http.get('/.netlify/functions/jokeTypescript');
142150
```
143151

144152
Then place a `proxy.config.json` file in the root of your project, the contents should look something like...
@@ -175,6 +183,7 @@ To make your life easier you can add these to your `scripts` in `package.json`
175183
```
176184

177185
Obviously you need to run up `netlify-lambda` & `angular` at the same time.
186+
178187
</details>
179188

180189
## Webpack Configuration
@@ -236,6 +245,10 @@ There are additional CLI options:
236245
-s --static
237246
```
238247

248+
### --config option
249+
250+
If you need to use additional webpack modules or loaders, you can specify an additional webpack config with the `-c`/`--config` option when running either `serve` or `build`.
251+
239252
### --port option
240253

241254
The serving port can be changed with the `-p`/`--port` option.
@@ -244,24 +257,24 @@ The serving port can be changed with the `-p`/`--port` option.
244257

245258
If you need an escape hatch and are building your lambda in some way that is incompatible with our build process, you can skip the build with the `-s` or `--static` flag. [More info here](https://github.com/netlify/netlify-lambda/pull/62).
246259

247-
## Debugging
260+
## Netlify Identity
248261

249-
To debug lambdas, prepend the `serve` command with [npm's package runner npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) `npx --node-arg=--inspect netlify-lambda serve ...`. Additionally:
262+
Make sure to [read the docs](https://www.netlify.com/docs/functions/#identity-and-functions) on how Netlify Functions and Netlify Identity work together. Basically you have to make your request with an `authorization` header and a `Bearer` token with your Netlify Identity JWT supplied. You can get this JWT from any of our Identity solutions from [gotrue-js](https://github.com/netlify/gotrue-js) to [netlify-identity-widget](https://github.com/netlify/netlify-identity-widget).
250263

251-
1. make sure that sourcemaps are built along the way (e.g. in the webpack configuration and the `tsconfig.json` if typescript is used)
252-
2. webpack's uglification is turned off with `optimization: { minimize: false }`. If using VSCode, it is likely that the `sourceMapPathOverrides` have to be adapted for breakpoints to work.
264+
Since for practical purposes we cannot fully emulate Netlify Identity locally, we provide [simple JWT decoding inside the `context` of your function](https://github.com/netlify/netlify-lambda/pull/57). This will give you back the `user` info you need to work with.
253265

254-
Netlify Functions [run in Node v8.10](https://www.netlify.com/blog/2018/04/03/node.js-8.10-now-available-in-netlify-functions/) and you may need to run the same version to mirror the environment locally. Also make sure to check that you aren't [committing one of these common Node 8 mistakes in Lambda!](https://serverless.com/blog/common-node8-mistakes-in-lambda/)
266+
Minor note: For the `identity` field, since we are not fully emulating Netlify Identity, we can't give you details on the Identity instance, so we give you [unambiguous strings](https://github.com/netlify/netlify-lambda/blob/master/lib/serve.js#L87) so you know not to rely on it locally: `NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_URL` and `NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_TOKEN`. In production, of course, Netlify Functions will give you the correct `identity.url` and `identity.token` fields. We find we dont use this info often in our functions so it is not that big of a deal in our judgment.
255267

256-
Don't forget to search our issues in case someone has run into a similar problem you have!
268+
## Debugging
257269

258-
## Netlify Identity
270+
To debug lambdas, prepend the `serve` command with [npm's package runner npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) `npx --node-arg=--inspect netlify-lambda serve ...`. Additionally:
259271

260-
Make sure to [read the docs](https://www.netlify.com/docs/functions/#identity-and-functions) on how Netlify Functions and Netlify Identity work together. Basically you have to make your request with an `authorization` header and a `Bearer` token with your Netlify Identity JWT supplied. You can get this JWT from any of our Identity solutions from [gotrue-js](https://github.com/netlify/gotrue-js) to [netlify-identity-widget](https://github.com/netlify/netlify-identity-widget).
272+
1. make sure that sourcemaps are built along the way (e.g. in the webpack configuration and the `tsconfig.json` if typescript is used)
273+
2. webpack's uglification is turned off with `optimization: { minimize: false }`. If using VSCode, it is likely that the `sourceMapPathOverrides` have to be adapted for breakpoints to work.
261274

262-
Since for practical purposes we cannot fully emulate Netlify Identity locally, we provide [simple JWT decoding inside the `context` of your function](https://github.com/netlify/netlify-lambda/pull/57). This will give you back the `user` info you need to work with.
275+
Netlify Functions [run in Node v8.10](https://www.netlify.com/blog/2018/04/03/node.js-8.10-now-available-in-netlify-functions/) and you may need to run the same version to mirror the environment locally. Also make sure to check that you aren't [committing one of these common Node 8 mistakes in Lambda!](https://serverless.com/blog/common-node8-mistakes-in-lambda/)
263276

264-
Minor note: For the `identity` field, since we are not fully emulating Netlify Identity, we can't give you details on the Identity instance, so we give you [unambiguous strings](https://github.com/netlify/netlify-lambda/blob/master/lib/serve.js#L87) so you know not to rely on it locally: `NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_URL` and `NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_TOKEN`. In production, of course, Netlify Functions will give you the correct `identity.url` and `identity.token` fields. We find we dont use this info often in our functions so it is not that big of a deal in our judgment.
277+
Don't forget to search our issues in case someone has run into a similar problem you have!
265278

266279
## Example functions and Tutorials
267280

lib/build.js

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
var fs = require("fs");
2-
var path = require("path");
3-
var conf = require("./config");
4-
var webpack = require("webpack");
5-
var merge = require("webpack-merge");
1+
var fs = require('fs');
2+
var path = require('path');
3+
var conf = require('./config');
4+
var webpack = require('webpack');
5+
var merge = require('webpack-merge');
66

77
const testFilePattern = "\\.(test|spec)\\.?";
88

99
// custom babel target for each node version
1010
function getBabelTarget(envConfig) {
11-
var key = "AWS_LAMBDA_JS_RUNTIME";
12-
var runtimes = ["nodejs8.10", "nodejs4.3.2", "nodejs6.10.3"];
13-
var current = envConfig[key] || process.env[key] || "nodejs6.10.3";
11+
var key = 'AWS_LAMBDA_JS_RUNTIME';
12+
var runtimes = ['nodejs8.15.0', 'nodejs6.10.3'];
13+
var current = envConfig[key] || process.env[key] || 'nodejs8.15.0';
1414
var unknown = runtimes.indexOf(current) === -1;
15-
return unknown ? "6.10" : current.replace(/^nodejs/, "");
15+
return unknown ? '8.15.0' : current.replace(/^nodejs/, '');
1616
}
1717

1818
function haveBabelrc(functionsDir) {
1919
const cwd = process.cwd();
2020

2121
return (
22-
fs.existsSync(path.join(cwd, ".babelrc")) ||
23-
functionsDir.split("/").reduce((foundBabelrc, dir) => {
22+
fs.existsSync(path.join(cwd, '.babelrc')) ||
23+
functionsDir.split('/').reduce((foundBabelrc, dir) => {
2424
if (foundBabelrc) return foundBabelrc;
2525

2626
const indexOf = functionsDir.indexOf(dir);
2727
const dirToSearch = functionsDir.substr(0, indexOf);
2828

29-
return fs.existsSync(path.join(cwd, dirToSearch, ".babelrc"));
29+
return fs.existsSync(path.join(cwd, dirToSearch, '.babelrc'));
3030
}, false)
3131
);
3232
}
@@ -37,13 +37,13 @@ function webpackConfig(dir, additionalConfig) {
3737
var babelOpts = { cacheDirectory: true };
3838
if (!haveBabelrc(dir)) {
3939
babelOpts.presets = [
40-
["@babel/preset-env", { targets: { node: getBabelTarget(envConfig) } }]
40+
['@babel/preset-env', { targets: { node: getBabelTarget(envConfig) } }]
4141
];
4242

4343
babelOpts.plugins = [
44-
"@babel/plugin-proposal-class-properties",
45-
"@babel/plugin-transform-object-assign",
46-
"@babel/plugin-proposal-object-rest-spread"
44+
'@babel/plugin-proposal-class-properties',
45+
'@babel/plugin-transform-object-assign',
46+
'@babel/plugin-proposal-object-rest-spread'
4747
];
4848
}
4949

@@ -53,20 +53,25 @@ function webpackConfig(dir, additionalConfig) {
5353

5454
if (dirPath === functionsPath) {
5555
throw new Error(
56-
"Function source and publish folder should be in different locations"
56+
`
57+
netlify-lambda Error: Function source folder (specified in netlify-lambda serve/build command)
58+
and publish folder (specified in netlify.toml)
59+
should be different.
60+
For more info, check https://github.com/netlify/netlify-lambda#usage
61+
`
5762
);
5863
}
5964

6065
// Include environment variables from config if available
6166
var defineEnv = {};
6267
Object.keys(envConfig).forEach(key => {
63-
defineEnv["process.env." + key] = JSON.stringify(envConfig[key]);
68+
defineEnv['process.env.' + key] = JSON.stringify(envConfig[key]);
6469
});
6570

6671
var webpackConfig = {
67-
mode: "production",
72+
mode: 'production',
6873
resolve: {
69-
extensions: [".wasm", ".mjs", ".js", ".json", ".ts"]
74+
extensions: ['.wasm', '.mjs', '.js', '.json', '.ts']
7075
},
7176
module: {
7277
rules: [
@@ -76,23 +81,23 @@ function webpackConfig(dir, additionalConfig) {
7681
`(node_modules|bower_components|${testFilePattern})`
7782
),
7883
use: {
79-
loader: "babel-loader",
84+
loader: 'babel-loader',
8085
options: babelOpts
8186
}
8287
}
8388
]
8489
},
8590
context: dirPath,
8691
entry: {},
87-
target: "node",
92+
target: 'node',
8893
plugins: [
8994
new webpack.IgnorePlugin(/vertx/),
9095
new webpack.DefinePlugin(defineEnv)
9196
],
9297
output: {
9398
path: functionsPath,
94-
filename: "[name].js",
95-
libraryTarget: "commonjs"
99+
filename: '[name].js',
100+
libraryTarget: 'commonjs'
96101
},
97102
devtool: false
98103
};

lib/config.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
var toml = require("toml");
2-
var fs = require("fs");
3-
var path = require("path");
1+
var toml = require('toml');
2+
var fs = require('fs');
3+
var path = require('path');
44

55
exports.load = function() {
6-
var configPath = path.join(process.cwd(), "netlify.toml");
6+
var configPath = path.join(process.cwd(), 'netlify.toml');
77
if (!fs.existsSync(configPath)) {
88
console.error(
9-
"No netlify.toml found. This is needed to configure the function settings"
9+
'No netlify.toml found. This is needed to configure the function settings. For more info: https://github.com/netlify/netlify-lambda#installation'
1010
);
1111
process.exit(1);
1212
}
@@ -16,16 +16,16 @@ exports.load = function() {
1616

1717
exports.loadContext = function(config) {
1818
var buildConfig = config.build;
19-
var contextConfig = (
20-
process.env.CONTEXT &&
21-
config.context &&
22-
config.context[process.env.CONTEXT]
23-
) || {};
24-
var branchConfig = (
25-
process.env.BRANCH &&
26-
config.context &&
27-
config.context[process.env.BRANCH]
28-
) || {};
19+
var contextConfig =
20+
(process.env.CONTEXT &&
21+
config.context &&
22+
config.context[process.env.CONTEXT]) ||
23+
{};
24+
var branchConfig =
25+
(process.env.BRANCH &&
26+
config.context &&
27+
config.context[process.env.BRANCH]) ||
28+
{};
2929
var buildEnv = buildConfig.environment || buildConfig.Environment || {};
3030
var contextEnv = contextConfig.environment || contextConfig.Environment || {};
3131
var branchEnv = branchConfig.environment || branchConfig.Environment || {};
@@ -36,7 +36,7 @@ exports.loadContext = function(config) {
3636
environment: {
3737
...buildEnv,
3838
...contextEnv,
39-
...branchEnv,
39+
...branchEnv
4040
}
4141
};
4242
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "netlify-lambda",
3-
"version": "1.0.3",
3+
"version": "1.2.0",
44
"description": "Build and serve lambda function with webpack compilation",
55
"homepage": "https://github.com/netlify/netlify-lambda#readme",
66
"main": "bin/cmd.js",

0 commit comments

Comments
 (0)