UNPKG

3.42 kBJavaScriptView Raw
1'use strict';
2
3const path = require('path');
4
5const semver = require('semver');
6const micromatch = require('micromatch');
7
8const getDependencyList = require('./get-dependency-list');
9
10function union(a, b) {
11 const arr = a || [];
12 return Array.from(new Set(arr.concat(b || [])));
13}
14
15module.exports = class IncludeDependencies {
16
17 constructor(serverless, options) {
18 if (!semver.satisfies(serverless.version, '>= 1.2')) {
19 throw new Error('serverless-plugin-include-dependencies requires serverless 1.2 or higher!');
20 }
21 this.serverless = serverless;
22 this.options = options;
23 this.hooks = {
24 'before:deploy:function:packageFunction': this.functionDeploy.bind(this),
25 'before:deploy:createDeploymentArtifacts': this.createDeploymentArtifacts.bind(this)
26 };
27 }
28
29 functionDeploy() {
30 return this.processFunction(this.options.function);
31 }
32
33 createDeploymentArtifacts() {
34 const service = this.serverless.service;
35 if (typeof service.functions === 'object') {
36 Object.keys(service.functions).forEach(functionName => {
37 this.processFunction(functionName);
38 });
39 }
40 }
41
42 processFunction(functionName) {
43 const service = this.serverless.service;
44
45 const functionObject = service.functions[functionName];
46 const runtime = this.getFunctionRuntime(functionObject);
47
48 functionObject.package = functionObject.package || {};
49
50 service.package = service.package || {};
51 service.package.exclude = union(service.package.exclude, ['node_modules/**']);
52
53 if (runtime.match(/nodejs*/)) {
54 this.processNodeFunction(functionObject);
55 }
56 }
57
58 processNodeFunction(functionObject) {
59 const service = this.serverless.service;
60
61 const fileName = this.getHandlerFilename(functionObject.handler);
62
63 if (service.package && service.package.individually) {
64 const exclude = union(service.package.exclude, functionObject.exclude);
65 const dependencies = this.getDependencies(fileName, exclude);
66
67 this.include(functionObject, dependencies);
68 } else {
69 const exclude = service.package.exclude;
70 const dependencies = this.getDependencies(fileName, exclude);
71
72 this.include(service, dependencies);
73 }
74 }
75
76 getFunctionRuntime(functionObject) {
77 const service = this.serverless.service;
78
79 const functionRuntime = functionObject.runtime;
80 const providerRuntime = service.provider && service.provider.runtime;
81
82 return functionRuntime || providerRuntime || 'nodejs4.3';
83 }
84
85 getHandlerFilename(handler) {
86 const handlerPath = handler.slice(0, handler.lastIndexOf('.'));
87 return require.resolve((path.join(this.serverless.config.servicePath, handlerPath)));
88 }
89
90 getDependencies(fileName, exclude) {
91 const servicePath = this.serverless.config.servicePath;
92 const dependencies = this.getDependencyList(fileName);
93
94 const relativeDependencies = dependencies.map(p => path.relative(servicePath, p));
95
96 return relativeDependencies.filter(p => {
97 return !exclude.some(e => {
98 if (e.indexOf('node_modules') !== 0 || e === 'node_modules' || e === 'node_modules/**') {
99 return false;
100 }
101
102 return micromatch.contains(p, e);
103 });
104 });
105 }
106
107 getDependencyList(fileName) {
108 return getDependencyList(fileName, this.serverless);
109 }
110
111 include(target, dependencies) {
112 target.package.include = union(target.package.include, dependencies);
113 }
114
115};