or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-amdefine

Provides AMD's define() API for declaring modules in the AMD format in Node.js environments

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/amdefine@1.0.x

To install, run

npx @tessl/cli install tessl/npm-amdefine@1.0.0

index.mddocs/

amdefine

amdefine provides AMD's define() API for declaring modules in the AMD format in Node.js environments. It allows you to code to the AMD API and have modules work in Node.js programs without requiring those programs to use AMD, bridging the gap between AMD and CommonJS module systems.

Package Information

  • Package Name: amdefine
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install amdefine

Core Imports

Standard require:

const amdefine = require('amdefine');

For automatic injection:

require('amdefine/intercept');

Basic Usage

Standard Usage Pattern

// At the top of each module that uses define()
if (typeof define !== 'function') { 
  var define = require('amdefine')(module); 
}

// Then use AMD-style define()
define(['dependency'], function (dependency) {
  return {
    // module exports
  };
});

Intercept Usage Pattern

// In your main application file
require('amdefine/intercept');

// Now all .js files loaded will automatically have define() available
// No need for the amdefine snippet in individual modules

Architecture

amdefine consists of two main components:

  • Core Module: Factory function that creates AMD-compatible define() functions for individual Node.js modules
  • Intercept Module: Automatic injection mechanism that modifies Node.js module loading to inject define() globally
  • AMD Compatibility: Implements AMD specification including synchronous dependency resolution, loader plugins, and special dependencies
  • Node.js Integration: Leverages Node.js module system for dependency resolution while maintaining AMD semantics

Capabilities

AMD Define Function Creation

Creates a define() function that implements the AMD API for a specific Node.js module, supporting all AMD define() signatures with Node.js-compatible synchronous dependency resolution.

/**
 * Creates a define function for Node.js modules
 * @param {Object} module - The Node.js module object
 * @param {Function} [requireFn] - Node.js require function (needed for Node < 0.5)
 * @returns {Function} AMD-compatible define function
 */
function amdefine(module, requireFn);

The returned define function supports these signatures:

/**
 * AMD define function with multiple signatures
 */
function define(factory);
function define(dependencies, factory);
function define(id, factory);
function define(id, dependencies, factory);
function define(id, object);

/**
 * Special properties on the define function
 */
define.amd; // Empty object indicating AMD compatibility
define.require(id); // Access cached modules by ID

Usage Examples:

const amdefine = require('amdefine');
const define = amdefine(module);

// Anonymous function module
define(function (require) {
  const fs = require('fs');
  return { readFile: fs.readFile };
});

// Anonymous with dependencies
define(['fs', 'path'], function (fs, path) {
  return { readFile: fs.readFile, join: path.join };
});

// Named module
define('myModule', function (require, exports, module) {
  exports.hello = function() { return 'world'; };
});

// Object module
define('config', { apiUrl: 'https://api.example.com' });

AMD Require Function

The define() function creates AMD-compatible require functions that support both synchronous and asynchronous dependency loading patterns.

/**
 * AMD require function created by define()
 * @param {string|Array} deps - Single dependency ID or array of dependency IDs
 * @param {Function} [callback] - Callback for asynchronous array-based require
 * @returns {*} Module exports for synchronous calls, undefined for async calls
 */
function amdRequire(deps, callback);

/**
 * Convert file paths to URLs
 * @param {string} filePath - File path to convert
 * @returns {string} Resolved path
 */
amdRequire.toUrl(filePath);

Usage Examples:

define(function (require) {
  // Synchronous single dependency
  const fs = require('fs');
  
  // Asynchronous multiple dependencies
  require(['fs', 'path'], function (fs, path) {
    // Called on process.nextTick()
  });
  
  // Path resolution
  const configPath = require.toUrl('./config.json');
});

Special Dependencies

AMD special dependency names that provide access to Node.js module internals:

/**
 * Special dependency identifiers
 */
'require' // Returns AMD require function for current module
'exports' // Returns exports object for current module  
'module'  // Returns module object for current module

Usage Examples:

// Access special dependencies
define(['require', 'exports', 'module'], function (require, exports, module) {
  // Use require to load additional dependencies
  const util = require('util');
  
  // Set exports
  exports.moduleId = module.id;
  exports.filename = module.filename;
});

Loader Plugin Support

Support for AMD loader plugins using the pluginName!resourceId syntax, with synchronous loading requirement for Node.js compatibility.

