New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

serverless-esbuild

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serverless-esbuild - npm Package Compare versions

Comparing version

to
1.26.0

12

dist/helper.js

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.providerRuntimeMatcher = exports.doSharePath = exports.getDepsFromBundle = exports.flatDep = exports.extractFileNames = void 0;
exports.buildServerlessV3LoggerFromLegacyLogger = exports.providerRuntimeMatcher = exports.doSharePath = exports.getDepsFromBundle = exports.flatDep = exports.extractFileNames = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));

@@ -131,1 +131,11 @@ const path_1 = __importDefault(require("path"));

});
const buildServerlessV3LoggerFromLegacyLogger = (legacyLogger, verbose) => ({
error: legacyLogger,
warning: legacyLogger,
notice: legacyLogger,
info: legacyLogger,
debug: verbose ? legacyLogger : () => null,
verbose: legacyLogger,
success: legacyLogger,
});
exports.buildServerlessV3LoggerFromLegacyLogger = buildServerlessV3LoggerFromLegacyLogger;

15

dist/index.js

@@ -36,3 +36,3 @@ "use strict";

class EsbuildServerlessPlugin {
constructor(serverless, options) {
constructor(serverless, options, logging) {
this.getCachedOptions = (0, ramda_1.memoizeWith)((0, ramda_1.always)('cache'), () => {

@@ -51,2 +51,5 @@ var _a, _b;

this.options = options;
this.log =
(logging === null || logging === void 0 ? void 0 : logging.log) ||
(0, helper_1.buildServerlessV3LoggerFromLegacyLogger)(this.serverless.cli.log, this.options.verbose);
this.packExternalModules = pack_externals_1.packExternalModules.bind(this);

@@ -164,4 +167,4 @@ this.pack = pack_1.pack.bind(this);

chokidar_1.default.watch(this.buildOptions.watch.pattern, options).on('all', () => this.bundle(true)
.then(() => this.serverless.cli.log('Watching files for changes...'))
.catch(() => this.serverless.cli.log('Bundle error, waiting for a file change to reload...')));
.then(() => this.log.verbose('Watching files for changes...'))
.catch(() => this.log.error('Bundle error, waiting for a file change to reload...')));
}

@@ -200,3 +203,3 @@ prepare() {

this.prepare();
this.serverless.cli.log(`Compiling to ${this.buildOptions.target} bundle with esbuild...`);
this.log.verbose(`Compiling to ${this.buildOptions.target} bundle with esbuild...`);
if (this.buildOptions.disableIncremental === true) {

@@ -245,7 +248,7 @@ incremental = false;

};
this.serverless.cli.log(`Compiling with concurrency: ${(_a = this.buildOptions.concurrency) !== null && _a !== void 0 ? _a : 'Infinity'}`);
this.log.verbose(`Compiling with concurrency: ${(_a = this.buildOptions.concurrency) !== null && _a !== void 0 ? _a : 'Infinity'}`);
this.buildResults = await (0, p_map_1.default)(this.rootFileNames, bundleMapper, {
concurrency: this.buildOptions.concurrency,
});
this.serverless.cli.log('Compiling completed.');
this.log.verbose('Compiling completed.');
return this.buildResults.map((r) => r.result);

@@ -252,0 +255,0 @@ }

@@ -72,4 +72,3 @@ "use strict";

!packageJson.devDependencies[externalModule.external]) {
this.options.verbose &&
this.serverless.cli.log(`INFO: Runtime dependency '${externalModule.external}' not found in dependencies or devDependencies. It has been excluded automatically.`);
this.log.debug(`INFO: Runtime dependency '${externalModule.external}' not found in dependencies or devDependencies. It has been excluded automatically.`);
return;

@@ -85,7 +84,6 @@ }

// Runtime dependency found in devDependencies but not forcefully excluded
this.serverless.cli.log(`ERROR: Runtime dependency '${externalModule.external}' found in devDependencies.`);
this.log.error(`ERROR: Runtime dependency '${externalModule.external}' found in devDependencies.`);
throw new this.serverless.classes.Error(`Serverless-webpack dependency error: ${externalModule.external}.`);
}
this.options.verbose &&
this.serverless.cli.log(`INFO: Runtime dependency '${externalModule.external}' found in devDependencies. It has been excluded automatically.`);
this.log.debug(`INFO: Runtime dependency '${externalModule.external}' found in devDependencies. It has been excluded automatically.`);
return;

@@ -117,4 +115,3 @@ }

