My application consists of multiple script files on the front end. Each such file is in need of a module:
//foo.js
var myModule = require('../module/myMod');
//bar.js
var myModule = require('../module/myMod');
I am using browserify to get this to work.
Now I would like to configure my module at a central point
//aCentralPoint.js
var myModule = require('../module/myMod');
myModule.configure(//...);
//foo.js
var myModule = require('../module/myMod');
/**
* I would expect this to be what I set in aCentralPoint.js
*/
console.log(myModule.config);
Unfortunately, due to the fact that myModule will be freshly injected into each file requiring it, this is unpossible.
How can I do this?
The require function will always return the same instance of the module.
If in module.js you have:
module.exports = {name: 'my object'};
Then in foo.js:
require('./module').foo = 'hello from foo';
If you require it later in bar.js:
console.log(require('./module')); //prints {name: 'my object', foo: 'hello from foo'}
Set up a plunker
Related
I'm using PythonNet to call a Python script from within a C# code.
I would like to define a module in a string variable (like myModule in the code below) and to be able to import that module and use its functions later:
using (Py.GIL())
{
// create a Python scope
using (PyScope scope = Py.CreateScope())
{
string myModule = #"# a lot of fancy Python code"; // Define a module here
// Here I'd like to register myModule as a module,
// to be used later within this scope: what shall I do?
string script = #"import myModule as functions"; // import and use the module here
scope.Exec(script);
...
string s = scope.Eval<string>(...);
return s;
}
}
How can this be achieved?
The PyScope class defines an overload of Import that accepts a PyScope and a string as parameters.
First, execute your module in a scope (moduleScope), then you can import it in a second scope
using (PyScope moduleScope = Py.CreateScope())
{
string myModule = #"# a lot of fancy Python code"; // Define a module here
moduleScope.Exec(myModule);
// create a Python scope
using (PyScope scope = Py.CreateScope())
{
scope.Import(moduleScope, "functions");
double d = scope.Eval<double>("functions.my_variable");
...
I'm trying to load my custom module base on the condition.
CustomModule.js
define([], function(){
export {
run: function(){ log.debug('run in CustomModule' }
};
}
And here is my user event script
userevent.js
define(['N/record'], function(record){
...
var moduleName = record.getValue('custom_module_name'); // will return CustomModule.js
require([moduleName], function(customModule){
customModule.run();
});
});
But I got following error
{
type: "error.SuiteScriptModuleLoaderError",
name: "INCORRECT_SUITESCRIPT_CONFIGURATION",
message: "Incorrect SuiteScript configuration for module: CustomModule.js",
}
When I using preload like define(['CustomModule.js'), function(customModule){...})
is working, but this might not suitable for our scenario.
Any suggestion?
So the way you would call a custom module would be (sample snippets below):
CustomModule.js [Code in file cabinet]
define([], function() {
// You can have multiple functions
function testFunction() {
log.debug("Run in CustomModule");
return 123;
}
return { // Return all your functions here
testFunction: testFunction
};
});
And the way you would call the custom module functions in other scripts would be:
Sample User Event Script:
/**
* #NApiVersion 2.x
* #NScriptType UserEventScript
* #NModuleScope SameAccount
*/
define(['./CustomModule.js'], function(customModule) {
.....
function sampleFunction(customerId, recId, invNumberCounter) {
var storeNumber = customModule.testFunction(); // value of 'storeNumber' will be 123
}
.....
});
Additional Important Note:
When writing library scripts (custom modules), have the client-side supported modules in a different script and server-side supported modules in a different script.
This is because, if you incorporate a library script that has a module which is supported only by server-side scripts (eg. N/task module) into a client script, an error would be thrown saying that the module is not supported in this scrpt.
Hope this helps.
I'm stuck with the right way to import an AMD JavaScript library (https://github.com/dcodeIO/bytebuffer.js) into a TypeScript file.
I found its - not up-to-date - type definition (https://github.com/SINTEF-9012/Proto2TypeScript/commit/0889dccbf6048f116551a73e77d75dd83553cfe6), but actually I was not able to find a way to use it and have the library loaded by RequireJS.
This is the code I'm using:
/// <amd-dependency path="Scripts/bytebuffer" />
var ByteBuffer = require( 'Scripts/bytebuffer' );
import protocols = require( 'protocols' );
export class Pippo
{
readPayload( payload: ArrayBuffer, ECType: string ): any
{
var ECStruct = new protocols.ECStruct( ECType );
var bb = new ByteBuffer()
.writeIString( "Hello world!" )
.flip();
console.log( bb.readIString() + " from bytebuffer.js" );
}
}
The two modules protocols and bytebuffer are loaded correctly, but actually I cannot see members of instance bb in Visual Studio. If I put the line
/// <reference path="scripts/typings/bytebuffer/bytebuffer.d.ts" />
and comment
//var ByteBuffer = require( 'Scripts/bytebuffer' );
of course I can see methods and properties of bb, but the module is not loaded at runtime.
Is there a way to have the ByteBuffer.js loaded by RequireJS with the possibility to see its members in VS?
Thanks
There is a syntax for declaring the interface of external modules:
declare module 'amd/module/name' {
// module definition, probably with:
exports = thingToExport;
}
In your case it should probably be:
declare module 'Scripts/bytebuffer' {
exports = ByteBuffer;
}
Put this after the bytebuffer.d.ts file!!! Also see "Writing .d.ts files" in the handbook.
In my case the /// <amd-dependency> and /// <reference> stuff were also redundant - you may want to try it too, to simplify your code.
Have a question with regards to the default meanjs app from yeoman.
Inside the express.js file it has a statement like so:
// Globbing model files
config.getGlobbedFiles('./app/models/**/*.js').forEach(function(modelPath) {
require(path.resolve(modelPath));
});
Now I understand that it gets all the .js files inside the path "./app/models/", but what I am trying to understand is the alone standing
require(path.resolve(modelPath));
How is the require function being used without it being set to a "var"?
An example of one of these included files is like this:
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Article Schema
*/
var ArticleSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
content: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
mongoose.model('Article', ArticleSchema);
This file doesn't expose anything.
So why is the require being called with a "var" and without the contents exposing a function?
How will this allow for the contents to be used later?
The code in the express.js file executes the contents of your model files. The anatomy of a MEAN.js model file is the following;
Load the mongoose and schema packages, along with all your included
models (if any).
Declare the schema for the given model
Register the given schema under the model name (Article for the given example).
There is nothing to return, hence the lack of any variable assignment in the express.js file. From now on you can call models by the label you assigned in the third part. Therefore, in your controller, you would write something like;
var articles = Article.query();
This line of code would load up the Article schema and run the provided query() method in your back-end (which by default returns all the instances in the database under that model).
In general, remember; not all functions return something.
I'm developing an NPM package using typescript. Within this package the TS files are setup as external modules. The compiler won't generate a single .d.ts for external modules. I'm trying to concat all tsc generated type definitions into a single .d.ts for the entire package.
I'm having issues laying out the single .d.ts file (following a similar approach to that used in grunt-dts-bundle). The condensed example below captures my issue.
Given this external module declaration and test file:
test.d.ts :
declare module "ExternalWrapper" {
export import Foo = require("FooModule");
}
declare module "FooModule" {
class Foo {
name: string;
}
export = Foo;
}
test.ts:
import externalWrapper = require( 'ExternalWrapper' );
var t = new externalWrapper.Foo();
Running tsc test.ts test.d.ts -m commonjs produces this error: TS2083: Invalid 'new' expression.
If you change 'test.ts' to look like this, importing 'FooModule' directly:
import Foo = require( "FooModule" );
var t = new Foo();
It compiles fine.
The compiler understands the type externalWrapper.Foo however it doesn't seem to represent it as the same type FooModule.Foo. There is something I'm not getting about how the compilers handles modules that are exported via 'export import'.
Failing the above I'll probably look to manually creating the .d.ts :(
Any help appreciated.
You are probably missing a reference tag:
/// <reference path="test.d.ts"/>
It works :
You should be able to fix this by modifying your .d.ts file to resemble the following:
declare module "ExternalWrapper" {
import FooModule = require("FooModule");
export var Foo: typeof FooModule;
}
declare module "FooModule" {
class Foo {
name: string;
}
export = Foo;
}
With the export import syntax the compiler was assuming you were exporting an instance of Foo, not Foo itself... a little quirky.