Skip to content

Commit

Permalink
feat: support same allowList options as webpack-node-externals (#50)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Sprouse <[email protected]>
  • Loading branch information
pradel and asprouse authored Nov 20, 2023
1 parent d038f1e commit 2dde999
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
2 changes: 1 addition & 1 deletion esbuild-node-externals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Make package.json `optionalDependencies` external.

#### `options.allowList` (default to `[]`)

Specify packages which are not marked as external. They will be included in the bundle.
An array for the externals to allow, so they will be included in the bundle. Can accept exact strings ('module_name'), regex patterns (/^module_name/), or a function that accepts the module name and returns whether it should be included.

#### `options.allowWorkspaces` (default to `false`)

Expand Down
17 changes: 12 additions & 5 deletions esbuild-node-externals/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import type { Plugin } from 'esbuild';

import { findPackagePaths, findDependencies } from './utils';
import {
findPackagePaths,
findDependencies,
AllowList,
createAllowPredicate,
} from './utils';

export interface Options {
packagePath?: string | string[];
dependencies?: boolean;
devDependencies?: boolean;
peerDependencies?: boolean;
optionalDependencies?: boolean;
allowList?: string[];
allowList?: AllowList;
allowWorkspaces?: boolean;
}

Expand All @@ -18,7 +23,6 @@ export const nodeExternalsPlugin = (paramsOptions: Options = {}): Plugin => {
devDependencies: true,
peerDependencies: true,
optionalDependencies: true,
allowList: [] as string[],
allowWorkspaces: false,
...paramsOptions,
packagePath:
Expand All @@ -27,6 +31,9 @@ export const nodeExternalsPlugin = (paramsOptions: Options = {}): Plugin => {
: (paramsOptions.packagePath as string[] | undefined),
};

const allowPredicate =
options.allowList && createAllowPredicate(options.allowList);

const nodeModules = findDependencies({
packagePaths: options.packagePath
? options.packagePath
Expand All @@ -35,7 +42,7 @@ export const nodeExternalsPlugin = (paramsOptions: Options = {}): Plugin => {
devDependencies: options.devDependencies,
peerDependencies: options.peerDependencies,
optionalDependencies: options.optionalDependencies,
allowList: options.allowList,
allowPredicate,
allowWorkspaces: options.allowWorkspaces,
});

Expand All @@ -45,7 +52,7 @@ export const nodeExternalsPlugin = (paramsOptions: Options = {}): Plugin => {
// On every module resolved, we check if the module name should be an external
build.onResolve({ namespace: 'file', filter: /.*/ }, (args) => {
// To allow allowList to target sub imports
if (options.allowList.includes(args.path)) {
if (allowPredicate?.(args.path)) {
return null;
}

Expand Down
35 changes: 28 additions & 7 deletions esbuild-node-externals/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ import path from 'path';
import fs from 'fs';
import findUp from 'find-up';

export type AllowPredicate = (path: string) => boolean;
export type AllowList = (string | RegExp)[] | AllowPredicate;

export const createAllowPredicate = (allowList: AllowList): AllowPredicate => {
return typeof allowList === 'function'
? allowList
: (path: string) =>
Boolean(
allowList.find((pattern) =>
typeof pattern === 'string' ? path === pattern : pattern.test(path)
)
);
};

/**
* Determines if the `child` path is under the `parent` path.
*/
Expand Down Expand Up @@ -43,7 +57,10 @@ export const findPackagePaths = (): string[] => {
return packagePaths;
};

function getDependencyKeys(map: Record<string, string> = {}, allowWorkspaces: boolean = false): string[] {
function getDependencyKeys(
map: Record<string, string> = {},
allowWorkspaces: boolean = false
): string[] {
if (!map) {
return [];
}
Expand All @@ -63,7 +80,7 @@ export const findDependencies = (options: {
devDependencies: boolean;
peerDependencies: boolean;
optionalDependencies: boolean;
allowList: string[];
allowPredicate?: AllowPredicate | undefined;
allowWorkspaces: boolean;
}): string[] => {
const packageJsonKeys = [
Expand All @@ -85,11 +102,15 @@ export const findDependencies = (options: {
);
}

return packageJsonKeys
// Automatically exclude keys for interconnected yarn workspaces.
.map((key) => getDependencyKeys(packageJson[key], options.allowWorkspaces))
.flat(1)
.filter((packageName) => !options.allowList.includes(packageName));
const packageNames = packageJsonKeys
.map((key) =>
getDependencyKeys(packageJson[key], options.allowWorkspaces)
)
.flat(1);
const { allowPredicate } = options;
return allowPredicate
? packageNames.filter((packageName) => !allowPredicate(packageName))
: packageNames;
});

return data.flat(1);
Expand Down

0 comments on commit 2dde999

Please sign in to comment.