Issues when running under phantomjs #184

Closed
opened 2015-02-28 02:23:21 +00:00 by machinewu · 14 comments
machinewu commented 2015-02-28 02:23:21 +00:00 (Migrated from github.com)

I wrote a simple test ir run by phantomjs (Ubuntu):
test.js

var fs = require('fs');
var xlsx = require('./xlsx');
var page = require('webpage').create();

page.open('http://www.google.com', function(status) {

  var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'});
  var workbook = xlsx.read(data, {type: 'binary'});
  data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']);
  console.log("Data: " + data);

  phantom.exit();
});

Directory tree of phantomjs dir "phantomjs/bin":

  • a.xlsx
  • dist/cpexcel.js
  • jszip.js
  • phantomjs
  • test.js
  • xlsx.js

Run-time error occurred:
TypeError: 'undefined' is not a constructor (evaluating 'new jszip(d, { base64:false })')

for the reason, I found in xlsx.js:

if(typeof JSZip !== 'undefined') jszip = JSZip;
if (typeof exports !== 'undefined') {
    if (typeof module !== 'undefined' && module.exports) {
        if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip');  // not go here, because has_buf is false
        if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;  // go here, but require('./jszip').JSZip is a wrong require!!!  require('./jszip') is a correct require.
        _fs = require('f'+'s');
    }
}
I wrote a simple test ir run by phantomjs (Ubuntu): **test.js** ``` var fs = require('fs'); var xlsx = require('./xlsx'); var page = require('webpage').create(); page.open('http://www.google.com', function(status) { var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'}); var workbook = xlsx.read(data, {type: 'binary'}); data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']); console.log("Data: " + data); phantom.exit(); }); ``` Directory tree of phantomjs dir "phantomjs/bin": - a.xlsx - dist/cpexcel.js - jszip.js - phantomjs - test.js - xlsx.js Run-time error occurred: TypeError: 'undefined' is not a constructor (evaluating 'new jszip(d, { base64:false })') for the reason, I found in **xlsx.js**: ``` if(typeof JSZip !== 'undefined') jszip = JSZip; if (typeof exports !== 'undefined') { if (typeof module !== 'undefined' && module.exports) { if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip'); // not go here, because has_buf is false if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip; // go here, but require('./jszip').JSZip is a wrong require!!! require('./jszip') is a correct require. _fs = require('f'+'s'); } } ```
SheetJSDev commented 2015-02-28 02:41:13 +00:00 (Migrated from github.com)

@machinewu Let's keep all of the relevant phantomjs issues to this discussion (I closed the other issue)

Can you check if require('./jszip').JSZip is defined in test.js?

Also, with regards to the other issue, do you happen to know what is the correct way to detect if the script is being run in a phantomjs context? Clearly that part (fs detection and read/write semantics) needs to be reevaluated.

@machinewu Let's keep all of the relevant phantomjs issues to this discussion (I closed the other issue) Can you check if `require('./jszip').JSZip` is defined in test.js? Also, with regards to the other issue, do you happen to know what is the correct way to detect if the script is being run in a phantomjs context? Clearly that part (fs detection and read/write semantics) needs to be reevaluated.
machinewu commented 2015-02-28 02:53:50 +00:00 (Migrated from github.com)

I change the xlsx.js

if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip;

to

if(typeof jszip === 'undefined') jszip = require('./js'+'zip');

and run script test.js in phantomjs, it work.

so, I write some console log in xlsx.js to trace the jszip where it define by require. I found in phantomjs, it should not require: jszip = require('./js'+'zip').JSZip, but jszip = require('./js'+'zip')

The trace code:

var _fs, jszip;
if(typeof JSZip !== 'undefined') { jszip = JSZip; console.log("Trace1:", typeof jszip);}
if (typeof exports !== 'undefined') {
    console.log("Trace2");
    if (typeof module !== 'undefined' && module.exports) {
        console.log("Trace3");
        if(has_buf && typeof jszip === 'undefined') {jszip = require('js'+'zip'); console.log("Trace4", typeof jszip);}
        if(typeof jszip === 'undefined') {jszip = require('./js'+'zip').JSZip; console.log("Trace5", typeof jszip);}
        _fs = require('f'+'s');
    }
    {console.log("Trace6", typeof jszip);}
}

result:

Trace2
Trace3
Trace5 undefined
Trace6 undefined
TypeError: 'undefined' is not a constructor (evaluating 'new jszip(d, { base64:false })')

