
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
10-25-2024 04:08 PM - edited 10-25-2024 04:12 PM
A pretty common question is "how do you call a module (from sys_module) cross scope?"
This is not only a common question, but a good question. After all, I want to keep as much of my logic as possible in a common, modular format and I just stylistically prefer the "require" or "import" syntax.
There is no cross-scope mechanism for modules--we need to use the existing infrastructure for managing cross-scope access and defining our public interfaces using script includes (after all, they solved this issue years ago).
The good news is that it's super easy--barely an inconvenience--and the syntax remains (in my opinion) quite elegant.
Add a wrapper, but let's do it the easy way
Adding a wrapper to expose the modules is pretty obvious. However, I really don't want to get into manually mapping every single property and method in a new script include class like "methodA = my_module.methodA", etc.
NOTE: Prior to Xanadu Patch 2 any attempt to call a script include which uses a module from another scope will give you the error "require is not defined". This was documented in PRB1767574 and fixed in XP2.
Create a new wrapper script include called "x_require"
In your instance switch to the scope with the modules you wish to expose and create a new script include with the following values:
Name: x_require
Accessible from: All application scopes
Script:
var x_require = function(path) {
return require(path);
};
Get the path to the module
Next we need to get the path to the module so that we can pass it to x_require.
Type sys_module.list in the left hand navigation and hit enter.
Navigate to your module (perhaps by filtering by the application). NOTE: Make sure you find the ".js" entry and not the package.json one and that you get the correct version as denoted in the path.
Copy the path value, e.g. x_snc_jon_test_3/jon-test-3/0.0.2/src/server/index.js
Use the module
Excellent, you're almost done. Let's just unit test it really quickly.
Navigate to System Definition > Scripts - Background.
Paste in the following example script, using the ES6+ or the ES5 syntax if you're sadly stuck in 2009. Modify the scope, path and method names to match your code.
const {methodA, propertyB } = your_scope.x_require("your/path/here"); // ES6+
var x = your_scope.x_require("your/path/here"); // ES5
x.methodA("test")
gs.info(x.propertyB);
Execute the script and verify that it works.
If you're calling from the original scope nothing will change, but you may use the drop down in background scripts to switch to the scope you will be calling from and the cross-scope configurations will be created automatically.
Summary
I kind of like this. The "wrap your modules in a script include" sort of bugged me at first. I mean, I don't want to write wrapper code! Now I realize that it's pretty elegant by leveraging a solution that's been in place for many years, the configuration is in code (i.e. if you see a reference to "x_require" you can figure out what it does and where the code is) and, IMO, the syntax is familiar, simple and explicitly displays the methods, the scope and the path to the module.
- 751 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Thank you Jon! I was driving myself mad trying to find a solution for this, it turns out I was in Washington and need to upgrade to Xanadu.