Skip to content

Commit

Permalink
enhancement/issue 684 import map generation cache and dedupe optimiza…
Browse files Browse the repository at this point in the history
…tions (#1377)
  • Loading branch information
thescientist13 authored Jan 18, 2025
1 parent 3f93860 commit 2037d3b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 22 deletions.
41 changes: 20 additions & 21 deletions packages/cli/src/lib/walker-package-ranger.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import fs from 'fs';
// priority if from L -> R
const SUPPORTED_EXPORT_CONDITIONS = ['import', 'module-sync', 'default'];
const IMPORT_MAP_RESOLVED_PREFIX = '/~';
const importMap = {};
const importMap = new Map();
const diagnostics = {};

function updateImportMap(key, value, resolvedRoot) {
if (!importMap[key.replace('./', '')]) {
importMap[key.replace('./', '')] = `${IMPORT_MAP_RESOLVED_PREFIX}${resolvedRoot.replace('file://', '')}${value.replace('./', '')}`;
}
importMap.set(
key.replace('./', ''),
`${IMPORT_MAP_RESOLVED_PREFIX}${resolvedRoot.replace('file://', '')}${value.replace('./', '')}`
);
}

// wrapper around import.meta.resolve to provide graceful error handling / logging
Expand Down Expand Up @@ -68,7 +69,7 @@ function derivePackageRoot(resolved) {
return root;
}

// Helper function to convert export patterns to a regex (thanks ChatGPT :D)
// helper function to convert export patterns to a regex (thanks ChatGPT :D)
function globToRegex(pattern) {
// Escape special regex characters
pattern = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&');
Expand All @@ -83,7 +84,7 @@ function globToRegex(pattern) {
return new RegExp('^' + pattern + '$');
}

// convert path to its lowest common root
// helper function to convert path to its lowest common root
// e.g. ./img/path/*/index.js -> /img/path
// https://unpkg.com/browse/@uswds/[email protected]/package.json
function patternRoot(pattern) {
Expand Down Expand Up @@ -209,30 +210,28 @@ async function walkPackageForExports(dependency, packageJson, resolvedRoot) {
}
}

// https://nodejs.org/api/packages.html#package-entry-points
async function walkPackageJson(packageJson = {}) {
// we recursively cache / memoize walkedPackages to account for scenarios where Greenwood can (pre)render concurrently
async function walkPackageJson(packageJson = {}, walkedPackages = new Set()) {

try {
for (const dependency of Object.keys(packageJson.dependencies || {})) {
const dependencies = Object.keys(packageJson.dependencies || {});

for (const dependency of dependencies) {
const resolved = resolveBareSpecifier(dependency);

if (resolved) {
const resolvedRoot = derivePackageRoot(resolved);
const resolvedPackageJson = (await import(new URL('./package.json', resolvedRoot), { with: { type: 'json' } })).default;

walkPackageForExports(dependency, resolvedPackageJson, resolvedRoot);

if (resolvedPackageJson.dependencies) {
for (const dependency in resolvedPackageJson.dependencies) {
const resolved = resolveBareSpecifier(dependency);
if (resolvedRoot) {
const resolvedPackageJson = (await import(new URL('./package.json', resolvedRoot), { with: { type: 'json' } })).default;
const { name } = resolvedPackageJson;

if (resolved) {
const resolvedRoot = derivePackageRoot(resolved);
const resolvedPackageJson = (await import(new URL('./package.json', resolvedRoot), { with: { type: 'json' } })).default;
walkPackageForExports(dependency, resolvedPackageJson, resolvedRoot);

walkPackageForExports(dependency, resolvedPackageJson, resolvedRoot);
if (!walkedPackages.has(name)) {
walkedPackages.add(name);

await walkPackageJson(resolvedPackageJson);
}
await walkPackageJson(resolvedPackageJson, walkedPackages);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/src/plugins/resource/plugin-node-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,16 @@ class NodeModulesResource extends ResourceInterface {

if (Object.keys(diagnostics).length > 0) {
console.log('****************************************************************************');

Object.keys(diagnostics).forEach((diagnostic) => {
console.warn(diagnostics[diagnostic]);
});

console.log('Learn more about these warnings at => https://greenwoodjs.dev/docs/introduction/web-standards/#import-maps');
console.log('****************************************************************************');
}

generatedImportMap = importMap;
generatedImportMap = Object.fromEntries(importMap);
} else {
generatedImportMap = generatedImportMap || {};
}
Expand Down

0 comments on commit 2037d3b

Please sign in to comment.