Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Electron: loading an external script and passing it into a function

Tags:

I am building an Atom Electron app. Right now I have this in the preload.js of one of my webviews:

var { requireTaskPool } = require('electron-remote');
var work = '';
var _ = require('lodash');

work = requireTaskPool(require.resolve('./local/path/to/js/file.js'));


function scriptRun() {
  console.log('Preload: Script Started');
  // `work` will get executed concurrently in separate background processes
  // and resolve with a promise
  _.times(1, () => {
    work(currentTab).then(result => {
      console.log(`Script stopped. Total time running was ${result} ms`);
    });
  });
}
module.exports = scriptRun;
scriptRun();

It gets a local script and then executes it in a background process.

I want to do the same exact thing, except I want to retrieve the script from an external source like so

work = requireTaskPool(require.resolve('https://ex.com/path/to/js/file.js'));

When I do this, I get errors like:

Uncaught Error: Cannot find module 'https://ex.com/path/to/js/file.js'

How can I load external scripts? And then use the loaded scripts with my work function. My feeling is that require only works with local files. If AJAX is the answer, can I see an example of how to get a script, then pass it into my work without executing it prior?

like image 711
T Mack Avatar asked Jul 20 '17 19:07

T Mack


1 Answers

I was able to load a remote js file and execute the function defined in it, hopefully it will provide you enough to start with...

my remote dummy.js, available online somewhere:

const dummy = () => console.log('dummy works');

my download.js:

const vm = require("vm");
const rp = require('request-promise');

module.exports = {
    downloadModule: async () => {
        try {
            let body = await rp('http://somewhere.online/dummy.js');
            let script = vm.createScript(body);
            script.runInThisContext();

            // this is the actual dummy method loaded from remote dummy.js
            // now available in this context:
            return dummy;

        } catch (err) {
            console.log('err', err);
        }
        return null;
    }
};

You need to add the request-promise package.

Then in my main.js I use it like this:

const {downloadModule} = require('./download');

downloadModule().then((dummy) => {
    if (dummy) dummy();
    else console.log('no dummy');
});

When I run it, this is what I get:

$ electron .

 dummy works

I wanted to create an actual module and require it, but I have not had the time to play with this further. If I accomplish that I will add it here.

like image 56
Predrag Stojadinović Avatar answered Sep 30 '22 14:09

Predrag Stojadinović