Module Resolution

Resolve SFCC CommonJS modules, explicit cartridge paths, resource-driven imports, and inherited implementations

SFCC module paths are resolved in a cartridge context. The language server connects a recognized require() to its module so the returned value can expose exports, member types, documentation, and definition locations

Choose the right path

Path styleExampleMeaning
SFCC APIdw/catalog/ProductMgrA bundled platform API declaration
Active cartridge overlay*/cartridge/scripts/helpers/productLabelsThe first matching module in the configured cartridge order
Current cartridge~/cartridge/scripts/helpers/productLabelsA path rooted in the current cartridge
Explicit cartridgeapp_base/cartridge/scripts/helpers/productLabelsA module in the named cartridge
Relative./productLabels or ../helpers/productLabelsA path relative to the importing module
Moduleserver or app/utilA linked B2C module or global module
var ProductMgr = require('dw/catalog/ProductMgr');
var labels = require('*/cartridge/scripts/helpers/productLabels');
var localConfig = require('~/cartridge/scripts/config');

Invoke completion inside the path to discover modules, then after labels. to inspect its exports. The useful type comes from the resolved implementation or an applicable bundled declaration, not merely the spelling of the variable

B2C modules and global modules

A path that does not start with dw/, */, ~/, ./ or ../ names a linked module. Find Cartridges detects both kinds, or link the folder from the Explorer right-click menu with B2C - Link as B2C Module or B2C - Link as Global Modules. See Three cartridge types

ModuleExampleResolves to
B2C module entryrequire('app')The main file in the app folder's package.json, or its main.js
B2C module filerequire('app/util')util.js in the app folder
Global modulerequire('server')server/index.js in the modules folder
Global module filerequire('server/render')server/render.js in the modules folder

The name is tried as written, then with .js, .d.ts, .ts, .json and .ds, then as a folder with index.js or index.d.ts

var server = require('server');
var collections = require('*/cartridge/scripts/util/collections');

server.get('Show', function (req, res, next) {
    next();
});

Inside the quotes, completion lists every linked cartridge and module folder, and the files of the modules folder by path, such as server/index.js. Picking a file inserts its path without the extension. Go to Definition on the path opens the resolved file

Cartridge order and inherited modules

Changing the active cartridge context can change which implementation supplies an overlay import. Both the cartridge locations and their order must be available locally for the editor to model that relationship accurately

In app_custom the base module is the next cartridge's file with the same path, so Peek Definition on base.getLabel shows the implementation in app_base

module.superModule selects the next matching implementation after the current cartridge. It is not another name for the first */ match

Modules selected through a resource bundle

Some projects store module paths in a properties bundle and load them through Resource.msg. The server recognizes the direct require(Resource.msg(...)) pattern when it can resolve the literal key, bundle, and resulting module path

cartridge/templates/resources/require.properties
helpers.productLabels=*/cartridge/scripts/helpers/productLabels
var Resource = require('dw/web/Resource');
var labels = require(Resource.msg('helpers.productLabels', 'require', null));

Completion on labels uses the resolved helper's exports. The resource key remains connected to the indexed properties entry

This is a specific recognized pattern. Arbitrary variables, wrappers, or runtime-generated resource values are not guaranteed to resolve statically. Local resource selection also cannot establish the runtime locale or deployed bundle contents

CommonJS and TypeScript

Use require() and module.exports for server-side modules. The language server can type those imports in .ts as well as .js; deployment still needs JavaScript suitable for the SFCC runtime

An editor's ability to parse an ES-module import is not evidence of an ES-module loader on SFCC. See Imports & the Rhino engine and Build & transpile

Digital Script imports

importScript, importPackage, and importClass introduce names through the legacy scripting model rather than returning an ordinary CommonJS module object. Their path resolution, global-symbol analysis, transitive imports, and shadowing checks are covered in Digital Script

On this page