Skip to content

Commit

Permalink
Merge pull request #111 from kabo/master
Browse files Browse the repository at this point in the history
fix: #110 package.patterns
  • Loading branch information
floydspace authored Apr 13, 2021
2 parents 2a64b18 + 7cbbf1f commit a78b5f6
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 22 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ 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).

Include/exclude is deprecated, but still supported.

### External Dependencies

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
62 changes: 48 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { build, BuildResult, BuildOptions } from 'esbuild';
import * as fs from 'fs-extra';
import * as globby from 'globby';
import * as path from 'path';
import { mergeRight } from 'ramda';
import { concat, mergeRight } from 'ramda';
import * as Serverless from 'serverless';
import * as Plugin from 'serverless/classes/Plugin';
import * as chokidar from 'chokidar';
Expand Down Expand Up @@ -170,17 +170,30 @@ export class EsbuildPlugin implements Plugin {
fs.mkdirpSync(this.buildDirPath);
fs.mkdirpSync(path.join(this.workDirPath, SERVERLESS_FOLDER));
// exclude serverless-esbuild
this.serverless.service.package = {
...(this.serverless.service.package || {}),
patterns: [
...new Set([
...(this.serverless.service.package?.include || []),
...(this.serverless.service.package?.exclude || []).map(concat('!')),
...(this.serverless.service.package?.patterns || []),
'!node_modules/serverless-esbuild',
]),
]
};

for (const fnName in this.functions) {
const fn = this.serverless.service.getFunction(fnName);
fn.package = fn.package || {
exclude: [],
include: [],
fn.package = {
...(fn.package || {}),
patterns: [
...new Set([
...(fn.package?.include || []),
...(fn.package?.exclude || []).map(concat('!')),
...(fn.package?.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']),
];
}
}

Expand Down Expand Up @@ -221,13 +234,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.length > 0) {
const files = await globby(service.package.patterns);

for (const filename of files) {
const destFileName = path.resolve(path.join(this.buildDirPath, filename));
Expand All @@ -238,7 +251,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 === 0) {
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);
}
}
}
Expand Down
22 changes: 17 additions & 5 deletions src/pack.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as fs from 'fs-extra';
import * as glob from 'glob';
import * as path from 'path';
import { intersection, isEmpty, path as get, without } from 'ramda';
import { intersection, isEmpty, lensProp, map, over, path as get, pipe, reject, replace, test, without } from 'ramda';
import * as semver from 'semver';
import { EsbuildPlugin, SERVERLESS_FOLDER } from '.';
import { doSharePath, flatDep, getDepsFromBundle } from './helper';
import * as Packagers from './packagers';
import { IFiles } from './types';
import { humanSize, zip } from './utils';

function setFunctionArtifactPath(this: EsbuildPlugin, func, artifactPath) {
Expand Down Expand Up @@ -38,7 +39,7 @@ export async function pack(this: EsbuildPlugin) {
);

// get a list of all path in build
const files: { localPath: string; rootPath: string }[] = glob
const files: IFiles = glob
.sync('**', {
cwd: this.buildDirPath,
dot: true,
Expand All @@ -57,8 +58,14 @@ export async function pack(this: EsbuildPlugin) {
const zipName = `${this.serverless.service.service}.zip`;
const artifactPath = path.join(this.workDirPath, SERVERLESS_FOLDER, zipName);

// remove prefixes from individual extra files
const filesPathList = pipe<IFiles, IFiles, IFiles>(
reject(test(/^__only_[^/]+$/)) as (x: IFiles) => IFiles,
map(over(lensProp('localPath'), replace(/^__only_[^/]+\//, '')))
)(files);

const startZip = Date.now();
await zip(artifactPath, files);
await zip(artifactPath, filesPathList);
const { size } = fs.statSync(artifactPath);

this.serverless.cli.log(
Expand Down Expand Up @@ -107,10 +114,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
Expand All @@ -123,7 +133,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);
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type JSONObject = any;

export interface IFile {
readonly localPath: string
readonly rootPath: string
}
export type IFiles = readonly IFile[];
3 changes: 2 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as childProcess from 'child_process';
import * as fs from 'fs-extra';
import * as path from 'path';
import { join } from 'ramda';
import { IFiles } from './types';

export class SpawnError extends Error {
constructor(message: string, public stdout: string, public stderr: string) {
Expand Down Expand Up @@ -91,7 +92,7 @@ export const humanSize = (size: number) => {
return `${sanitized} ${['B', 'KB', 'MB', 'GB', 'TB'][i]}`;
};

export const zip = (zipPath: string, filesPathList: { rootPath: string; localPath: string }[]) => {
export const zip = (zipPath: string, filesPathList: IFiles) => {
fs.mkdirpSync(path.dirname(zipPath));

const zip = archiver.create('zip');
Expand Down

0 comments on commit a78b5f6

Please sign in to comment.