You can access JavaScript/B2C Commerce script modules within your storefront script code.
Starting in 13.6, B2C Commerce supports the Modules 1.1.1 CommonJS specification. Script modules within your storefront code can be located in cartridges. But unlike traditional B2C Commerce script files, the script modules within your storefront script code don't have to be located in cartridges.
This topic assumes that you are familiar with the Modules 1.1.1 CommonJS specification.
A
CommonJS-compliant B2C Commerce script module is either a script file (with a
.js, .json, or .ds extension) or a directory containing script files. A
module can hide private data, while exposing public objects and methods
via a free variable named exports
.
A free variable is accessible within a function but is not a local variable defined within the function and isn't a parameter of the function. A free variable can be (but doesn't have to be) a global variable.
Before 13.6, you had to use the importScript
and importPackage
methods to access other scripts; these methods automatically export everything into the
global context. Now you can access CommonJS-compliant modules using the
require
method. These modules don't automatically export everything into
the global context.
Within a script file, you load a CommonJS-compliant B2C Commerce script
module using the TopLevel.global.require(path:String)
method. When the module is loaded, you can use any of its exported
variables or methods.
Example 1: Creating the Mod1.Js Module
mod1
module exports the doit()
method
and the aaa
variable, but hides the
localMethod(
). exports.aaa = "bbb";
exports.doit = function() {
return "done.";
}
var localVariable = 1;
/**
* @param {String} Error message.
* @returns {Error} New object.
*/
function localMethod(message, localVariable) {
return new Error({message: localVariable});
}
Example 2: Loading the Mod1 Module
In the following example, the script loads the mod1
module, retrieves the
aaa
variable from the module, and runs the doit()
method.
/*
* @output ModuleId : String
* @output Mod1_1 : String
* @output Mod1_2 : String
*/
var m1 = require( './mod1.js' );
function execute( pdict )
{
pdict.ModuleId = module.id;
pdict.Mod1_1 = m1.aaa;
pdict.Mod1_2 = m1.doit();
return PIPELET_NEXT;
}
TopLevel.global.require(path:String)
method has different
lookup behavior than the require()
function as specified
in the Modules 1.1.1
CommonJS specification:If the path
argument starts with "./" or "../", then it loads relative to the
current module. The module can be a file or a directory. A file extension is
acknowledged, but not required. If it's a directory, a package.json
or a main
file is expected in the directory.
A main
file is a file named
main
, with either a .js, .ds, or .json
extension.
If the package.json
file does
not contain a main
property, then the script defaults
to the main
file in the directory, if one exists.
Access to parent files can't go beyond the top-level version
directory. Access to other cartridges is allowed.
path
argument starts with "*/", it's a path relative to the
start of the cartridge path.path
argument starts with "~/", it's a path relative to the
current cartridge in the cartridge path.path
argument that prepends "dw", or that starts with "dw/",
references B2C Commerce built-in functions and classes, for
example: var u = require( 'dw/util' );
loads the classes in the
util
package, which can be then used as
follows:var h = new u.HashMap();
path
argument that doesn't start with "./" or "../" is resolved as
top-level module. path
argument is used to find a folder in the top-level
version directory, typically a cartridge itself, but it can also be a simple
folder.path
argument is used to look into a
special folder (named modules
) in the top version directory. You
can use this folder to manage different modules. For example, you can drop a module
like express.js
into that folder.TopLevel.global.require(path:String)
method is used to reference a file, an optional file extension is used to
determine the content of the file. Currently, B2C Commerce supports the
following extensions, listed in priority order:exports
variable.importScript
and importPackage
methods. However, it's recommended
that you replace them with the
TopLevel.global.require(path:String)
method.Example: Path Lookup for Mymodule.Js
require()
method:
var u = require( 'mymodule');
TOP_LEVEL_VERSION_DIRECTORY
│
│ mymodule.js (2)
│
├───modules // Directory
│ mymodule.js (3)
│
├───mymodule // Directory
│ myScript.ds (1)
│ package.json // References myScript.ds
│ main.js
│
├───SiteGenesis Storefront Core // Cartridge directory
└─── Controllers // Cartridge directory
This structure includes directories and files that are outside of cartridges. To upload such directories and files to a version directory, you can use the B2C Commerce Build Suite cartridge.
mymodule
directory
for a package.json
file.package.json
is present,
so B2C Commerce checks the value of the main
property
in the file.myScript.ds
file, so B2C Commerce loads myScript.ds
as a
module.package.json
or if the
main
property is missing, B2C Commerce searches the
directory for a main
file to load.main
file, the file is
loaded; otherwise, B2C Commerce continues to search.mymodule.js
file because it's in the
top-level version directory. If there is no file at this level, B2C Commerce continues
to search.modules
directory in
the top level for a mymodule
script file.Although Salesforce provides a sophisticated fallback mechanism for scripts in the global namespace, we generally discourage polluting the global namespace with utility scripts. We recommend adding scripts to specific project cartridges.