After change jszip = require('./js'+'zip').JSZip to jszip = require('./js'+'zip'):
The trace code:

var _fs, jszip;
if(typeof JSZip !== 'undefined') { jszip = JSZip; console.log("Trace1:", typeof jszip);}
if (typeof exports !== 'undefined') {
    console.log("Trace2");
    if (typeof module !== 'undefined' && module.exports) {
        console.log("Trace3");
        if(has_buf && typeof jszip === 'undefined') {jszip = require('js'+'zip'); console.log("Trace4", typeof jszip);}
        if(typeof jszip === 'undefined') {jszip = require('./js'+'zip'); console.log("Trace5", typeof jszip);}
        _fs = require('f'+'s');
    }
    {console.log("Trace6", typeof jszip);}
}

result:

Trace2
Trace3
Trace5 function
Trace6 function

I change the xlsx.js ``` if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip; ``` to ``` if(typeof jszip === 'undefined') jszip = require('./js'+'zip'); ``` and run script test.js in phantomjs, it work. so, I write some console log in xlsx.js to trace the jszip where it define by require. I found in phantomjs, it should not require: **jszip = require('./js'+'zip').JSZip**, but **jszip = require('./js'+'zip')** The trace code: ``` var _fs, jszip; if(typeof JSZip !== 'undefined') { jszip = JSZip; console.log("Trace1:", typeof jszip);} if (typeof exports !== 'undefined') { console.log("Trace2"); if (typeof module !== 'undefined' && module.exports) { console.log("Trace3"); if(has_buf && typeof jszip === 'undefined') {jszip = require('js'+'zip'); console.log("Trace4", typeof jszip);} if(typeof jszip === 'undefined') {jszip = require('./js'+'zip').JSZip; console.log("Trace5", typeof jszip);} _fs = require('f'+'s'); } {console.log("Trace6", typeof jszip);} } ``` result: > Trace2 > Trace3 > Trace5 undefined > Trace6 undefined > TypeError: 'undefined' is not a constructor (evaluating 'new jszip(d, { base64:false })') After change **jszip = require('./js'+'zip').JSZip** to **jszip = require('./js'+'zip')**: The trace code: ``` var _fs, jszip; if(typeof JSZip !== 'undefined') { jszip = JSZip; console.log("Trace1:", typeof jszip);} if (typeof exports !== 'undefined') { console.log("Trace2"); if (typeof module !== 'undefined' && module.exports) { console.log("Trace3"); if(has_buf && typeof jszip === 'undefined') {jszip = require('js'+'zip'); console.log("Trace4", typeof jszip);} if(typeof jszip === 'undefined') {jszip = require('./js'+'zip'); console.log("Trace5", typeof jszip);} _fs = require('f'+'s'); } {console.log("Trace6", typeof jszip);} } ``` result: > Trace2 > Trace3 > Trace5 function > Trace6 function
machinewu commented 2015-02-28 03:02:30 +00:00 (Migrated from github.com)

If I define JSZip at my code at first in phantomjs, It can work.

var fs = require('fs');
var JSZip = require('./jszip');
var xlsx = require('./xlsx');
var page = require('webpage').create();
If I define JSZip at my code at first in phantomjs, It can work. ``` var fs = require('fs'); var JSZip = require('./jszip'); var xlsx = require('./xlsx'); var page = require('webpage').create(); ```
machinewu commented 2015-02-28 03:34:56 +00:00 (Migrated from github.com)

If I defined JSZip in a module but not global, it does not work.
test_module.js locate in the diretcory the same as test.js

Not work code:
test.js

var process = require('./test_module');
var page = require('webpage').create();

page.open('http://www.google.com', function(status) {
    process.run();
    phantom.exit();
});

test_module.js

var fs = require('fs');
var JSZip = require('./jszip');
var xlsx = require('./xlsx');

exports.run = function () {
    var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'});
    var workbook = xlsx.read(data, {type: 'binary'});
    data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']);
    console.log("Status: " + data);
}

Work code:
test.js

var JSZip = require('./jszip');
var process = require('./test_module');
var page = require('webpage').create();

page.open('http://www.google.com', function(status) {
    process.run();

    phantom.exit();
});

test_module.js

var fs = require('fs');
var xlsx = require('./xlsx');

exports.run = function () {
    var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'});
    var workbook = xlsx.read(data, {type: 'binary'});
    data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']);
    console.log("Status: " + data);
}

