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 utility that enables the importation and modification of CommonJS modules before execution in both browser and Node.js environments.
Capabilities of als-require
:
Where it can be particularly useful:
To install als-require
, use npm:
npm install als-require
Import in nodejs:
const Require = require('als-require')
const module = Require.getModule('./some/path')
Import in browser:
<script src="/node_modules/als-require/require.js"></script>
<script>
Require.getModule('./some/path')
.then(module => {
// ...
})
// or Require.getModule('./some/path')
require('./some/path').then(module => {
// ...
})
</script>
als-require
has two files for NodeJS and browser which has same structure and api.
Each file includes Require
class with folowing structure:
class Require {
static getModule(path, context, contextName) {}
static _requireClass = null
static contents = {}
constructor(path) {
this.contents = {}
this.path = path
this.fullPath = Require.getFullPath(path, Require.relativePath)
this.contentReady = false
}
// returns promise in browser
getContent() {}
// returns result
build(modules = {}, context = {}, contextName = 'context') {}
// only in nodejs version. returns bundle
bundle(options={}) {}
//default options = { context = {}, script = '', contextName = 'context', includeRequire = true, minified = true }
}
const require = Require.getModule // in browser
The structure above describes only properties and methods for usage, without additional properties and methods which used as private methods.
Arguments:
path
(String): relative path to module for requirecontext
(Object): shared object which will be available in all modulescontextName
(String): Name for context variable (default context)Here explanation what each method and property used for:
Require.getModule
- quick way to get contents and build them in one step
contents
, modules
and result
Require.contents
- includes modules contents and their children list and used as cacherequire.getContent()
- used for reading module file's contents
Require.contents
and to require.contents
async
and NodeJS version is sync
require.build(modules,context,contextName)
- builds all modules results
bundle
- returns bundle inside (function() {})()
script
- Additional script to execute after bundle created (default '')
context
, modules
and result
after creation, but before returning the resultcontext
- The context for build in bundle (default empty object)contextName
- name for context variable (default 'context')includeRequire
: Include browser's Require class code in bundle (default true)minified
: minify the result (default true)const Require = require('als-require')
const path = './relative/path/to/module'
const mod = new Require(path)
mod.getContent() // reading all modules
for(const path in mod.contents) {
mod.contents[path] = mod.contents[path] // modify if needed
}
const context = {} // shared object for all modules empty object by default
const modules = {} // will include all module`s results {relativePath:moduleResult,...}
const result = mod.build(modules,context) // build the result
<script src="/node_modules/als-require/require.js"></script>
<script>
const path = './relative/path/to/module'
const mod = new Require(path)
const promise = mod.getContent() // fetching all modules
promise.then(mod => {
for(const path in mod.contents) {
mod.contents[path] = mod.contents[path] // modify if needed
}
const modules={}, context = {}
const result = mod.build(modules,context) // build the 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 null
.
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 null.
Pay attention, using './node_modules/some-package/index.js'
instead 'some-package'
, you save extra request/readFile for looking the filename.
The context
object is a shared space accessible by all modules loaded by als-require
. This allows modules to read and write shared data, enabling more interactive and dynamic module behaviors.
Make sure you are using the context
for static value (like constants and common variables and functions) and not dynamic, cause it available to all require's results.
The bundle
method in als-require
is designed to compile all the required modules into a single executable JavaScript bundle. This method is particularly useful for preparing code that needs to be executed in a browser environment where modules may not be natively supported or where a single script file is preferred for performance reasons.
The bundle
method accepts an options
object that can be used to customize the behavior of the bundling process. Here are the available options:
context
(Object): A shared object that will be available in all modules. This object can be used to pass state or utilities between modules.
als-object-serializer
contextName
(String): The name of the variable that will hold the context
object within the bundled code. Defaults to 'context'
.script
(String): Additional JavaScript code to be executed at the end of the bundle. This script can interact with the modules and the context
.includeRequire
(Boolean): Whether to include the Require
class code within the bundle. This is necessary if the modules in the bundle rely on the Require
method to load other modules.minified
(Boolean): Whether to minify the resulting bundle. Minification reduces the size of the bundle but can make debugging more difficult.The bundle
method operates by first gathering all the modules specified by their paths and dependencies, ensuring they are all loaded and resolved correctly. It then compiles these modules into a single JavaScript function, which includes the Require
class if includeRequire
is set to true
. If minified
is true, it applies a minification algorithm to compress the code.
The context object is serialized and injected into the bundle, allowing all modules to access shared data through the specified contextName
. Finally, any additional script provided in the script
option is appended to the end of the function, allowing for custom logic to be executed when the bundle is loaded.
Here's how you might create a simple bundle with some additional script:
const Require = require('als-require');
const path = './relative/path/to/module';
const mod = new Require(path);
mod.getContent();
const options = {
script: 'console.log("Bundle executed",{modules,context,result});',
context: { userId: 123 },
contextName: 'appContext',
includeRequire: true,
minified: true
};
const bundleScript = mod.bundle(options);
console.log(bundleScript); // Outputs the bundled script
You can use the bundle
method in conjunction with server-side rendering to prepare a script that will rehydrate the server-rendered page in the client's browser:
const mod = new Require(path);
mod.getContent();
const serverRenderedContent = mod.build();
const clientBundle = mod.bundle({
script: 'startApp(result,context);',
context: serverRenderedContent,
includeRequire: true,
minified: false
});
const rawHtml = `
<!DOCTYPE html>
<html lang="en">
<head><title>App</title></head>
<body>${serverRenderedContent}</body>
<script>${clientBundle}</script>
</html>
`;
// Send rawHtml as the response to the client
In this example, serverRenderedContent
might be HTML or other content generated by the server based on the modules, and clientBundle
is a script that will effectively "take over" in the browser, allowing for a smooth transition from server-rendered to client-side dynamic content.
You can also use the bundle
method to create different bundles based on runtime conditions, such as different user roles, feature flags, or experimental features. This allows for a highly customizable delivery of resources tailored to specific user experiences or testing scenarios.
als-require
throwing errors in case of cyclic dependencies and if some module throwing error.
For the case of module's error, Require
adds to stack modules paths which has called.
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.