Module Resolution
How SFCC require() paths, cartridge overrides, module.superModule, and resource requires resolve and get typed
SFCC require() paths are not standard Node paths - they resolve across your cartridge path overlay. The language server understands every SFCC path style and types the result as the actual module it resolves to, so member access on an imported module is fully typed and navigable.
Cartridge-Aware require()
// Resolves to the first cartridge in the path that provides this module
var collections = require('*/cartridge/scripts/util/collections');
var productHelpers = require('*/cartridge/scripts/helpers/productHelpers');The result is typed from whichever cartridge wins the overlay - the same file SFCC would load at runtime.
// Resolves within the current cartridge
var guard = require('~/cartridge/scripts/guard');var Site = require('dw/system/Site');
var Money = require('dw/value/Money');Resolves to the bundled dw/* type definitions.
var helpers = require('./helpers');
var base = require('../base/order');After resolution, member access on the imported module is fully typed:
var collections = require('*/cartridge/scripts/util/collections');
collections. // ← completion for map(), forEach(), pluck(), …Prefer CommonJS require() / module.exports over ESM import / export in SFCC. See Imports & the Rhino Engine for the reasons and how scope works at runtime.
module.superModule
When a cartridge overrides a module and pulls in the version it shadows via module.superModule, the engine resolves the parent module across the overlay and types superModule as that module - so members are completed and navigable.
var base = module.superModule; // typed as the overridden module
base. // ← completion for the parent module's exports
base.myExtra = function () { /* ... */ };
module.exports = base;Go to Definition on a superModule member jumps to the assignment in the parent cartridge's module.
Resource Require
The require(Resource.msg('…', 'require')) pattern - loading a module path from a properties file - is resolved to the real target module, so the required value is typed correctly rather than left as any.
importScript / importPackage
Legacy Digital Script brings symbols into scope with importScript(), importPackage(), and importClass() rather than require(). The engine models these too - resolving the imported symbols so they autocomplete and navigate. Because the scoping rules are specific to Digital Script, they are covered in detail on their own page.
See Digital Script (.ds) for exactly what each import adds to scope and where.