Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
als-require
Advanced tools
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
:
{plugins=[],cyclicDependencies,logger}
)build
and bundle
methods. fn
and stringFn
methods instead
fn(options = {scriptBefore='', scriptAfter='', parameters=[]})
stringFn(options = {scriptBefore='', scriptAfter='', parameters=[],name})
To install als-require
, use npm:
npm install als-require
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>
als-require
has two files for NodeJS and browser which has same structure and api.
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 }
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 bundlescriptAfter
- Should be script as string to run it after bundle
modules
and result
.
modules
- the object which includes all modules ({path:content,...})result
- the function to run bundle which returned after scriptAfter
parameters
- The array of strings which will include parameters to pass in result's fnname
- Only for stringFn
for changing function name
// 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);
<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>
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.
/**
* 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 = {}) {}
}
/**
* 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;
FAQs
A utility for using CommonJS require in the browser and creating bundles.
The npm package als-require receives a total of 21 weekly downloads. As such, als-require popularity was classified as not popular.
We found that als-require demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
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.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.