Security News
Weekly Downloads Now Available in npm Package Search Results
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
helios-kernel
Advanced tools
Helios Kernel is an isomorphic JavaScript module loader and dependency manager. Under isomorphic it is implied that an application or a library based upon the Helios Kernel can run both in browser-based environment and in Node.js natively and without any kind of conversion. For the moment of writing, this is the only module loader focused on being truly isomorphic.
Helios Kernel tracks the dependency graph, loads and unloads corresponding modules dynamically in the runtime according to the needs of different and independent parts of an application. It is smart enough to start initializing the modules which are ready for that, while others are still being downloaded or parsed, and to handle some tricky problems such as circular dependencies or broken code (reporting the problem, but still keeping the application alive). But the key feature of Helios Kernel is
Helios Kernel provides the necessary features intended to make dependency management simple and straightforward. Syntax of a module and dependency declaration is implemented in the classic include-style:
// list of dependencies
include('path/to/someLibrary.js');
include('../path/to/anotherLibrary.js');
init = function() {
// module code,
// objects declared in the included modules are available at this point
LIB.someLibrary.sayHello();
}
A set of dependencies is listed in the module head using the
include()
function, where each call stands for a single dependency.
The only argument is the exact path to the source of the needed module
— so that it is always easy to find out the particular dependency
source location.
Module code is located inisde the init()
function declaration. It
will be issued by Helios Kernel as soon as all dependencies are
loaded.
This is how someLibrary.js
included in the module above could look:
init = function() {
// object containing the library routines
LIB.someLibrary = {};
// library method
LIB.someLibrary.sayHello = function() {
console.log('Hello World!');
}
}
Helios Kernel introduces a global object called LIB
, which is a
special registry designed to store the libraries. In this example a
library object someLibrary
is declared as a property of the LIB
object. Other modules may then access the library object over the
LIB
registry.
This differs to a more common approach of objects exporting, which is based on the module pattern, aims to provide the precise control over the objects created by a library, and thus considered as a must-have nowadays and reused in most of other loaders. However the disadvantage of such technique is the overheads during managing the dependency structure, introduced by an artificial coupling between a module (library internal structure) and the exported object (library interface).
Using Helios Kernel one may split a library into modules with the most logical and convenient way without being linked to the objects created by the particular modules. Moreover Helios Kernel does not apply any restrictions on how to transfer the data between the modules or what to perform at all inside a module body.
By convention a library stores its routines as a property of the LIB
registry, and the name of that property should match the library
name. A set of modules which the library is split into may build-up
and fill-in the library object.
This is basicly everything you need to know to start using Helios Kernel for setting-up the dependencies in your project. This text contains the full documentation on Helios Kernel.
There is no native dependency management solution in browser environments. To ensure that a set of JavaScript-libraries is loaded, the libraries are usually listed within a single html-page header. Managing the dependencies and loading order is too tricky in this case, and gets more and more complicated along with the project growth. To solve this problem, several script loading approaches and libraries exist, one of which is Helios Kernel.
In Node.js there is a native dependency declaration technique — the
require()
function which implements the specifications suggested by
CommonJS group. Just like as
in most of the browser-based solutions, it introduces object
exporting, which as mentioned
more likely brings unnecessary complications to dependency management
and objects declaration. Therefore Helios Kernel pretends to be a
simplier and more flexible alternative.
Helios Kernel may be preferred because of its simplicity, or if there is a need to to have the modules isomorphic and compatible between web and Node.js environments. Comparing to other dependency-management solutions, with Helios Kernel it could be more convenient to:
modify or refactor a list of dependencies, especially when there are
a lot of them (each dependency is just a single include()
line
referring to a module by its path, which is specified at the module
head, not inside the module body or even some external config)
create a compound module which should load several modules to be
used at once (such module could simply list all dependencies using
include()
, without a need to transfer other modules' routines
through the exported objects)
reuse "ordinary" JavaScript libraries designed to be loaded using
the <script>
tag in a html-page (module format is very simple, and
such a library could be easily converted to a module by wrapping its
code with an init()
function declaration)
helios-kernel/
directory. You may
also use npm to install Helios Kernel under
Node.js:$ npm install helios-kernel
main.js
with the
following content:// include the needed libraries here
init = function() {
// start your application code here
console.log('Hello world!');
}
To declare the initial module dependencies, use include()
function at the
module head
index.html
with the
following content:<script src="helios-kernel/kernel.js"></script>
<script>
window.onload = function(){
kernel.require('main.js');
}
</script>
nodestart.js
with the following
content:require('helios-kernel/kernel.js');
kernel.require(__dirname + '/main.js');
If you have used npm
to install Helios Kernel, you may also do it
like this:
require('helios-kernel');
kernel.require(__dirname + '/main.js');
index.html
, or set the project directory as a web-server root. To
start the application under node, launch the newly created
nodestart.js
using Node.js:$ node nodestart.js
npm
to install
Helios Kernel:$ npm install helios-kernel
Load the Helios Kernel library script kernel.js
from the
distribution using any technique suitable for your
project/environment. For a browser-based environment you could add a
<script>
tag to the head of HTML-document. For Node.js you could use
node's require()
function to load Helios Kernel (see examples in the
previous section).
After the Helios Kernel is loaded, you may use kernel.require()
function to load any Kernel-compatible library.
Optionally you can even convert and merge a Kernel-compatible library using the helios-merge tool into a plain JavaScript bundle suitable for using without Helios Kernel.
Module structure is explained in the first section of this
text. Basically a module consists of the two parts: the list of
dependencies in the module head using the include()
function, and
the module code inside the init()
function declaration:
// list of dependencies
include('path/to/someLibrary.js');
include('../path/to/anotherLibrary.js');
init = function() {
// module code,
// objects declared in the included modules are available at this point
LIB.someLibrary.sayHello();
}
The simpliest approach to make the module data available to other
modules, is to put the data inside a library object in the LIB
registry.
To load a module in the runtime, use kernel.require()
function. It
takes three arguments — absolute path of the module, and the two
callbacks — for a success and for a failure.
Unlike include()
which is used for declaring a dependency in a
module head, and is mostly intended to work with relative paths,
kernel.require()
only accepts specifying the absolute path. For a
web environment you may start it with the slash /
which will stand
for the domain root. To load a remote module, provide the full URL
starting with a protocol (http://...
). You may also provide an array
of paths to load several modules at once.
Second argument, the success callback, is a function which is called after all demanded modules and their dependencies are successfully loaded and initialized. Inside this callback you may start using the objects provided by the requested modules.
Third argument is a failure callback which will be called in case if some of the requested modules (or their dependencies has failed to be loaded. Reasons could be very different (from syntax error to network problems), therefore you must implement some reasonable fallback or cancellation behaviour for the loading failure.
The returned value of kernel.require()
is a reservation ticket, a
special object corresponding to a single require()
act. You will
need the ticket if you wish to unload the requested modules in the
future when you don't need them anymore.
Therefore, dynamically loading a module looks like this:
var sCallback = function() {
// the library is loaded, we may use it now
LIB.someLibrary.doSomething();
}
var fCallback = function() {
// library failed to load, falling back
console.log('Cannot go any further!');
}
var ticket = kernel.require(
'/path/to/library.js', sCallback, fCallback
);
After you have finished using the requested modules, you may release
the ticket by calling kernel.release()
function:
kernel.release(ticket);
This will not make the Kernel to unload the related modules immediately, instead the Kernel will know that they are not needed anymore at the area related to the given ticket, and will unload the modules after they will be released everywhere else.
Upon the module unload, its code is removed from the Kernel cache. But Kernel does not track the objects created by the module's initializer, therefore you may provide an uninitializer function which would remove the library objects. This function will be called during the module unload.
Therefore the full version of a library module could look like this:
// module initializer
init = function() {
// object containing the library routines
LIB.someLibrary = {};
// library method
LIB.someLibrary.sayHello = function() {
console.log('Hello World!');
}
}
// module uninitializer
uninit = function() {
// removing objects created in the initializer
LIB.someLibrary = null;
delete LIB.someLibrary;
}
If a module initializer declares a single compound object
encapsulating all the library routines (the recommended way,
someLibrary
in the example above), simply clearing that object
should be enough, garbage collector should (hopefully) do the rest.
If you have a library of any format, it usually defines a set of
routines which should be used from the outside later. In most of the
web-libraries which are intended to be included using the <script>
tag, a set of global objects is defined. In this case it should be
enough to wrap the library code with the init()
function
declaration. So if the original source was like this:
libraryObject = {
...
};
libraryFunction = function() {
...
};
then it should be remade like this:
init = function() {
libraryObject = {
...
};
libraryFunction = function() {
...
}
}
Now this is a Helios Kernel compatible module, and could be loaded
using the include()
function. If you load this module, the code of
library's init()
function will be issued and initialize the objects
before the init()
function code of the module which requested the
library.
For the libraries using some kind of export object, the whole code
should also be wrapped with the init()
function. To make the
exported objects, they could be globally redeclared. For instance, a
CommonJS module could looks like this:
this.someObject = {
...
};
this.someFunction = function() {
...
};
To be converted to the Helios module, it should be remade like this:
init = function() {
// global library object
someLibrary = {};
someLibrary.someObject = {
...
};
someLibrary.someFunction = function() {
...
}
}
After this module is loaded, its routines could be referred to as
someLibrary.someObject
.
FAQs
include-style dependencies manager
We found that helios-kernel demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.
Security News
A Stanford study reveals 9.5% of engineers contribute almost nothing, costing tech $90B annually, with remote work fueling the rise of "ghost engineers."
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.