skip to Main Content

I have a function that lets me run a JavaScript function in the browser:

export async function executeFunction(data: LoadOutput, input: Record<string, any>): Promise<any> {
    let args = [];
    for (let param of data.functionTree[0].parameters) {
        let value = input[param.name];

        if(!value) {
            return undefined;
        }

        args.push(value);
    }

    let func = new Function('return ' + data.jsCode)();
    return await func.call(null, ...args);
}

It all works, but now I want to add more functionality by being able to use external libraries.
I tried adding imports in the string but this didn’t work and resulted in errors

There was an error: Module name, 'image-conversion' does not resolve to a valid URL.

Is there a way I can import external libraries?
Preferably by not having to pass them as a parameter (That’s what ChatGPT suggested but would require a massive refactor of my code)

Is there maybe a library that does the same thing as Function but lets me add external libraries to the scope?

For additional information: I’m using SvelteKit

2

Answers


  1. Chosen as BEST ANSWER

    I know managed to do it. I imported a library (I used lodash as an example for testing) and saved it into a const

    import lodash from 'lodash';
    const libraries = { lodash }
    

    I pass it into the Function call like this

    let func = new Function(...Object.keys(libraries), 'return ' + data.jsCode)(...Object.values(libraries));
    return await func.call(null, ...args);
    

    And now I can use lodash when calling a function from a string.

    Here is my testing example:

    "libraryTest": "function libraryTest(text: string): { result: string } {n" +
        "    const result = lodash.toUpper(text);n" +
        "    return { result };n" +
        "}"
    

  2. Such dependencies cannot be fully dynamic unless you somehow ship all your node modules and do some complicated on-the-fly bundling, but you can probably e.g. somewhere import the module via an URL import and use that.

    import imageConversionUrl from 'image-conversion?url';
    
    `import ... from ${JSON.stringify(imageConversionUrl)}`
    

    URL imports bundle the dependency and output it as an asset in the build.
    (More commonly used for media assets so they can be used e.g. as an image src. For a list of file types URL imports are the implicit default.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search