简体   繁体   中英

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

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?

You have not provided any details on your file.js. But I can give you the general idea.

There are two things that you need at minimum to call your package a module:

  1. file.js (of course you have it) and
  2. package.json

The structure of your file.js should be something like this:

//load your dependencies here

var something = require("something");

//module.exports is necessary to export your code, 
//so that you can fetch this code in another file by using require.

module.exports = function() {
    abc: function(){
         //code for abc function
    },
    xyz: function(){
         //code for xyz function
    }
}

Now if you put your package on any website, you can access it as:

npm install https://ex.com/path/to/js/file.js

Now, a copy of your package will be put into node-modules folder.

So, now you can access it as:

var x = require('name-of-your-package-in-node-modules');

Now, you can also do:

var abc = require('name-of-your-package-in-node-modules').abc;

or

var xyz = require('name-of-your-package-in-node-modules').xyz;

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM