如何要求从URL在Node.js

how to require from URL in Node.js

本文关键字:Node js URL      更新时间:2023-09-26

是否有一种标准方法来要求位于某个URL(而不是本地文件系统)的Node模块?

类似:

require('http://example.com/nodejsmodules/myModule.js');

目前,我只是将文件提取到一个临时文件中,并要求这样做。

您可以使用http获取模块。get方法,并使用vm模块方法runInThisContext和runInNewContext在沙箱中执行。

例子
var http = require('http')
  , vm = require('vm')
  , concat = require('concat-stream'); // this is just a helper to receive the
                                       // http payload in a single callback
                                       // see https://www.npmjs.com/package/concat-stream
http.get({
    host: 'example.com', 
    port: 80, 
    path: '/hello.js'
  }, 
  function(res) {
    res.setEncoding('utf8');
    res.pipe(concat({ encoding: 'string' }, function(remoteSrc) {
      vm.runInThisContext(remoteSrc, 'remote_modules/hello.js');
    }));
});
依我看,在没有替代方案的情况下,在服务器应用程序运行时内执行远程代码可能是合理的。

先安装模块:

npm install require-from-url

然后写入文件:

var requireFromUrl = require('require-from-url/sync');
requireFromUrl("http://example.com/nodejsmodules/myModule.js");

0依赖版本(需要节点6+,你可以简单地改回ES5)

const http = require('http'), vm = require('vm');
['http://example.com/nodejsmodules/myModule.js'].forEach(url => {
    http.get(url, res => {
        if (res.statusCode === 200 && /'/javascript/.test(res.headers['content-type'])) {
            let rawData = '';
            res.setEncoding('utf8');
            res.on('data', chunk => { rawData += chunk; });
            res.on('end', () => { vm.runInThisContext(rawData, url); });
        }
    });
});

它仍然是异步版本,如果是同步加载的情况下,应该需要一个sync http request module为例

如果您想要更像require的东西,您可以这样做:

var http = require('http')
  , vm = require('vm')
  , concat = require('concat-stream') 
  , async = require('async'); 
function http_require(url, callback) {
  http.get(url, function(res) {
    // console.log('fetching: ' + url)
    res.setEncoding('utf8');
    res.pipe(concat({encoding: 'string'}, function(data) {
      callback(null, vm.runInThisContext(data));
    }));
  })
}
urls = [
  'http://example.com/nodejsmodules/myModule1.js',
  'http://example.com/nodejsmodules/myModule2.js',
  'http://example.com/nodejsmodules/myModule3.js',
]
async.map(urls, http_require, function(err, results) {
  // `results` is an array of values returned by `runInThisContext`
  // the rest of your program logic
});

你可以重写.js文件的默认require处理程序:

require.extensions['.js'] = function (module, filename) {
    // ...
}

您可能想签出better-require,因为它对许多文件格式都做了很多这样的工作。(我写的)


  const localeSrc = 'https://www.trip.com/m/i18n/100012631/zh-HK.js';
  const http = require('http');
  const vm = require('vm');
  const concat = require('concat-stream');
  http.get(
    localeSrc,
    res => {
      res.setEncoding('utf8');
      res.pipe(
        concat({ encoding: 'string' }, remoteSrc => {
          let context = {};
          const script = new vm.Script(remoteSrc);
          script.runInNewContext(context);
          console.log(context);
        }),
      );
    },
    err => {
      console.log('err', err);
    },
  );