if (!(0, ramda_1.isEmpty)(peerDependenciesWithoutOptionals)) {
this.options.verbose &&
this.serverless.cli.log(`Adding explicit non-optionals peers for dependency ${externalModule.external}`);
this.log.debug(`Adding explicit non-optionals peers for dependency ${externalModule.external}`);
const peerModules = getProdModules.call(this, (0, ramda_1.compose)((0, ramda_1.map)(([external]) => ({ external })), ramda_1.toPairs)(peerDependenciesWithoutOptionals), packageJsonPath, rootPackageJsonPath);

@@ -125,3 +122,3 @@ Array.prototype.push.apply(prodModules, peerModules);

catch (e) {
this.serverless.cli.log(`WARNING: Could not check for peer dependencies of ${externalModule.external}`);
this.log.warning(`WARNING: Could not check for peer dependencies of ${externalModule.external}`);
}

@@ -191,7 +188,6 @@ }, externalModules);

if (!(0, ramda_1.isEmpty)(packageSections)) {
this.options.verbose &&
this.serverless.cli.log(`Using package.json sections ${(0, ramda_1.join)(', ', (0, ramda_1.keys)(packageSections))}`);
this.log.debug(`Using package.json sections ${(0, ramda_1.join)(', ', (0, ramda_1.keys)(packageSections))}`);
}
// Get first level dependency graph
this.options.verbose && this.serverless.cli.log(`Fetch dependency graph from ${packageJson}`);
this.log.debug(`Fetch dependency graph from ${packageJson}`);
// (1) Generate dependency composition

@@ -202,3 +198,3 @@ const externalModules = (0, ramda_1.map)((external) => ({ external }), externals);

// The compiled code does not reference any external modules at all
this.serverless.cli.log('No external modules needed');
this.log.warning('No external modules needed');
return;

@@ -224,3 +220,3 @@ }

if (exists) {
this.serverless.cli.log('Package lock found - Using locked versions');
this.log.verbose('Package lock found - Using locked versions');
try {

@@ -235,3 +231,3 @@ let packageLockFile = this.serverless.utils.readFileSync(packageLockPath);

catch (err) {
this.serverless.cli.log(`Warning: Could not read lock file: ${err.message}`);
this.log.warning(`Warning: Could not read lock file: ${err.message}`);
}

@@ -245,11 +241,10 @@ }

const start = Date.now();
this.serverless.cli.log('Packing external modules: ' + compositeModules.join(', '));
this.log.verbose('Packing external modules: ' + compositeModules.join(', '));
const installExtraArgs = this.buildOptions.installExtraArgs;
await packager.install(compositeModulePath, installExtraArgs, exists);
this.options.verbose && this.serverless.cli.log(`Package took [${Date.now() - start} ms]`);
this.log.debug(`Package took [${Date.now() - start} ms]`);
// Prune extraneous packages - removes not needed ones
const startPrune = Date.now();
await packager.prune(compositeModulePath);
this.options.verbose &&
this.serverless.cli.log(`Prune: ${compositeModulePath} [${Date.now() - startPrune} ms]`);
this.log.debug(`Prune: ${compositeModulePath} [${Date.now() - startPrune} ms]`);
// Run packager scripts

@@ -259,6 +254,5 @@ if (Object.keys(packagerScripts).length > 0) {

await packager.runScripts(this.buildDirPath, Object.keys(packagerScripts));
this.options.verbose &&
this.serverless.cli.log(`Packager scripts took [${Date.now() - startScripts} ms].\nExecuted scripts: ${Object.values(packagerScripts).map((script) => `\n ${script}`)}`);
this.log.debug(`Packager scripts took [${Date.now() - startScripts} ms].\nExecuted scripts: ${Object.values(packagerScripts).map((script) => `\n ${script}`)}`);
}
}
exports.packExternalModules = packExternalModules;

@@ -41,3 +41,3 @@ "use strict";

func.package = Object.assign({}, func.package, { disable: true });
this.serverless.cli.log(`${func.name} is packaged by the esbuild plugin. Ignore messages from SLS.`);
this.log.verbose(`${func.name} is packaged by the esbuild plugin. Ignore messages from SLS.`);
}

@@ -108,3 +108,3 @@ else {

const { size } = fs_extra_1.default.statSync(artifactPath);
this.serverless.cli.log(`Zip service ${this.serverless.service.service} - ${(0, utils_1.humanSize)(size)} [${Date.now() - startZip} ms]`);
this.log.verbose(`Zip service ${this.serverless.service.service} - ${(0, utils_1.humanSize)(size)} [${Date.now() - startZip} ms]`);
// defined present zip as output artifact

@@ -164,3 +164,3 @@ this.serverless.service.package.artifact = artifactPath;

const { size } = fs_extra_1.default.statSync(artifactPath);
this.serverless.cli.log(`Zip function: ${functionAlias} - ${(0, utils_1.humanSize)(size)} [${Date.now() - startZip} ms]`);
this.log.verbose(`Zip function: ${functionAlias} - ${(0, utils_1.humanSize)(size)} [${Date.now() - startZip} ms]`);
// defined present zip as output artifact

@@ -167,0 +167,0 @@ setFunctionArtifactPath.call(this, func, path_1.default.relative(this.serviceDirPath, artifactPath));

@@ -39,3 +39,3 @@ "use strict";

const message = `Could not find packager '${packagerId}'`;
this.serverless.cli.log(`ERROR: ${message}`);
this.log.error(`ERROR: ${message}`);
throw new this.serverless.classes.Error(message);

@@ -42,0 +42,0 @@ }