/**
 * Plugin interface for loader plugins
 */
interface LoaderPlugin {
  /**
   * Normalize resource ID (optional)
   * @param {string} id - Resource ID to normalize
   * @param {Function} normalize - Normalization helper function
   * @returns {string} Normalized resource ID
   */
  normalize?(id, normalize);
  
  /**
   * Load resource synchronously
   * @param {string} id - Normalized resource ID
   * @param {Function} require - AMD require function
   * @param {Function} load - Load callback function
   * @param {Object} config - Configuration object
   */
  load(id, require, load, config);
}

/**
 * Load callback function provided to plugins
 * @param {*} value - Loaded resource value
 */
function load(value);

/**
 * UNSUPPORTED: load.fromText() throws error in amdefine
 */
load.fromText; // Throws Error: 'amdefine does not implement load.fromText'

Usage Examples:

// Using a text plugin to load local files
define(['text!./template.html'], function (template) {
  return { template: template };
});

// Plugin that normalizes IDs
define(['myplugin!./resource'], function (resource) {
  return { data: resource };
});

Automatic Define Injection

Modifies Node.js module loading to automatically inject amdefine setup code into all .js files, eliminating the need for manual setup in each module.

/**
 * Intercept module that modifies Node.js Module._extensions['.js']
 * No return value - call require('amdefine/intercept') for side effects
 */
require('amdefine/intercept');

/**
 * Internal intercept function (used as Module._extensions['.js'])
 * @param {Object} module - Node.js module object
 * @param {string} filename - File path being loaded
 */
function intercept(module, filename);

/**
 * Internal BOM stripping function
 * @param {string} content - File content
 * @returns {string} Content with BOM removed
 */
function stripBOM(content);

Usage Examples:

// In your main application file
require('amdefine/intercept');

// Now any .js file can use define() without setup
// The following is automatically prepended to each .js file:
// if (typeof define !== 'function') {var define = require('amdefine')(module)}

// Example module file (no manual setup needed)
define(['fs'], function (fs) {
  return { readFile: fs.readFile };
});

Named Module Management

Support for named modules with internal caching and cross-module access through define.require().

/**
 * Access named modules from the internal cache
 * @param {string} id - Module identifier
 * @returns {*} Module exports if found, undefined otherwise
 */
define.require(id);

Usage Examples:

// Define named modules
define('moduleA', { value: 'A' });
define('moduleB', ['moduleA'], function (moduleA) {
  return { combined: moduleA.value + 'B' };
});

// Access named modules
const moduleB = define.require('moduleB');
console.log(moduleB.combined); // 'AB'

// Export named module to Node.js
module.exports = define.require('moduleB');

Error Handling

amdefine throws specific errors for unsupported operations and invalid usage:

/**
 * Common error conditions
 */

// Multiple anonymous define() calls in same file
// Error: 'amdefine with no module ID cannot be called more than once per file.'

// Missing module dependency
// Error: 'No module with ID: <id>'

// Unsupported plugin operation
// Error: 'amdefine does not implement load.fromText'

Limitations

Synchronous Execution

  • Factory functions execute synchronously to match Node.js behavior
  • Array-based require() callbacks are called on process.nextTick()

Loader Plugin Constraints

  • Plugins must call load() callback synchronously
  • Network-based plugins will not work
  • load.fromText() is not supported (throws error)

Node.js Version Support

  • Node.js >= 0.4.2 required
  • For Node.js < 0.5, must pass require as second parameter to amdefine()

Types

/**
 * AMD factory function signatures
 */
type Factory = (() => any) | ((require: Function) => any) | ((require: Function, exports: Object, module: Object) => any);

/**
 * Module definition with dependencies
 */
interface ModuleDefinition {
  id?: string;
  dependencies?: string[];
  factory: Factory | Object;
}

/**
 * AMD require function interface
 */
interface AMDRequire {
  (id: string): any;
  (dependencies: string[], callback: Function): void;
  toUrl(filePath: string): string;
}

/**
 * AMD define function interface
 */
interface AMDDefine {
  (factory: Factory): void;
  (dependencies: string[], factory: Factory): void;
  (id: string, factory: Factory): void;
  (id: string, dependencies: string[], factory: Factory): void;
  (id: string, object: Object): void;
  amd: {};
  require(id: string): any;
}