Skip to content

Commit

Permalink
fix: cache usage of modern-node-polyfills API (#115)
Browse files Browse the repository at this point in the history
Co-authored-by: parbez <imranbarbhuiya.fsd@gmail.com>
  • Loading branch information
markdalgleish and imranbarbhuiya authored Jun 20, 2023
1 parent ddfe4db commit c71714f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
12 changes: 5 additions & 7 deletions src/lib/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { builtinModules } from 'node:module';
import path from 'node:path';

import { polyfillContent, polyfillPath } from 'modern-node-polyfills';

import { escapeRegex, commonJsTemplate, removeEndingSlash } from './utils/util.js';
import { escapeRegex, commonJsTemplate, getCachedPolyfillPath, getCachedPolyfillContent } from './utils/util.js';

import type { OnResolveArgs, Plugin } from 'esbuild';
import type esbuild from 'esbuild';
Expand All @@ -19,9 +17,7 @@ const loader = async (args: esbuild.OnLoadArgs): Promise<esbuild.OnLoadResult> =
try {
const isCommonjs = args.namespace.endsWith('commonjs');

const resolved = await polyfillPath(removeEndingSlash(args.path));
const contents = (await polyfillContent(removeEndingSlash(args.path))).replaceAll('eval(', '(0,eval)(');

const resolved = await getCachedPolyfillPath(args.path);
const resolveDir = path.dirname(resolved);

if (isCommonjs) {
Expand All @@ -34,6 +30,8 @@ const loader = async (args: esbuild.OnLoadArgs): Promise<esbuild.OnLoadResult> =
};
}

const contents = await getCachedPolyfillContent(args.path);

return {
loader: 'js',
contents,
Expand Down Expand Up @@ -72,7 +70,7 @@ export const nodeModulesPolyfillPlugin = (options: NodePolyfillsOptions = {}): P
const resolver = async (args: OnResolveArgs) => {
const ignoreRequire = args.namespace === commonjsNamespace;

const pollyfill = await polyfillPath(args.path).catch(() => null);
const pollyfill = await getCachedPolyfillPath(args.path).catch(() => null);

if (!pollyfill) {
return;
Expand Down
43 changes: 39 additions & 4 deletions src/lib/utils/util.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
/* eslint-disable unicorn/prefer-string-replace-all -- node v14 doesn't supports string.replaceAll*/
import { polyfillContent, polyfillPath } from 'modern-node-polyfills';

export const escapeRegex = (str: string) => {
return str.replace(/[$()*+.?[\\\]^{|}]/g, '\\$&').replace(/-/g, '\\x2d');
};

export const removeEndingSlash = (str: string) => {
return str.replace(/\/$/, '');
};

export const commonJsTemplate = ({ importPath }: { importPath: string }) => {
return `
const polyfill = require('${importPath}')
Expand All @@ -20,3 +18,40 @@ if (polyfill && polyfill.default) {
}
`;
};

const normalizeNodeBuiltinPath = (path: string) => {
return path.replace(/^node:/, '').replace(/\/$/, '');
};

const polyfillPathCache: Map<string, Promise<string>> = new Map();
export const getCachedPolyfillPath = (_importPath: string): Promise<string> => {
const normalizedImportPath = normalizeNodeBuiltinPath(_importPath);

const cachedPromise = polyfillPathCache.get(normalizedImportPath);
if (cachedPromise) {
return cachedPromise;
}

const promise = polyfillPath(normalizedImportPath);
polyfillPathCache.set(normalizedImportPath, promise);
return promise;
};

const polyfillContentAndTransform = async (importPath: string) => {
const content = await polyfillContent(importPath);
return content.replace(/eval\(/g, '(0,eval)(');
};

const polyfillContentCache: Map<string, Promise<string>> = new Map();
export const getCachedPolyfillContent = (_importPath: string): Promise<string> => {
const normalizedImportPath = normalizeNodeBuiltinPath(_importPath);

const cachedPromise = polyfillContentCache.get(normalizedImportPath);
if (cachedPromise) {
return cachedPromise;
}

const promise = polyfillContentAndTransform(normalizedImportPath);
polyfillContentCache.set(normalizedImportPath, promise);
return promise;
};

0 comments on commit c71714f

Please sign in to comment.