3

I'm really stuck here. While the require of modules in mod_lua seems to work right similiar with the lua interpretor, the require() in mod_v8 seems to "include" the whole scripts. I haven't found a way to make works the import only the modules (not node modules) I need in the script.

For example, in the script I've some like below:

//core/dtmf_1.js

const a = (arg) => { return arg * 2 }
const b = (arg) => { return arg / 2 }


//I get an error DONT WORKS
exports.a = a
exports.b = b

The example below don't worked to me too, but does not throw an error.

//core/dtmf_2.js

export function a = (arg) => { return arg * 2 }
export function b = (arg) => { return arg / 2 }

Otherwise, when I call

//ivr.js
import a from 'core/dtmf_2.js' 

I get an error in 'import'

But if I simply do:

//core/dtmf_3.js
const function a = (arg) => { return arg * 2 }
const function b = (arg) => { return arg / 2 }
//ivr.js
require('core/dtmf_3.js')

console.log(b(30)) <-- WORKS! Outputs 15

I was wondering if there's some setting in conf of mod_v8 to allow the import of modules. I want to do that because I have diferent methods predefined in my library, but I rarely use more than one by service. Thanks in advice.

1 Answers1

3

FreeSwitch uses V8, not Node.js so you wont get require and export functions. For including JavaScript scripts you can use FreeSwitch include or require keywords - which are the same thing. Include will include entire script so you can't do something like example below because you are loading math.js twice so exception will occur: SyntaxError: Identifier 'pi' has already been declared (near: "const pi = 3.14;")

math.js

const pi = 3.14;

function circleArea(radius){
    return radius * radius * pi;
}

function sum(a, b){
    return a + b;
}

circle.js

include('/etc/freeswitch/test/math.js');

function getArea(radius){
    return circleArea(radius);
}

main.js

include('/etc/freeswitch/test/circle.js');
include('/etc/freeswitch/test/math.js');

//math.js
log( sum(5,10) );

//circle.js
log( getArea(10) );

Include function into variable

include implementation allows you to "copy-paste" code from script into script which calls include in first place so you can utilize that to load code into variables. For example:

math.js

(a, b) => {
    return a + b;
}

main.js

const sum = include('/etc/freeswitch/test/math.js');

//logs 15
log( sum(5, 10) );

Include self-invoking function into variable

Now you won't get problems with loading same script into global scope. We can get this to another level with use of self-invoking functions.

math.js

(() => {

    const pi = 3.14;

    function circleArea(radius){
        return radius * radius * pi;
    }

    function sum(a, b){
        return a + b;
    }

    return { circleArea, sum };

})();

main.js

const math = include('/etc/freeswitch/test/math.js');
const { sum, circleArea } = include('/etc/freeswitch/test/math.js');

//with module
log( math.circleArea(5) ); // logs 78.5
log( math.sum(5, 10) );    // logs 15

//direct call
log( circleArea(5) );      // logs 78.5
log( sum(5, 10) );         // logs 15

But every time you want to load math.js it will act as it's own module and will load multiple times, not acting like Node.js module. For example:

FreeSwitch

math.js

(() => {
    log("Math loaded...");
})();

main.js

const math1 = include('/etc/freeswitch/test/math.js');
const math2 = include('/etc/freeswitch/test/math.js');

This prints "Math loaded..." twice.

Node.js

math.js

(() => {
    console.log("Math loaded...");
})();

main.js

const math1 = require('./math.js');
const math2 = require('./math.js');

This prints "Math loaded..." once.

Include self-invoking function into variable only once

From here you can write your own include script (it is still bad approach, but should work). Something like this:

include.js

if (typeof _include === 'undefined') {

    var _loadedScripts = {};

    function _include(script){
        if (!_loadedScripts.hasOwnProperty(script)){
            _loadedScripts[script] = include(script);
        }
        return _loadedScripts[script];
    }

}

And then you can write your modules like before:

math.js

(() => {

    log("Math loaded...");

    var pi = 3.14;

    return { pi };

})();

And when you want to include scripts:

main.js

include('/etc/freeswitch/include.js');

const math1 = _include('/etc/freeswitch/test/math.js');
const math2 = _include('/etc/freeswitch/test/math.js');

math1.pi = 10;
math2.pi = 20;

log(math1.pi);
log(math2.pi);

This will produce:

Math loaded...
20
20

[EDIT]

Include.js is the only script that is not loaded as "module" so it will be loaded multiple times. You can prevent this by replacing default include function with your own and instead of include you use require.

include.js

if (typeof _include === 'undefined') {

    var _loadedScripts = {};

    function _include(script){
        if (!_loadedScripts.hasOwnProperty(script)){
            _loadedScripts[script] = require(script);
        }
        return _loadedScripts[script];
    }

    include = () => {  };

}

Now if Include.js is already included, everytime you call include("include.js") it won't load again.

IvanPenga
  • 325
  • 1
  • 10