Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

als-require

Package Overview
Dependencies
Maintainers
0
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

als-require

A utility for using CommonJS require in the browser and creating bundles.

  • 3.1.0
  • latest
  • npm
  • Socket score

Version published
Weekly downloads
25
increased by150%
Maintainers
0
Weekly downloads
 
Created
Source

als-require

als-require is a lightweight library for importing, modifying, and executing CommonJS modules in both browser and Node.js environments. It simplifies modular development by supporting dependency resolution, plugins for code transformation, and dynamic bundling.

Capabilities of als-require:

  • Import and execute CommonJS modules in NodeJs and browser with dependency resolution.
  • Dynamically bundle modules into a single executable function.
  • Transform module code using custom plugins before execution.
  • Support for cyclic dependency detection and flexible logging options.

In version 3

  • code refactoring
  • improved getting node modules on NodeJs (not in browser)
  • Changed constructor
    • Now it has options ({plugins=[],cyclicDependencies,logger})
  • No build and bundle methods. fn and stringFn methods instead
    • fn(options = {scriptBefore='', scriptAfter='', parameters=[]})
    • stringFn(options = {scriptBefore='', scriptAfter='', parameters=[],name})
  • no minifying and minifying options
    • The goal make it more simple. You can minify it separately
  • plugins for modifying content
  • no context
    • You can add it as parameter to fn and pass as parameter's value

Installation

To install als-require, use npm:

npm install als-require

Importing

Import in nodejs:

const Require = require('als-require')
const fn = Require.getModule('./some/path')

Import in browser:

<script src="/node_modules/als-require/require.js"></script>
or
<script src="/node_modules/als-require/require.min.js"></script>

<script>
   Require.version = '1.0'; // optional - adding version when fetching files
   Require.cyclicDependencies = true // false by default
   Require.logger = console // console by default


   Require.getModule('./some/path').then(fn => {fn()})
   // or 
   require('./some/path').then(result => {/* code */})

</script>

Usage

als-require has two files for NodeJS and browser which has same structure and api.

Constructor

Constructor initiating new Require instance. On Nodejs, it's automaticly reading all modules and applying plugins. In browser, you should run async method getContent for reading modules and applying plugins.

Constructor has two parameters: path and options. The path is a string relative path to modules. And options has plugins, logger and flag for allowing cyclicDependencies.

const plugins = [
   function(mod) {
      const {content,children,path} = mod
      mod.content = content.replace(...)
   }
]
const options = { plugins = [], cyclicDependencies = false, logger = console }

fn and stringFn parameters

The fn method generates an executable function containing the bundled modules. This function accepts custom parameters and includes pre- and post-bundle code if specified.

The stringFn method behaves similarly but returns the generated function as a string. This is particularly useful for embedding the function in HTML or scripts.

Here are parameters:

  • scriptBefore - Should be script as string to run it before bundle
  • scriptAfter - Should be script as string to run it after bundle
    • In this stage available two variables: modules and result.
      • modules - the object which includes all modules ({path:content,...})
      • result - the function to run bundle which returned after scriptAfter
    • In this stage, you can add return for returning something else
  • parameters - The array of strings which will include parameters to pass in result's fn
  • name - Only for stringFn for changing function name
    • For example, for icluding it in html and call by it's name

Node.Js

// Import the Require class
const Require = require('als-require');

// Create a new Require instance with options
const mod = new Require('./relative/path/to/module', {
   plugins: [],
   cyclicDependencies: true,
   logger: console
});

// Define custom parameters and scripts
const parameters = ['name'];
const scriptBefore = "const SomeVariableAvailableForAllModules = `Hello ${name}`;";
const scriptAfter = `
   console.log('All modules processed.');
   return result;
`;

// Generate the executable function
const resultFn = mod.fn({ scriptBefore, scriptAfter, parameters });

// Generate the function as a string with a custom name
const name = 'bundleFn';
const bundleString = mod.stringFn({ scriptBefore, scriptAfter, parameters, name });

// Execute the result function
const result = resultFn('Alex');
console.log(result);

// Example: Embed the bundle string in a script
const bundle = `${bundleString}\n const result = ${name}('Alex');`;
console.log(bundle);

Browser

<script src="/node_modules/als-require/require.js"></script>
<script>
   const scriptBefore = "const globalVar = 'Hello, world!';";
   const scriptAfter = "console.log('Bundle execution complete.');";
   const parameters = ['customParam'];

   // Create a Require instance for the browser
   const mod = new Require('./relative/path/to/module');

   // Fetch and load all module dependencies
   mod.getContent().then((mod) => {
      // Define parameters and custom scripts

      // Generate the executable function
      const resultFn = mod.fn({ scriptBefore, scriptAfter, parameters });

      // Execute the generated function
      const result = resultFn('Value');
      console.log(result);
   });

   // or
   require('./relative/path/to/module',{ scriptBefore, scriptAfter, parameters },'Value')
   .then(result => console.log(result))

</script>

Require node_modules packages and node modules

In case of path which not starts with ., Require will look for file in node_modules (by checking in package.json). If such package not found (for example require('fs')), result for this package will return empty object.

const somePackage = require('some-package');
const somePackage1 = require('./node_modules/some-package/index.js');
const fs = require('fs');

module.exports = {somePackage,somePackage1,fs}

In case above somePackage and somePackage1 should return the package, but fs, should return empty object.

Pay attention, in browser, using './node_modules/some-package/index.js' instead 'some-package', you save extra request/readFile for looking the filename.

API

NodeJs version

/**
 * The `Require` class handles modular dynamic loading, 
 * dependency resolution, and cyclic dependency detection.
 */
class Require {
   /**
    * Stores the contents of all loaded modules.
    * Each entry maps a module path to its content and children (dependencies).
    * @type {Object<string, { content: string, children: string[] }>}
    * @static
    */
   static contents = {};

   /**
    * List of global plugins to process module contents.
    * Plugins are functions that modify a module's content or children, without replacing the object reference.
    * For example, a plugin can transform `module.content` using `module.content.replace(...)`.
    * @type {Array<Function>}
    * @static
    */
   static plugins = [];

   /**
    * Flag to enable or disable cyclic dependency.
    * When enabled, it allows loading modules that depend on each other recursively.
    * @type {boolean}
    * @static
    */
   static cyclicDependencies = false;

   /**
    * Logger for warnings and error messages.
    * Defaults to the global `console` object but can be overridden with a custom logger.
    * @type {Console}
    * @static
    */
   static logger = console;

   /**
    * Retrieves a module by its path and options.
    * This is a shortcut for instantiating a `Require` object and calling its `fn` method.
    * @param {string} path - Path to the module.
    * @param {Object} [options] - Options for the module loading.
    * @param {string} [options.scriptBefore] - Code to prepend before the module's execution.
    * @param {string} [options.scriptAfter] - Code to append after the module's execution.
    * @param {string[]} [options.parameters] - Parameters to pass into the generated function.
    * @param {Function[]} [options.plugins] - Array of plugin functions.
    * @param {boolean} [options.cyclicDependencies] - Whether to allow cyclic dependencies.
    * @param {Console} [options.logger] - Custom logger for warnings and errors.
    * @returns {Function} - The dynamically generated function for the module.
    * @static
    */
   static getModule(path, options = {}) {
      // Creates a new Require instance and calls its `fn` method to generate the module's function.
      return new Require(path, options).fn(options);
   }

   /**
    * Creates a `Require` instance for managing a specific module and its dependencies.
    * The constructor handles loading the module's contents, resolving dependencies, and applying plugins.
    * @param {string} path - Path to the root module to be loaded.
    * @param {Object} [options] - Options for module handling.
    * @param {Function[]} [options.plugins] - Plugins to modify module content or structure.
    * @param {boolean} [options.cyclicDependencies] - Whether to detect cyclic dependencies.
    * @param {Console} [options.logger] - Custom logger for warnings and errors.
    */
   constructor(path, options = {}) {
      const {
         plugins = [],
         cyclicDependencies = Require.cyclicDependencies,
         logger = Require.logger,
      } = options;

      // Merge global plugins with instance-specific plugins.
      const combinedPlugins = [...Require.plugins, ...plugins].filter(p => typeof p === 'function');

      this.contents = {}; // Stores the current module's contents and dependencies.
      this.path = path; // Path to the root module.
      this.fullPath // will include full path for module
      // In NodeJs Require loads the module's contents and applies plugins.
      this.keys // Keys are the paths of all loaded modules, sorted in reverse order.
   }

