Skip to content
bizzehdee edited this page Jun 23, 2026 · 3 revisions

Modules

DScript supports CommonJS-style require / exports and ES-module import / export syntax. Both styles share the same module cache.

Setting up a module loader

Supply a callback that resolves a module path to its source code:

engine.ModuleLoader = (path, fromPath) =>
    File.ReadAllText(Path.Combine(baseDir, path + ".ds"));
  • path — the string passed to require() or import … from
  • fromPath — the absolute path of the file that issued the require (empty for top-level code)

Return the source text of the module. Throw an exception to signal a missing module.

CommonJS — require / exports

Exporting (named exports via export keyword, or by assigning module.exports):

// math.ds
export function add(a, b) { return a + b; }
export const PI = 3.14159;

Or the long form:

// math.ds
function add(a, b) { return a + b; }
const PI = 3.14159;

module.exports = { add, PI };

Importing:

var math = require("math");
console.log(math.add(2, 3));  // 5
console.log(math.PI);         // 3.14159

ES module import

import { add, PI } from "math";
import * as math from "math";
import defaultExport from "utils";

Named imports bind the named exports directly. Namespace imports (* as) bind the whole exports object.

Module environment globals

Every module has access to these built-in globals:

Global Value
__filename Absolute path of the current module file
__dirname Directory part of __filename
module The module object (module.exports, module.filename, module.loaded)
exports Alias for module.exports
// Inside any required module:
console.log(__filename);   // "/app/lib/math.ds"
console.log(__dirname);    // "/app/lib"
console.log(module.loaded); // false during execution, true after

Replacing module.exports

To export a single value (function, class, or primitive), assign module.exports directly:

// greeter.ds
module.exports = function(name) {
    return `Hello, ${name}!`;
};

// caller
var greet = require("greeter");
greet("Alice");  // "Hello, Alice!"

Module caching

Every resolved path is compiled and executed exactly once. Subsequent require() calls return the cached module.exports object without re-running the module body. This means module-level side effects (logging, registering listeners, etc.) only happen once.

Circular dependencies

If module A requires module B, and module B requires module A, DScript breaks the cycle by returning the partial exports of A (whatever has been assigned to module.exports so far) when B tries to require it. Design modules to avoid cycles where possible.

Default exports

// utils.ds
export default function helper() { return 42; }

// caller
import helper from "utils";
helper();  // 42

export default sets the default property on the exports object. The import defaultName from "module" form binds that property to defaultName.

Clone this wiki locally