I think jszip should require more automatic, less manual require.

If I defined JSZip in a module but not global, it does not work. test_module.js locate in the diretcory the same as test.js Not work code: **test.js** ``` var process = require('./test_module'); var page = require('webpage').create(); page.open('http://www.google.com', function(status) { process.run(); phantom.exit(); }); ``` **test_module.js** ``` var fs = require('fs'); var JSZip = require('./jszip'); var xlsx = require('./xlsx'); exports.run = function () { var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'}); var workbook = xlsx.read(data, {type: 'binary'}); data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']); console.log("Status: " + data); } ``` Work code: **test.js** ``` var JSZip = require('./jszip'); var process = require('./test_module'); var page = require('webpage').create(); page.open('http://www.google.com', function(status) { process.run(); phantom.exit(); }); ``` **test_module.js** ``` var fs = require('fs'); var xlsx = require('./xlsx'); exports.run = function () { var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'}); var workbook = xlsx.read(data, {type: 'binary'}); data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']); console.log("Status: " + data); } ``` I think jszip should require more automatic, less manual require.
SheetJSDev commented 2015-02-28 03:38:30 +00:00 (Migrated from github.com)

@machinewu last question: what happens if you use the xlsx.core.min.js file https://github.com/SheetJS/js-xlsx/blob/master/dist/xlsx.core.min.js in place of xlsx.js? When using this file, JSZip should not be pulled with require (it is defined so that entire code block is skipped)

@machinewu last question: what happens if you use the xlsx.core.min.js file https://github.com/SheetJS/js-xlsx/blob/master/dist/xlsx.core.min.js in place of xlsx.js? When using this file, JSZip should not be pulled with `require` (it is defined so that entire code block is skipped)
machinewu commented 2015-02-28 03:53:55 +00:00 (Migrated from github.com)

I change the name xlsx.core.min.js to xlsx.js, and replace the original xlsx.js. Remove jszip.js and dist/cpexcel.js.

test_module.js

var fs = require('fs');
var xlsx = require('./xlsx');

exports.run = function () {
    console.log('=== xlsx:', typeof xlsx);
    var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'});
    var workbook = xlsx.read(data, {type: 'binary'});
    data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']);
    console.log("Status: " + data);
}

Terminal display:

SyntaxError: Parse error

=== xlsx: object
TypeError: 'undefined' is not a function (evaluating 'xlsx.read(data, {type: 'binary'})')

I change the name xlsx.core.min.js to xlsx.js, and replace the original xlsx.js. Remove jszip.js and dist/cpexcel.js. **test_module.js** ``` var fs = require('fs'); var xlsx = require('./xlsx'); exports.run = function () { console.log('=== xlsx:', typeof xlsx); var data = fs.read('a.xlsx', {mode: 'rb', charset: 'utf8'}); var workbook = xlsx.read(data, {type: 'binary'}); data = xlsx.utils.sheet_to_csv(workbook.Sheets['Worksheet']); console.log("Status: " + data); } ``` Terminal display: > SyntaxError: Parse error > > === xlsx: object > TypeError: 'undefined' is not a function (evaluating 'xlsx.read(data, {type: 'binary'})')
SheetJSDev commented 2015-02-28 04:09:14 +00:00 (Migrated from github.com)

@machinewu thanks for looking into this! You've exposed quite a few interesting issues.

