PhantomJS require() a relative path

别说谁变了你拦得住时间么 提交于 2021-02-06 00:52:32

问题


In a PhantomJS script I would like to load a custom module but it seems relative paths do not works in PhantomJS ?

script.js:

var foo = require('./script/lib/foo.js');
foo.bar('hello world');
phantom.exit();

foo.js:

exports.bar = function(text){
  console.log(text);
}
  • According to fs.workingDirectory I am in the good directory
  • foo.js is not in the lookup path of phantomjs

Am I missing something ?

EDIT:

inject() is not revelant because I do not need to inject a JS to an HTML page but instead load my own module like require('fs') but with a relative path.


回答1:


After a lot of time searching for the same thing, here is what I understood, though I might be wrong :

  • PhantomJS doesn't use Node's require, but its own require, so things are different
  • when providing a relative path to phantomjs's require, it is always interpreted as relative to the current working directory
  • PhantomJS doesn't implement node's __dirname, and as such there is no direct way to have the directory of your script

The solution I found least annoying :

  • if using phantomjs pure, without casperjs :

    require(phantom.libraryPath + '/script/lib/foo.js')
    
  • if using casperjs :

    var scriptName = fs.absolute( require("system").args[3] );
    var scriptDirectory = scriptName.substring(0, scriptName.lastIndexOf('/'));
    require(scriptDirectory + '/script/lib/foo.js')
    



回答2:


To load your own module, the right way to do it is to use module.exports, like this: foo.js

function bar(text) {
   console.log(text);
}

exports.bar = bar 

And in script.js (which is executed with phantomjs script.js):

var foo = require('./script/lib/foo');
foo.bar('hello world');
phantom.exit();



回答3:


My solution to load a resource file (like let's say a json file) within a phantomjs subfolder from a outer folder like in this structure:

├── consumer.js
├── assets
    ├── data.json
    ├── loader.js

Supposed that data.json must be load by the consumer module and that this module is called by somewhere else on this machine, outside the project root folder, the fs.workingDirectory will not work, since it will be the path of the caller file. So to solve this, I did a simple loader module within the assets folder, where the files I want to load are:

(function() {

var loader = {
    load : function(fileName) {
        var res=require('./'+fileName);
        return res;
    }
}
module.exports=loader;

}).call(this);

I therefore call the loader module from the consumer module like

var loader=require('./data/loader');
var assets=loader.load('data.json');

and that's it.

NOTE. The require here is the phantomjs require not the node version, so it works a bit differently. In this case the data.json was a json array with no module.exports declaration. The array will be backed in the assets variable directly when calling the loader.load(fileName) method.




回答4:


have you tried to use injectJs(filename)

excerpt form PhantomJS documentation:

Injects external script code from the specified file. If the file can not be found in the current directory, libraryPath is used for additional look up.

This function returns true if injection is successful, otherwise it returns false.




回答5:


Which PhantomJS version are you running? Support for user provided modules was added in 1.7.



来源:https://stackoverflow.com/questions/11873853/phantomjs-require-a-relative-path

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!