task-master-neo-sdlc
Version:
Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.
157 lines (143 loc) • 4.37 kB
JavaScript
/**
* Module Loader Utility
*
* Provides utilities for loading modules in both ESM and CommonJS environments.
*/
import { log } from './logging.js';
import path from 'path';
import fs from 'fs';
// Detect if we're in an ESM environment
const isESM = typeof require === 'undefined' || require.constructor.name !== 'Function';
/**
* Load a module dynamically in both ESM and CommonJS environments
* @param {string} modulePath - Path to the module
* @returns {Promise<any>} Loaded module
*/
export async function loadModule(modulePath) {
try {
if (isESM) {
// ESM environment - use dynamic import
return await import(modulePath);
} else {
// CommonJS environment - use require
return require(modulePath);
}
} catch (error) {
log.error(`Error loading module ${modulePath}: ${error.message}`);
throw error;
}
}
/**
* Load a JSON file in both ESM and CommonJS environments
* @param {string} filePath - Path to the JSON file
* @returns {Promise<any>} Parsed JSON
*/
export async function loadJSON(filePath) {
try {
const data = await fs.promises.readFile(filePath, 'utf8');
return JSON.parse(data);
} catch (error) {
log.error(`Error loading JSON file ${filePath}: ${error.message}`);
throw error;
}
}
/**
* Resolve a module path in both ESM and CommonJS environments
* @param {string} moduleName - Name of the module
* @param {string} basePath - Base path to resolve from
* @returns {Promise<string>} Resolved module path
*/
export async function resolveModulePath(moduleName, basePath = process.cwd()) {
try {
if (isESM) {
// ESM environment - use import.meta.resolve if available
if (typeof import.meta !== 'undefined' && typeof import.meta.resolve === 'function') {
return import.meta.resolve(moduleName);
}
// Fallback to manual resolution
const packageJsonPath = path.join(basePath, 'package.json');
if (fs.existsSync(packageJsonPath)) {
const packageJson = await loadJSON(packageJsonPath);
const dependencies = {
...packageJson.dependencies,
...packageJson.devDependencies
};
if (dependencies[moduleName]) {
// Check node_modules
const modulePath = path.join(basePath, 'node_modules', moduleName);
if (fs.existsSync(modulePath)) {
return modulePath;
}
}
}
// Try to find the module in node_modules
const modulePath = path.join(basePath, 'node_modules', moduleName);
if (fs.existsSync(modulePath)) {
return modulePath;
}
// If not found, return the module name as is
return moduleName;
} else {
// CommonJS environment - use require.resolve
return require.resolve(moduleName, { paths: [basePath] });
}
} catch (error) {
log.warn(`Error resolving module path for ${moduleName}: ${error.message}`);
return moduleName;
}
}
/**
* Check if a module exists
* @param {string} moduleName - Name of the module
* @returns {Promise<boolean>} Whether the module exists
*/
export async function moduleExists(moduleName) {
try {
if (isESM) {
// ESM environment - try to import
try {
await import(moduleName);
return true;
} catch (error) {
return false;
}
} else {
// CommonJS environment - use require.resolve
try {
require.resolve(moduleName);
return true;
} catch (error) {
return false;
}
}
} catch (error) {
return false;
}
}
/**
* Create a dynamic import function that works in both ESM and CommonJS environments
* @param {string} modulePath - Path to the module
* @returns {Function} Dynamic import function
*/
export function createDynamicImport(modulePath) {
return async () => {
return await loadModule(modulePath);
};
}
/**
* Get the appropriate import function for the current environment
* @returns {Function} Import function
*/
export function getImportFunction() {
if (isESM) {
return (modulePath) => import(modulePath);
} else {
return (modulePath) => Promise.resolve(require(modulePath));
}
}
// Export environment information
export const moduleEnvironment = {
isESM,
nodeVersion: process.version,
moduleType: isESM ? 'ESM' : 'CommonJS'
};