Skip to content

πŸ¦• A high-performance import map processor that transforms and caches JavaScript/TypeScript modules for Deno.

License

Notifications You must be signed in to change notification settings

lambdalisue/deno-import-map-importer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

42 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

import-map-importer

JSR Test workflow codecov

A high-performance import map processor for Deno that dynamically transforms and caches JavaScript/TypeScript modules. This tool enables you to use import maps in environments where they're not natively supported, with intelligent caching for optimal performance.

Features

  • πŸš€ High Performance - Multi-level caching (memory + disk) with parallel dependency processing
  • πŸ”„ Import Map Support - Full support for imports and scopes as defined in the Import Maps specification
  • πŸ“¦ Smart Caching - Content-based cache invalidation ensures updates are reflected immediately
  • πŸ” Comprehensive Import Detection - Catches all import/export patterns including those missed by standard parsers
  • πŸ›‘οΈ Type Safety - Full TypeScript support with exported types
  • 🎯 Zero Dependencies - Only uses Deno standard library and essential tools

Installation

deno add @lambdalisue/import-map-importer

Quick Start

import { ImportMapImporter } from "@lambdalisue/import-map-importer";

// Define your import map
const importMap = {
  imports: {
    // Map package names to URLs
    "lodash": "https://cdn.skypack.dev/lodash",
    "react": "https://esm.sh/react@18",

    // Map path prefixes
    "@utils/": "./src/utils/",
    "@components/": "./src/components/",
  },
};

// Create an importer instance
const importer = new ImportMapImporter(importMap);

// Import modules with automatic transformation
// This is an example - replace with your actual module path
const myModule = await importer.import<{ greet: (name: string) => void }>(
  "./src/main.ts",
);
myModule.greet("World"); // Uses transformed imports!

Advanced Usage

Custom Cache Directory

import { ImportMapImporter } from "@lambdalisue/import-map-importer";

const importMap = {
  imports: {
    "lodash": "https://cdn.skypack.dev/lodash",
  },
};

const importer = new ImportMapImporter(importMap, {
  // Use a custom cache directory
  cacheDir: "./.cache/imports",
});

Scoped Imports

const importMap = {
  imports: {
    "lodash": "https://cdn.skypack.dev/[email protected]",
  },
  scopes: {
    "/legacy/": {
      // Use older version in legacy code
      "lodash": "https://cdn.skypack.dev/[email protected]",
    },
  },
};

Clear Deno Cache

For modules that have their own deno.json configurations:

import { ImportMapImporter } from "@lambdalisue/import-map-importer";

const importMap = {
  imports: {
    "lodash": "https://cdn.skypack.dev/lodash",
  },
};

const importer = new ImportMapImporter(importMap, {
  // Clear Deno's module cache before importing
  clearDenoCache: true,
});

Type-Safe Imports

import { ImportMapImporter } from "@lambdalisue/import-map-importer";

// Define your module interface
interface MyUtils {
  formatDate: (date: Date) => string;
  parseJSON: <T>(json: string) => T;
}

const importMap = {
  imports: {
    "@utils/": "./src/utils/",
  },
};

const importer = new ImportMapImporter(importMap);

// Import with type safety
// This is an example - replace with your actual module path
// const utils = await importer.import<MyUtils>("@utils/helpers.ts");
// const formatted = utils.formatDate(new Date()); // Fully typed!

How It Works

  1. Parse - When you import a module, the importer parses its source code to find all import statements
  2. Transform - Import specifiers are transformed according to your import map rules
  3. Cache - Transformed modules are cached both in memory and on disk for fast subsequent loads
  4. Recurse - Dependencies are processed recursively and in parallel for optimal performance

Caching Strategy

The caching system uses a content-based approach:

  • Cache Key: SHA-256 hash of (module URL + source code + import map)
  • Cache Location: Configurable directory with hierarchical structure
  • Cache Invalidation: Automatic when source code or import map changes

API Reference

ImportMapImporter

The main class for import map processing.

interface ImportMap {
  imports: Record<string, string>;
  scopes?: Record<string, Record<string, string>>;
}

interface ImportMapImporterOptions {
  cacheDir?: string;
  clearDenoCache?: boolean;
}

// Class signature (implementation details omitted)
// class ImportMapImporter {
//   constructor(
//     importMap: ImportMap,
//     options?: ImportMapImporterOptions,
//   );
//
//   import<T>(specifier: string): Promise<T>;
// }

ImportMap

The import map configuration type.

interface ImportMap {
  imports: Record<string, string>;
  scopes?: Record<string, Record<string, string>>;
}

ImportMapImporterOptions

Configuration options for the importer.

interface ImportMapImporterOptions {
  // Custom cache directory (absolute or relative path)
  cacheDir?: string;

  // Clear Deno's module cache before importing
  clearDenoCache?: boolean;
}

Type Guards

The module also exports type guards for runtime validation:

import {
  ImportMapImporter,
  isImportMap,
  isImports,
  isScopes,
} from "@lambdalisue/import-map-importer";

// Validate import map structure
const data: unknown = {
  imports: { "lodash": "https://cdn.skypack.dev/lodash" },
};
if (isImportMap(data)) {
  const importer = new ImportMapImporter(data);
}

loadImportMap

A utility function to load import maps from JSON files with automatic path resolution.

import {
  ImportMapImporter,
  loadImportMap,
} from "@lambdalisue/import-map-importer";

// Load from a relative path
const importMap = await loadImportMap("./config/import_map.json");

// Load from an absolute path
const importMap2 = await loadImportMap("/path/to/import_map.json");

// Use with ImportMapImporter
const importer = new ImportMapImporter(importMap);

This function automatically resolves relative paths in your import map file:

  • Relative paths (starting with ./ or ../) are resolved relative to the import map file's location
  • Absolute paths are converted to file URLs
  • URLs (http://, https://, file://) are preserved as-is

Example: If your config/import_map.json contains:

{
  "imports": {
    "@utils/": "./src/utils/",
    "lodash": "https://cdn.skypack.dev/lodash"
  }
}

The resolved result will have the relative path converted to an absolute file URL:

{
  "imports": {
    "@utils/": "file:///absolute/path/to/config/src/utils/",
    "lodash": "https://cdn.skypack.dev/lodash"
  }
}

Performance Tips

  1. Reuse Importer Instances - Create one importer and reuse it for multiple imports
  2. Use Absolute URLs - Prefer absolute URLs in import maps for better caching
  3. Batch Imports - Import multiple modules in parallel when possible
import { ImportMapImporter } from "@lambdalisue/import-map-importer";

const importMap = {
  imports: {
    "lodash": "https://cdn.skypack.dev/lodash",
  },
};

const importer = new ImportMapImporter(importMap);

// Good - parallel imports
const [moduleA, moduleB] = await Promise.all([
  importer.import("./a.ts"),
  importer.import("./b.ts"),
]);

// Less optimal - sequential imports
const moduleA2 = await importer.import("./a.ts");
const moduleB2 = await importer.import("./b.ts");

Limitations

  • Only processes static imports (not dynamic import() expressions in the initial transformation)
  • Remote modules must be accessible via fetch
  • Import maps must be known at initialization time

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development

# Run tests
deno test -A

# Run linter
deno lint

# Run formatter
deno fmt

# Run type checking
deno check **/*.ts

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

πŸ¦• A high-performance import map processor that transforms and caches JavaScript/TypeScript modules for Deno.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 3

  •  
  •  
  •