84 lines
2.9 KiB
JavaScript
84 lines
2.9 KiB
JavaScript
/**
|
|
* Resolves a module specifier against an import map
|
|
* @param {string} specifier - The module specifier to resolve (bare specifier or absolute URL)
|
|
* @param {Object} importMap - The import map object containing imports and scopes
|
|
* @param {string} baseURL - The base URL for context (especially for scopes)
|
|
* @returns {string} The resolved URL
|
|
*/
|
|
export default function resolveImportMap(specifier, importMap, baseURL) {
|
|
|
|
// Check for exact matches first (most common case for bare specifiers)
|
|
const lookup = importMap.imports[specifier];
|
|
if (lookup) { return lookup; }
|
|
|
|
const Scanner =(obj)=>
|
|
{
|
|
// Check for path prefix matches (longest first)
|
|
const keys = Object.keys(obj)
|
|
.filter(key => key.endsWith('/'))
|
|
.sort((a, b) => b.length - a.length);
|
|
for (const key of keys)
|
|
{
|
|
if (specifier.startsWith(key))
|
|
{
|
|
const remainder = specifier.slice(key.length);
|
|
return obj[key] + remainder;
|
|
}
|
|
}
|
|
}
|
|
|
|
const scan = Scanner(importMap.imports);
|
|
if (scan) {return scan}
|
|
|
|
// Handle scopes if available
|
|
if (importMap.scopes) {
|
|
const scopeKeys = Object.keys(importMap.scopes).sort((a, b) => b.length - a.length);
|
|
for (const scopeKey of scopeKeys)
|
|
{
|
|
if (specifier.startsWith(scopeKey))
|
|
{
|
|
const scopeImports = importMap.scopes[scopeKey];
|
|
const scan = Scanner(scopeImports);
|
|
if (scan) {return scan}
|
|
}
|
|
}
|
|
}
|
|
|
|
return specifier;
|
|
}
|
|
|
|
// Example usage for bare specifiers:
|
|
function demonstrateOptimizedResolver() {
|
|
const importMap = {
|
|
"imports": {
|
|
"lodash": "https://cdn.skypack.dev/lodash",
|
|
"react": "https://cdn.skypack.dev/react",
|
|
"lib/": "/node_modules/lib/",
|
|
"components/": "/components/"
|
|
},
|
|
"scopes": {
|
|
"/admin/": {
|
|
"components/": "/admin-components/",
|
|
"admin-utils": "scoped!/js/admin-utils.js"
|
|
}
|
|
}
|
|
};
|
|
|
|
// Examples with bare specifiers
|
|
console.log("Resolving 'lodash':", resolveImportMap("lodash", importMap, "https://example.com/admin/dashboard/"));
|
|
console.log("Resolving 'components/button':", resolveImportMap("components/button", importMap, "https://example.com/admin/dashboard/"));
|
|
|
|
// Example with scope
|
|
console.log("Resolving 'admin-utils':",
|
|
resolveImportMap("admin-utils", importMap, "https://example.com/admin/dashboard/"));
|
|
|
|
console.log("Resolving '/admin/admin-utils':",
|
|
resolveImportMap("admin-utils", importMap, "https://example.com/admin/dashboard/"));
|
|
|
|
// Example with URL
|
|
console.log("Resolving 'https://example.com/external.js':",
|
|
resolveImportMap("https://example.com/external.js", importMap, "https://example.com/admin/dashboard/"));
|
|
}
|
|
|
|
demonstrateOptimizedResolver();
|