laurentj / slimerjs

A scriptable browser like PhantomJS, based on Firefox
http://slimerjs.org
Other
3k stars 259 forks source link

Can not resolve required module encoding #497

Open sdtemp-ml opened 8 years ago

sdtemp-ml commented 8 years ago

versions

    $ SLIMERJSLAUNCHER=/usr/bin/firefox46 slimerjs --version
    Innophi SlimerJS 0.10.1-pre, Copyright 2012-2016 Laurent Jouanneau & Innophi
    $ /usr/bin/firefox46 --version
    Mozilla Firefox 46.0.1
    $ cat /etc/issue
    Ubuntu 14.04.4 LTS \n \l

Steps to reproduce the issue

For details, please see: http://stackoverflow.com/questions/37748127/slimerjs-can-not-resolve-required-module-encoding

But basically:

$ npm install -g encoding
encoding@0.1.12 /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding
└── iconv-lite@0.4.13

$ ls -la `which slimerjs`
lrwxrwxrwx 1 root root 46 Jun  9 15:15 /usr/bin/slimerjs -> /path/to/slimerjs-0.10.1-pre/slimerjs

test_modload.js is:

var encoding = require('encoding');
var casper = require('casper').create();
casper.run();

run with:

NODE_PATH=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules SLIMERJSLAUNCHER=/usr/bin/firefox46 slimerjs test_modload.js

Actual results:

Script Error: Module: Can not resolve "encoding" module required by main located at file:///path/to/test/test_modload.js
       Stack:
         -> file:///path/to/test/test_modload.js: 350

Expected results:

Well, the webpage https://docs.slimerjs.org/current/release-notes-0.10.html says:

require supports node modules (it searches into node_modules directories)

so, it should work without error?!

laurentj commented 8 years ago

Yes it support node_modules, but those are in the same directory of your script. It doesn't search in $HOME/.nvm or else : there could be hundred node_modules, it would be to slow to search in all of these directories.

So if the path is /some/where/test_modload.js,, with require('encoding') it searches the module into /some/where/encoding.js, or in /some/where/node_modules/encoding/.

However, you can indicate where Slimerjs should search, with require.paths

laurentj commented 8 years ago

The documentation should be improved about this feature.

sdtemp-ml commented 8 years ago

Hi @laurentj,

Many thanks for the prompt feedback - it explains a lot!

I just wanted to report back, as I cannot seem to get the recommendations working:

However, you can indicate where Slimerjs should search, with require.paths

I tried this script as test_modload.js:

require.paths.push('/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/lib'); // ok?
require.paths.push('/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/node_modules/iconv-lite/lib'); //nope
require.paths.push('/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/node_modules'); //nope
var encoding = require('encoding');
var casper = require('casper').create();
console.log( encoding.convert("test", 'ASCII', 'UTF-8') );
casper.run();

This fails with:

$ SLIMERJSLAUNCHER=/usr/bin/firefox46 slimerjs test_modload.js
...
Script Error: Module: Can not resolve "iconv-lite" module required by encoding located at file:///home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/lib/encoding.js
       Stack:
         -> file:///home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/lib/encoding.js: 350

So, the encoding module here is found - but its dependency, iconv-lite, isn't - even if I tried explicitly adding its path. Note that the encoding module files are:

$ tree /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/
/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/
├── lib
│   ├── encoding.js
│   └── iconv-loader.js
├── LICENSE
├── node_modules
│   └── iconv-lite
│       ├── Changelog.md
│       ├── encodings
│       │   ├── dbcs-codec.js
│       │   ├── dbcs-data.js
│       │   ├── index.js
│       │   ├── internal.js
│       │   ├── sbcs-codec.js
│       │   ├── sbcs-data-generated.js
│       │   ├── sbcs-data.js
│       │   ├── tables
│       │   │   ├── big5-added.json
│       │   │   ├── cp936.json
│       │   │   ├── cp949.json
│       │   │   ├── cp950.json
│       │   │   ├── eucjp.json
│       │   │   ├── gb18030-ranges.json
│       │   │   ├── gbk-added.json
│       │   │   └── shiftjis.json
│       │   ├── utf16.js
│       │   └── utf7.js
│       ├── lib
│       │   ├── bom-handling.js
│       │   ├── extend-node.js
│       │   ├── index.js
│       │   └── streams.js
│       ├── LICENSE
│       ├── package.json
│       └── README.md
├── package.json
├── README.md
└── test
    └── test.js

That is, we have encoding.js file in $HOME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding, and that file is apparently loaded correctly via require.paths. But the dependency $HOME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding/node_modules/iconv-lite does not have a iconv-lite.js, only a package.json (which is only used by npm) - and seemingly this is a problem for slimerjs to load?!

Otherwise, are there any other suggestions, on what else I'd need to include in require.paths, in order to load this library?

Another thing - if I use the exact same test_modload.js, except I run it with node (v4.0.0) instead, I get this:

$ node test_modload.js
module.js:392
    throw new Error('require.paths is removed. Use ' +
    ^

Error: require.paths is removed. Use node_modules folders, or the NODE_PATH environment variable instead.
    at Function.Object.defineProperty.get (module.js:392:11)
    at Object.<anonymous> (/path/to/test/test_modload.js:1:70)
    at Module._compile (module.js:434:26)
    at Object.Module._extensions..js (module.js:452:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:475:10)
    at startup (node.js:117:18)
    at node.js:951:3

Should I be worried about this error message?

Finally, I tried this:

So if the path is /some/where/test_modload.js,, with require('encoding') it searches the module into /some/where/encoding.js, or in /some/where/node_modules/encoding/.

... with test_modload.js script with removed require.paths.push:

var encoding = require('encoding');
var casper = require('casper').create();
console.log( encoding.convert("test", 'ASCII', 'UTF-8') );
casper.run();

... and preparing like this:

mkdir node_modules
cp -a /home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules/encoding node_modules/

... and running like this:

$ ls node_modules/
encoding
$ SLIMERJSLAUNCHER=/usr/bin/firefox46 slimerjs test_modload.js

Script Error: Module: Can not resolve "encoding" module required by main located at file:///path/to/test/test_modload.js
       Stack:
         -> file:///path/to/test/test_modload.js: 350

So, apparently, just adding/copying the node_modules folder in say /path/to/test/ (where the test_modload.js) does not seem to work. What am I missing here - any suggestions for what I can try, to get the loading process to work here?