   /**
    * Generates a function for the module that incorporates options for execution.
    * The function includes dynamically generated code that can be executed with custom parameters.
    * @param {Object} [options] - Options for function generation.
    * @param {string} [options.scriptBefore] - Code to prepend before the module's execution.
    * @param {string} [options.scriptAfter] - Code to append after the module's execution.
    * @param {string[]} [options.parameters] - Parameters to pass into the generated function.
    * @returns {Function} - The dynamically generated function for the module.
    */
   fn(options = {}) {}

   /**
    * Generates a string representation of the function for the module.
    * Useful for embedding the module in scripts or HTML, with an optional function name.
    * @param {Object} [options] - Options for function generation.
    * @param {string} [options.scriptBefore] - Code to prepend before the module's execution.
    * @param {string} [options.scriptAfter] - Code to append after the module's execution.
    * @param {string[]} [options.parameters] - Parameters to pass into the generated function.
    * @param {string} [options.name] - If presented, replaces the anonymous function name with the provided name.
    * @returns {string} - The string representation of the function.
    */
   stringFn(options = {}) {}
}

Browser version

/**
 * The `Require` class provides modular loading, dependency resolution, 
 * cyclic dependency detection, and fetch-based loading for both server and browser environments.
 */
class Require {
   /**
    * A list of standard Node.js modules that are automatically excluded from fetching.
    * @type {string[]}
    * @static
    */
   static standartNodeModules = [...];

   /**
    * Stores the contents of all loaded modules.
    * Each entry maps a module path to its content and dependencies.
    * @type {Object<string, { content: string, children: string[] }>}
    * @static
    */
   static contents = {};

   /**
    * List of global plugins to process module contents.
    * Plugins are functions that modify a module's content or structure.
    * @type {Array<Function>}
    * @static
    */
   static plugins = [];

   /**
    * Flag to enable or disable cyclic dependency detection.
    * @type {boolean}
    * @static
    */
   static cyclicDependencies = false;

   /**
    * Logger for warnings and error messages.
    * Default is the `console` object but can be replaced with a custom logger.
    * @type {Console}
    * @static
    */
   static logger = console;

   /**
    * Version string to append to fetched module URLs for cache-busting.
    * @type {string | undefined}
    * @static
    */
   static version;

   /**
    * Checks if a cyclic dependency exists between two modules and throws an error if detected.
    * @param {string} fullPath - The full path of the dependent module.
    * @param {string} path - The path of the current module.
    * @throws {Error} Throws an error if a cyclic dependency is detected and cyclicDependencies=false.
    * @static
    */
   static isCyclyc(fullPath, path) {}

   /**
    * Fetches a resource from a given path and returns its content.
    * Supports different response types such as 'text', 'json', etc.
    * @param {string} path - The URL or path to fetch.
    * @param {string} [type='text'] - The type of the response (e.g., 'text', 'json').
    * @returns {Promise<any>} Resolves with the fetched content in the specified format.
    * @static
    */
   static async fetch(path, type = 'text') {}

   /**
    * Asynchronously loads a module and its dependencies, returning a function for execution.
    * @param {string} path - Path to the module.
    * @param {Object} [options] - Options for module loading.
    * @returns {Promise<Function>} Resolves to the dynamically generated function for the module.
    * @static
    */
   static async getModule(path, options = {}) {}

   /**
    * Creates a `Require` instance for managing a specific module.
    * The constructor initializes the module's path, content readiness state, and options.
    * @param {string} path - Path to the root module to be loaded.
    * @param {Object} [options] - Options for module handling.
    */
   constructor(path, options = {}) {
      this.contents = {}; // Stores the current module's contents and dependencies.
      this.path = path; // Path to the root module.
      this.fullPath; // Resolves the full path based on the current location.
      this.contentReady = false; // Indicates if the module's content has been fully loaded.
      this.options = options; // Custom options for module handling.
   }

   /**
    * Asynchronously loads the module's content and dependencies.
    * Applies plugins and detects cyclic dependencies if enabled.
    * @param {Object} [options] - Options for content loading.
    * @returns {Promise<Require>} Resolves to the current instance after loading content.
    */
   async getContent(options = {}) {}

   /**
    * Generates a function for the module that incorporates execution options.
    * The function includes dynamically generated code that can be executed with custom parameters.
    * @param {Object} [options] - Options for function generation.
    * @returns {Function} - The dynamically generated function for the module.
    */
   fn(options = {}) {}
}

module.exports = Require;

Keywords

FAQs

Package last updated on 07 Dec 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc