Socket
Socket
Sign inDemoInstall

serverless-plugin-include-dependencies

Package Overview
Dependencies
110
Maintainers
3
Versions
30
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.1.0 to 5.0.0

23

get-dependency-list.js

@@ -16,8 +16,6 @@ 'use strict';

module.exports = function(filename, serverless) {
module.exports = function(filename, serverless, cache) {
const servicePath = serverless.config.servicePath;
const modulePaths = new Set();
const filePaths = new Set();
const modulePaths = new Set();
const modulesToProcess = [];

@@ -28,3 +26,8 @@ const localFilesToProcess = [filename];

const moduleName = requirePackageName(name.replace(/\\/, '/'));
const cacheKey = `${basedir}:${name}`;
if (cache && cache.has(cacheKey)) {
return;
}
try {

@@ -36,2 +39,7 @@ const pathToModule = resolve.sync(path.join(moduleName, 'package.json'), { basedir });

modulesToProcess.push(pkg);
if (cache) {
cache.add(cacheKey);
}
} else {

@@ -50,5 +58,10 @@ // TODO: should we warn here?

localFilesToProcess.push(resolved);
if (cache) {
cache.add(cacheKey);
}
return;
} catch(e) {
throw new Error(`[serverless-plugin-include-dependencies]: Could not find ${moduleName}`);
throw new Error(`[serverless-plugin-include-dependencies]: Could not find npm package: ${moduleName}`);
}

@@ -55,0 +68,0 @@ }

@@ -7,10 +7,18 @@ 'use strict';

const micromatch = require('micromatch');
const glob = require('glob');
const fs = require('fs');
const getDependencyList = require('./get-dependency-list');
function union(a, b) {
const arr = a || [];
return Array.from(new Set(arr.concat(b || [])));
function union(a = [], b = []) {
const existing = [].concat(a);
const set = new Set(existing);
[].concat(b).forEach(p => {
if (set.has(p)) {
return;
}
set.add(p);
existing.push(p);
});
return existing;
}

@@ -21,4 +29,4 @@

constructor(serverless, options) {
if (!semver.satisfies(serverless.version, '>= 1.13')) {
throw new Error('serverless-plugin-include-dependencies requires serverless 1.13 or higher!');
if (!semver.satisfies(serverless.version, '>= 2.32')) {
throw new Error('serverless-plugin-include-dependencies requires serverless 2.32 or higher!');
}

@@ -28,3 +36,7 @@

this.options = options;
this.cache = new Set();
const service = this.serverless.service;
this.individually = service.package && service.package.individually;
this.hooks = {

@@ -41,7 +53,7 @@ 'before:deploy:function:packageFunction': this.functionDeploy.bind(this),

createDeploymentArtifacts() {
const service = this.serverless.service;
if (typeof service.functions === 'object') {
Object.keys(service.functions).forEach(functionName => {
this.processFunction(functionName);
});
const { service = {} } = this.serverless;
const { functions = {} } = service;
for (const functionName in functions) {
this.processFunction(functionName);
}

@@ -51,14 +63,11 @@ }

processFunction(functionName) {
const service = this.serverless.service;
const { service = {} } = this.serverless;
service.package = service.package || {};
service.package.patterns = union(['!node_modules/**'], service.package.patterns);
const functionObject = service.functions[functionName];
const runtime = this.getFunctionRuntime(functionObject);
functionObject.package = functionObject.package || {};
service.package = service.package || {};
service.package.exclude = union(service.package.exclude, ['node_modules/**']);
if (runtime === 'provided' || runtime.match(/nodejs*/)) {
this.processIncludes(functionObject);
if (/(provided|nodejs)+/.test(runtime)) {
this.processNodeFunction(functionObject);

@@ -68,23 +77,2 @@ }

includeGlobs(target, include, exclude) {
include.forEach(includeGlob => {
this.include(target, [includeGlob]);
glob.sync(path.join(this.serverless.config.servicePath, includeGlob))
.filter(p => !exclude.some(e => {
if (e.indexOf('node_modules') !== 0 || e === 'node_modules' || e === 'node_modules/**') {
return false;
}
return micromatch.contains(p, e);
}))
.forEach(filePath => {
var stat = fs.statSync(filePath);
if (stat && stat.isFile()) {
const dependencies = this.getDependencies(filePath, exclude);
this.include(target, dependencies);
}
});
}
);
}
getPluginOptions() {

@@ -95,38 +83,16 @@ const service = this.serverless.service;

processIncludes(functionObject) {
const service = this.serverless.service;
const options = this.getPluginOptions();
if (!options || !options.always) {
return;
}
const include = union(options.always, []);
if (service.package && service.package.individually) {
const exclude = union(service.package.exclude, functionObject.package.exclude);
this.includeGlobs(functionObject, include, exclude);
} else {
const exclude = service.package.exclude || [];
this.includeGlobs(service, include, exclude);
}
}
processNodeFunction(functionObject) {
const service = this.serverless.service;
const { service } = this.serverless;
functionObject.package = functionObject.package || {};
const fileName = this.getHandlerFilename(functionObject.handler);
const dependencies = this.getDependencies(fileName, service.package.patterns);
if (service.package && service.package.individually) {
const exclude = union(service.package.exclude, functionObject.package.exclude);
const dependencies = this.getDependencies(fileName, exclude);
this.include(functionObject, dependencies);
} else {
const exclude = service.package.exclude;
const dependencies = this.getDependencies(fileName, exclude);
this.include(service, dependencies);
}
const target = this.individually ? functionObject : service;
target.package.patterns = union(target.package.patterns, dependencies);
}
getFunctionRuntime(functionObject) {
const service = this.serverless.service;
const { service } = this.serverless;

@@ -136,32 +102,36 @@ const functionRuntime = functionObject.runtime;

return functionRuntime || providerRuntime || 'nodejs4.3';
return functionRuntime || providerRuntime;
}
getHandlerFilename(handler) {
const handlerPath = handler.slice(0, handler.lastIndexOf('.'));
const lastDotIndex = handler.lastIndexOf('.');
const handlerPath = lastDotIndex !== -1 ? handler.slice(0, lastDotIndex) : 'index';
return require.resolve((path.join(this.serverless.config.servicePath, handlerPath)));
}
getDependencies(fileName, exclude) {
getDependencies(fileName, patterns) {
const servicePath = this.serverless.config.servicePath;
const dependencies = this.getDependencyList(fileName);
const relativeDependencies = dependencies.map(p => path.relative(servicePath, p));
const relativeDependencies = dependencies.map(p => path.relative(servicePath, p));
const exclusions = exclude.filter(e => {
return !(e.indexOf('node_modules') !== 0 || e === 'node_modules' || e === 'node_modules/**');
const exclusions = patterns.filter(p => {
return !(p.indexOf('!node_modules') !== 0 || p === '!node_modules' || p === '!node_modules/**');
});
return relativeDependencies.filter(p => {
return !micromatch.some(p, exclusions);
});
if (exclusions.length > 0) {
return micromatch(relativeDependencies, exclusions);
}
return relativeDependencies;
}
getDependencyList(fileName) {
if (!this.individually) {
const options = this.getPluginOptions();
if (options && options.enableCaching) {
return getDependencyList(fileName, this.serverless, this.cache);
}
}
return getDependencyList(fileName, this.serverless);
}
include(target, dependencies) {
target.package.include = union(target.package.include, dependencies);
}
};
{
"name": "serverless-plugin-include-dependencies",
"version": "4.1.0",
"version": "5.0.0",
"engines": {

@@ -25,12 +25,11 @@ "node": ">=4.0"

"ava": "^3.0.0",
"eslint": "^6.8.0",
"eslint": "^7.30.0",
"lodash": "^4.17.11",
"nyc": "^15.0.0",
"sinon": "^8.1.1",
"sinon": "^11.1.1",
"updater-contributors": "^0.1.2"
},
"dependencies": {
"glob": "^7.1.6",
"micromatch": "^4.0.2",
"precinct": "^6.2.0",
"precinct": "^8.1.0",
"read-pkg-up": "^7.0.1",

@@ -37,0 +36,0 @@ "require-package-name": "^2.0.1",

# serverless-plugin-include-dependencies
> Note: This plugin no longer excludes the `aws-sdk` to stay in line with AWS best practices (bring your own SDK)
This is a Serverless plugin that should make your deployed functions smaller. It does this by excluding `node_modules` then individually adds each module file that your handler depends on.
This is a Serverless plugin that should make your deployed functions smaller.
As of 5.0.0 this plugin uses the `package.patterns` property. `always` is no longer supported as it should be possible with just package.patterns
It does this by enabling you to add your `node_modules` folder to the `exclude` list, then it individually adds each module that your handler depends on.
> Note: This plugin no longer excludes the `aws-sdk` to stay in line with AWS best practices (bring your own SDK)

@@ -20,3 +20,3 @@ If you use this plugin, you should disable the built-in Serverless option for excluding development dependencies, which is slower anyway:

First install the plugin via NPM.
First install the plugin via npm.

@@ -41,13 +41,9 @@ ```

package:
exclude:
- node_modules/** # no need to add this yourself, this plugin does it for you
patterns:
- '!node_modules/**' # no need to add this, this plugin does it for you
plugins:
- serverless-plugin-common-excludes # this should go before serverless-plugin-include-dependencies
- serverless-plugin-include-dependencies
custom:
includeDependencies:
always:
- 'src/lib/**' # (optional) always include these globs and their dependencies
functions:

@@ -68,18 +64,28 @@ foo:

## Dependency caching (Experimental)
When building a shared bundle for several functions, execution time can be reduced by enabling dependency caching. Caching is disabled by default and can be enabled using the `enableCaching` option:
```yaml
custom:
includeDependencies:
enableCaching: true
```
## New In 2.0 - Exclusion Support
Rather than including module folders (e.g. `node_modules/foo/**`, it now includes a list of actual files (e.g. `node_modules/foo/package.json`, `node_modules/foo/index.js`) and *uses the serverless package exclude* to filter these files. Excludes *must* start with `node_modules` to be considered by this plugin.
Rather than including module folders (e.g. `node_modules/foo/**`, it now includes a list of actual files (e.g. `node_modules/foo/package.json`, `node_modules/foo/index.js`) and *uses the serverless package patterns* to filter these files. Patterns *must* start with `!node_modules` to be considered by this plugin.
The following examples would filter files of your module dependencies:
- `node_modules/**/README.*`
- `node_modules/**/test/**`
- `!node_modules/**/README.*`
- `!node_modules/**/test/**`
These would not:
- `README`
- `**/*.txt`
- `!README`
- `!**/*.txt`
Even though normal matching libraries would match these rules, this library ignores them so that there's no chance of local excludes conflicting with node_modules excludes.
Unless you know exactly where dependencies will be installed (e.g. several things could depend on aws-sdk) you probably want a rule more like `node_modules/**/aws-sdk/**` (which will exclude all instances of aws-sdk) and not `node_modules/aws-sdk/**` (which would only exclude a top-level aws-sdk)
Unless you know exactly where dependencies will be installed (e.g. several things could depend on aws-sdk) you probably want a rule more like `!node_modules/**/foo/**` (which will exclude all instances of foo) and not `node_modules/foo/**` (which would only exclude a top-level foo)
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc