diff --git a/README.md b/README.md index a3c8d223..230cd6d1 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ See [example folder](example) for a minimal example. ### Including extra files -All files from `package/include` will be included in the final build file. See [Exclude/Include](https://serverless.com/framework/docs/providers/aws/guide/packaging#exclude--include) +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) ### External Dependencies diff --git a/package.json b/package.json index bd9eb330..7c524b23 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@types/jest": "^26.0.14", "@types/node": "^12.12.38", "@types/ramda": "^0.27.6", - "@types/serverless": "^1.78.18", + "@types/serverless": "^1.78.25", "@typescript-eslint/eslint-plugin": "^4.2.0", "@typescript-eslint/parser": "^4.2.0", "eslint": "^7.9.0", diff --git a/src/index.ts b/src/index.ts index cc61cd1d..4cfc708b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -172,13 +172,12 @@ export class EsbuildPlugin implements Plugin { for (const fnName in this.functions) { const fn = this.serverless.service.getFunction(fnName); fn.package = fn.package || { - exclude: [], - include: [], + patterns: [], }; // Add plugin to excluded packages or an empty array if exclude is undefined - fn.package.exclude = [ - ...new Set([...(fn.package.exclude || []), 'node_modules/serverless-esbuild']), + fn.package.patterns = [ + ...new Set([ ...(fn.package.patterns || []), '!node_modules/serverless-esbuild' ]), ]; } } @@ -216,13 +215,13 @@ export class EsbuildPlugin implements Plugin { }); } - /** Link or copy extras such as node_modules or package.include definitions */ + /** Link or copy extras such as node_modules or package.patterns definitions */ async copyExtras() { const { service } = this.serverless; - // include any "extras" from the "include" section - if (service.package.include && service.package.include.length > 0) { - const files = await globby(service.package.include); + // include any "extras" from the "patterns" section + if (service.package.patterns && service.package.patterns.length > 0) { + const files = await globby(service.package.patterns); for (const filename of files) { const destFileName = path.resolve(path.join(this.buildDirPath, filename)); @@ -233,7 +232,28 @@ export class EsbuildPlugin implements Plugin { } if (!fs.existsSync(destFileName)) { - fs.copySync(path.resolve(filename), path.resolve(path.join(this.buildDirPath, filename))); + fs.copySync(path.resolve(filename), destFileName); + } + } + } + + // include any "extras" from the individual function "patterns" section + for (const fnName in this.functions) { + const fn = this.serverless.service.getFunction(fnName); + if (!fn.package?.patterns?.length) { + continue; + } + const files = await globby(fn.package.patterns); + for (const filename of files) { + const destFileName = path.resolve(path.join(this.buildDirPath, `__only_${fn.name}`, filename)); + const dirname = path.dirname(destFileName); + + if (!fs.existsSync(dirname)) { + fs.mkdirpSync(dirname); + } + + if (!fs.existsSync(destFileName)) { + fs.copySync(path.resolve(filename), destFileName); } } } diff --git a/src/pack.ts b/src/pack.ts index 6ba764c4..4dca3ddf 100644 --- a/src/pack.ts +++ b/src/pack.ts @@ -107,10 +107,13 @@ export async function pack(this: EsbuildPlugin) { const artifactPath = path.join(this.workDirPath, SERVERLESS_FOLDER, zipName); // filter files - const filesPathList = files.filter(({ rootPath, localPath }) => { + const filesPathList = files.filter(({ localPath }) => { // exclude non individual files based on file path (and things that look derived, e.g. foo.js => foo.js.map) if (excludedFiles.find(p => localPath.startsWith(p))) return false; + // exclude files that belong to individual functions + if (localPath.startsWith('__only_') && !localPath.startsWith(`__only_${name}/`)) return false; + // exclude non whitelisted dependencies if (localPath.startsWith('node_modules')) { // if no externals is set or if the provider is google, we do not need any files from node_modules @@ -123,7 +126,9 @@ export async function pack(this: EsbuildPlugin) { } return true; - }); + }) + // remove prefix from individual function extra files + .map(({localPath, ...rest}) => ({ localPath: localPath.replace(`__only_${name}/`, ''), ...rest})); const startZip = Date.now(); await zip(artifactPath, filesPathList);