That workaround is in the code because the jszip.js script uses a different version from the nodejs module (there were quite a few problems when they stopped using https://github.com/imaya/zlib.js for DEFLATE). I will do some more tests in the browser with the latest version. If it works out, we can update the browser dependency and simplify the require logic

@machinewu thanks for looking into this! You've exposed quite a few interesting issues. That workaround is in the code because the jszip.js script uses a different version from the nodejs module (there were quite a few problems when they stopped using https://github.com/imaya/zlib.js for DEFLATE). I will do some more tests in the browser with the latest version. If it works out, we can update the browser dependency and simplify the require logic
brunoshine commented 2015-03-04 19:25:33 +00:00 (Migrated from github.com)

Hi all,

I'm also experiencing some issues, but in my case the message is different:
_TypeError: undefined is not a constructor (evaluating 'fs.readFileSync(data)')

I've installed xlsx via npm.

my code is:

var page = new WebPage(), testindex = 0, loadInProgress = false;
var fs = require('fs');
var XLSX = require('xlsx');

var workbook = XLSX.readFile('data.xlsx');

Any thoughts?

Thanks,
Bruno

Hi all, I'm also experiencing some issues, but in my case the message is different: _TypeError: undefined is not a constructor (evaluating '_fs.readFileSync(data)')_ I've installed xlsx via npm. my code is: ``` var page = new WebPage(), testindex = 0, loadInProgress = false; var fs = require('fs'); var XLSX = require('xlsx'); var workbook = XLSX.readFile('data.xlsx'); ``` Any thoughts? Thanks, Bruno
LinusU commented 2015-06-15 11:39:56 +00:00 (Migrated from github.com)

@brunoshine Phantom.js dosen't have an fs module and can't write to or read from disk. It seems like it have, sorry...

@brunoshine ~~Phantom.js dosen't have an `fs` module and can't write to or read from disk.~~ It seems like it have, sorry...
jonbonraki commented 2015-06-18 16:58:49 +00:00 (Migrated from github.com)

i am also having the same has there been a solution on this ?
function read_zip(data, opts) {
var zip, d = data;
var o = opts||{};
if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
switch(o.type) {
case "base64": zip = new jszip(d, { base64:true }); break;
case "binary": case "array": zip = new jszip(d, { base64:false }); break;
case "buffer": zip = new jszip(d); break;
case "file": zip=new jszip(d=_fs.readFileSync(data)); break;
default: throw new Error("Unrecognized type " + o.type);

xlsx.js:11374 Uncaught TypeError: undefined is not a function

i am also having the same has there been a solution on this ? function read_zip(data, opts) { var zip, d = data; var o = opts||{}; if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64"; switch(o.type) { case "base64": zip = new jszip(d, { base64:true }); break; case "binary": case "array": zip = new jszip(d, { base64:false }); break; case "buffer": zip = new jszip(d); break; case "file": zip=new jszip(d=_fs.readFileSync(data)); break; default: throw new Error("Unrecognized type " + o.type); xlsx.js:11374 Uncaught TypeError: undefined is not a function
raiym commented 2015-07-06 12:41:11 +00:00 (Migrated from github.com)

The same thing:
var xlsx = require('./bower_components/js-xlsx/dist/xlsx.core.min.js');
var workbook = xlsx.XLSX.read(bstr, {type:"binary"});
first_sheet_name = workbook.SheetNames[0];
And response is:
TypeError: 'undefined' is not an object (evaluating 'xlsx.XLSX.read')

Is ti works with phantom?

The same thing: <code>var xlsx = require('./bower_components/js-xlsx/dist/xlsx.core.min.js');</code> <code>var workbook = xlsx.XLSX.read(bstr, {type:"binary"});</code> <code>first_sheet_name = workbook.SheetNames[0];</code> And response is: <code>TypeError: 'undefined' is not an object (evaluating 'xlsx.XLSX.read')</code> Is ti works with phantom?
hypogealgaol commented 2016-05-17 07:11:50 +00:00 (Migrated from github.com)

I was having this issue using vanilla JS, I fixed it by making sure I included the scripts in the same order as the example.

    <script src="js-xlsx-master/jszip.js"></script>
    <script src="js-xlsx-master/shim.js"></script>
    <script src="js-xlsx-master/xlsx.js"></script>
    <script src="js-xlsx-master/dist/ods.js"></script>

I was having this issue using vanilla JS, I fixed it by making sure I included the scripts in the same order as the example. ``` <script src="js-xlsx-master/jszip.js"></script> <script src="js-xlsx-master/shim.js"></script> <script src="js-xlsx-master/xlsx.js"></script> <script src="js-xlsx-master/dist/ods.js"></script> ```
binhnq94 commented 2016-09-25 21:24:56 +00:00 (Migrated from github.com)

How fix it on react-native context ?

How fix it on `react-native` context ?
SheetJSDev commented 2017-03-28 04:40:15 +00:00 (Migrated from github.com)

We are including a phantomjs sample based on @machinewu initial code in the next commit, as this appears to work in 2.1.1. Please test and let us know if you have any other issues.

@TechBK please raise a new issue if you are talking about something other than phantomjs

We are including a [phantomjs sample](https://github.com/SheetJS/js-xlsx/tree/master/demos/phantomjs) based on @machinewu initial code in the next commit, as this appears to work in `2.1.1`. Please test and let us know if you have any other issues. @TechBK please raise a new issue if you are talking about something other than `phantomjs`
Sign in to join this conversation.
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: sheetjs/sheetjs#184
No description provided.