Provides AMD's define() API for declaring modules in the AMD format in Node.js environments
npx @tessl/cli install tessl/npm-amdefine@1.0.0amdefine 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.
npm install amdefineStandard require:
const amdefine = require('amdefine');For automatic injection:
require('amdefine/intercept');// 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
};
});// 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 modulesamdefine consists of two main components:
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 IDUsage 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' });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');
});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 moduleUsage 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;
});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 };
});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 };
});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');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'process.nextTick()load.fromText() is not supported (throws error)require as second parameter to amdefine()/**
* 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;
}