{
"name": "serverless-esbuild",
"description": "Serverless plugin for zero-config JavaScript and TypeScript code bundling using extremely fast esbuild",
"version": "1.25.0",
"version": "1.26.0",
"license": "MIT",

@@ -52,3 +52,3 @@ "author": "Victor Korzunin",

"@types/semver": "^7.3.8",
"@types/serverless": "^1.78.25",
"@types/serverless": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^4.2.0",

@@ -55,0 +55,0 @@ "@typescript-eslint/parser": "^4.2.0",

@@ -13,10 +13,29 @@ # 💨 serverless-esbuild

- Zero-config: Works out of the box without the need to install any other compiler or plugins
- Supports ESNext syntax with transforming limitations (See _Note_)
- Supports `sls package`, `sls deploy` and `sls deploy function`
- Supports `sls invoke local`
- Integrates nicely with [`serverless-offline`](https://github.com/dherault/serverless-offline)
- Zero-config: Works out of the box without the need to install any additional plugins
- Works with Typescript and Javascript projects
- Supports `sls package`, `sls deploy`, `sls deploy function`
- Integrates with [`Serverless Invoke Local`](https://www.serverless.com/framework/docs/providers/aws/cli-reference/invoke-local) & [`serverless-offline`](https://github.com/dherault/serverless-offline)
_Note_: The default JavaScript syntax target is determined from serverless provider configuration otherwise set to [`node12`], so the final bundle will be supported by all [AWS Lambda Node.js runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html). If you still using an old lambda runtime and have to respect it you can play with esbuild `target` option, see [JavaScript syntax support](https://github.com/evanw/esbuild#javascript-syntax-support) for more details about syntax transform limitations.
## Table of Contents
- [Install](#install)
- [Configuration](#configuration)
- [Examples](#examples)
- [Options](#options)
- [Default Esbuild Options](#default-esbuild-options)
- [Packager Options](#packager-options)
- [Watch Options](#watch-options)
- [Supported Runtimes](#supported-runtimes)
- [Advanced Configuration](#advanced-configuration)
- [Including Extra Files](#including-extra-files)
- [External Dependencies](#external-dependencies)
- [Esbuild Plugins](#esbuild-plugins)
- [Usage](#usage)
- [Automatic Compilation](#automatic-compilation)
- [Serverless Offline](#serverless-offline)
- [Serverless Dynamodb Local](#serverless-dynamodb-local)
- [Invoke Local](#invoke-local)
- [External Tools](#external-tools)
- [Contributors](#contributors)
## Install

@@ -40,5 +59,5 @@

## Configure
## Configuration
By default, no configuration is required, but you can change esbuild behavior in custom `esbuild` section in `serverless.yaml` config:
By default, no configuration is required, but you can override the default behavior via the `custom.esbuild` section in the `serverless.yml` file.

@@ -52,16 +71,70 @@ ```yml

Check [esbuild](https://github.com/evanw/esbuild#command-line-usage) documentation for the full list of available options. Note that some options like `entryPoints` or `outdir` cannot be overwritten. We rely on the Javascript API so make sure you provide the JavaScript options as they can be different to the CLI options.
The package specified in the `exclude` option is passed to esbuild as `external`, but it is not included in the function bundle either. The default value for this option is `['aws-sdk']`. You can set `exclude` to `*` to disable packaging `node_modules`.
### Examples
See [example folder](examples) for a minimal example.
See [example folder](examples) for some example configurations.
### Including extra files
### Options
All files from `package/patterns` will be included in the final build file. See [Patterns](https://serverless.com/framework/docs/providers/aws/guide/packaging#patterns).
| Option | Description | Default |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| Esbuild Options | This plugin can take almost any [Esbuild Javascript Build Option](https://esbuild.github.io/api/#build-api). See [Default Esbuild Options](#default-esbuild-options) | N/A |
| `concurrency` | The number of concurrent zip and bundle operations to run at once (This can be memory intensive). eg. `10`. _NOTE_: This will produce slower builds. | `'Infinity'` |
| `disableIncremental` | Disables the use of esbuild `incremental` compilation. | `false` |
| `exclude` | An array of dependencies to exclude from the Lambda. This is passed to the esbuild `external` option. Set to `*` to disable packaging `node_modules` | `['aws-sdk']` |
| `installExtraArgs` | Optional arguments passed to npm or yarn for `external` dependency resolution. eg. `['--legacy-peer-deps']` for npm v7+ to use legacy `peerDependency` resolution behavior | `[]` |
| `keepOutputDirectory` | Keeps the `.esbuild` output folder. Useful for debugging. | `false` |
| `nativeZip` | Uses the system's `zip` executable to create archives. _NOTE_: This will produce non-deterministic archives which causes a Serverless deployment update on every deploy. | `false` |
| `packagePath` | Path to the `package.json` file for `external` dependency resolution. | `'./package.json'` |
| `packager` | Package to use for `external` dependency resolution. Values: `npm`, `yarn`, `pnpm` | `'npm'` |
| `packagerOptions` | Extra options for packagers for `external` dependency resolution. See [Packager Options](#packager-options) | N/A |
| `watch` | Watch options for `serverless-offline`. See [Watch Options](#watch-options) | N/A |
Include/exclude is deprecated, but still supported.
#### Default Esbuild Options
The following `esbuild` options are automatically set.
| Option | Default | Notes |
| ------------- | ---------- | ---------------------------------------------------------------------- |
| `bundle` | `true` | Esbuild requires this for use with `external` |
| `entryPoints` | N/A | Cannot be overridden |
| `incremental` | N/A | Cannot be overridden. Use `disableIncremental` to disable it |
| `outDir` | N/A | Cannot be overridden |
| `platform` | `'node'` | Set to `'neutral'` to enable ESM support |
| `target` | `'node12'` | We dynamically set this. See [Supported Runtimes](#supported-runtimes) |
#### Packager Options
| Option | Description | Default |
| --------- | ----------------------------------------------------------------------------------------------------- | ----------- |
| `scripts` | A string or array of scripts to be executed, currently only supports 'scripts' for npm, pnpm and yarn | `undefined` |
#### Watch Options
| Option | Description | Default |
| --------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `pattern` | An [anymatch-compatible definition](https://github.com/es128/anymatch) for the watcher to respond to | `./\*_/_.(js\|ts)` (watches all `.js` and `.ts` files) |
| `ignore` | An [anymatch-compatible definition](https://github.com/es128/anymatch) for the watcher to ignore | `['.build', 'dist', 'node_modules', '.serverless']` |
## Supported Runtimes
This plugin will automatically set the esbuild `target` for the following supported Serverless runtimes
AWS:
| Runtime | Target |
| ------------ | -------- |
| `nodejs14.x` | `node14` |
| `nodejs12.x` | `node12` |
If you wish to use this plugin alongside non Node functions like Python or functions with images, this plugin will automatically ignore any function which does not contain a handler or use a supported Node.js runtime.
## Advanced Configuration
### Including Extra Files
[Serverless Package Configuration](https://www.serverless.com/framework/docs/providers/aws/guide/packaging#package-configuration) will behave in the same way as native packaging. You can use `patterns`, `include` and `exclude` to include extra files into your bundles.
### External Dependencies
Packages that are marked as `external` and exist in the package.json's `dependencies` will be installed and included with your build under `node_modules`. You can configure how these are installed:
Packages that are marked as `external` and exist in the package.json's `dependencies` will be installed and included with your build under `node_modules`. You can customize this with a number of options.

@@ -71,8 +144,12 @@ ```yml

esbuild:
packager: yarn # optional - npm, pnpm or yarn, default is npm
packagePath: absolute/path/to/package.json # optional - by default it looks for a package.json in the working directory
packagerOptions: # optional - packager related options, currently supports only 'scripts' for both npm, pnpm and yarn
scripts: # scripts to be executed, can be a string or array of strings
external:
- lodash
packager: yarn
packagePath: absolute/path/to/package.json
packagerOptions:
scripts:
- echo 'Hello World!'
- rm -rf node_modules
installExtraArgs:
- '--legacy-peer-deps'
```

@@ -92,18 +169,6 @@

### Passing Extra Arguments to Packager
### Esbuild Plugins
This might be required to resolve some issues on package installation.
One example is to pass `--legacy-peer-deps` to npm v7+, to use legacy `peerDependency` resolution behavior.
_Note: The [Esbuild plugins API](https://esbuild.github.io/plugins/) is still experimental_
```yml
custom:
esbuild:
installExtraArgs: # optional. Default is empty (no arguments)
- '--legacy-peer-deps'
```
### Using esbuild plugins
_Note that the plugins API is still experimental : see [the documentation page](https://esbuild.github.io/plugins/)_
You can configure esbuild plugins by passing a plugins' configuration file:

@@ -148,26 +213,2 @@

### Native Zip
If you wish to use your system's `zip` executable to create archives (can be significantly faster when working with many large archives), set the `nativeZip` option:
```yml
custom:
esbuild:
nativeZip: true
```
_NOTE_: This will produce non-deterministic archives which causes a Serverless deployment update on every deploy.
### Concurrency
If you wish to limit the concurrency of the bundling process (can be very expensive on memory), set the `concurrency` option:
```yml
custom:
esbuild:
concurrency: 10
```
_NOTE_: This will produce slower builds.
## Usage

@@ -177,24 +218,6 @@

The normal Serverless deploy procedure will automatically compile with `esbuild`:
As long as the plugin is properly installed, all regular Serverless operations `sls package`, `sls deploy`, `sls deploy function`, `sls invoke local`, `sls offline` will automatically compile using `serverless-esbuild`.
- Create the Serverless project with `serverless create -t aws-nodejs`
- Install Serverless esbuild plugin as above
- Deploy with `serverless deploy`
### Serverless Offline
### ESM Support
If you wish to enable ESM support you may set the esbuild [platform](https://esbuild.github.io/api/#platform) option to `neutral`. This is set to `node` by default.
### Usage with non Node functions
If you wish to use this plugin alongside non Node functions like Python, this plugin will automatically ignore any function which does not contain a handler or use a supported Node.js runtime.
Current supported runtimes:
- AWS
- nodejs14.x
- nodejs12.x
### Usage with serverless-offline
The plugin integrates very well with [serverless-offline](https://github.com/dherault/serverless-offline) to

@@ -218,12 +241,5 @@ simulate AWS Lambda and AWS API Gateway locally.

Automatic compilation is available while using the plugin with `serverless-offline`. Following are the default configuration:
Automatic compilation is available while using the plugin with `serverless-offline`.
```
pattern: './**/*.(js|ts)' # watches all javascript or typescripts files in the project
ignore: [.build, 'dist', 'node_modules', '.serverless']
```
You can override the defaults by using `watch` option in serverless esbuild config. Both options take [anymatch-compatible definition] (https://github.com/es128/anymatch)
```
custom:

@@ -236,5 +252,5 @@ esbuild:

Note: When overriding ignore pattern, remember to ignore `.build` directory to avoid endless compilation.
Note: When overriding the ignore pattern, remember to ignore `.build` directory to avoid endless compilation.
#### serverless-dynamodb-local
#### Serverless Dynamodb Local

@@ -253,29 +269,8 @@ Configure your service the same as mentioned above, but additionally add the `serverless-dynamodb-local`

### Run a function locally
### Invoke Local
To run your compiled functions locally you can:
This plugin supports the Serverless [Invoke Local](https://www.serverless.com/framework/docs/providers/aws/cli-reference/invoke-local) functionality and will automatically compile the selected function.
```bash
$ serverless invoke local --function <function-name>
```
## External Tools
Options are:
- `--function` or `-f` (required) is the name of the function to run
- `--path` or `-p` (optional) path to JSON or YAML file holding input data
- `--data` or `-d` (optional) input data
## Plugin-Specific Options in Serverless Config
These options belong under `custom.esbuild` in your `serverless.yml` or `serverless.ts` file, and are specific to this plugin (these are not esbuild API options):
- `packager`: Package to use (npm, pnpm or yarn - npm is default)
- `packagePath`: Path to the `package.json` file (`./package.json` is default)
- `packagerOptions`:
- `scripts`: A string or array of scripts to be executed, currently only supports 'scripts' for npm, pnpm and yarn
- `exclude`: An array of dependencies to exclude (declares it as an external as well as excludes it from Lambda ZIP file)
- `installExtraArgs`: Optional arguments passed to npm or yarn (empty is default)
## External tools
- [`serverless-analyze-bundle-plugin`](https://github.com/adriencaccia/serverless-analyze-bundle-plugin): a plugin that allow users to analyze the bundle of a lambda

@@ -282,0 +277,0 @@