Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error while using with TypeScript: Error: "Please include the xlsx.js library" #1013

Open
eluleci opened this issue Jun 7, 2018 · 9 comments
Assignees

Comments

@eluleci
Copy link

eluleci commented Jun 7, 2018

I am working on a project which is created with create-react-app which has TypeScript version. You can see from here: https://github.com/Microsoft/TypeScript-React-Starter

The library is added to package json as:
"alasql": "^0.4.5"

The library is imported like:
import * as alasql from 'alasql';

When it is executed like:

const opts = [{ sheetid: fileName, header: true }];
alasql(`SELECT * INTO XLSX("${fileName}.xlsx",?) FROM ?`, [opts, [list]]);

the app crashes and the error message is:
Error: Please include the xlsx.js library

@mathiasrw
Copy link
Member

Does it work if you select into a csv file? "SELECT * INTO CSV"?

The solution is to include the xlsx.js library (as stated in the error message)

Have a look at https://github.com/SheetJS/js-xlsx

@mathiasrw
Copy link
Member

Any news on this?

@eluleci
Copy link
Author

eluleci commented Jul 26, 2018

I tried "SELECT * INTO CSV", it doesn't crash but the generated file is not a valid file.

I checked the code and saw that the XLSX is taken from XLSX = utils.global.XLSX || null; where the global is defined like

utils.global = (function() {
	try {
		return Function('return this')();
	} catch (e) {
		//If Content Security Policy
		var global = self || window || global;

		if (global) {
			return global;
		} else {
			throw new Error('Unable to locate global object');
		}
	}
})();

So I imported xlsx library and put the XLSX into window like (window as any).XLSX = xlsx; but it is still not working. However I can reach to window.XLSX from browser console.

I also tried to add the xlsx into the HTML with script tag <script lang="javascript" src="/xlsx.min.js"/> but the typescript project doesn't compile when there is a javascript file referenced in a script tag.

How should I include the xlsx.js library for alasql.js to see it?

@eluleci
Copy link
Author

eluleci commented Jul 26, 2018

I also tried to see what is in utils.global by logging it like console.log((alasql as any).utils.global) and it seems it is referenced to Window and it has XLSX in it.

@eluleci
Copy link
Author

eluleci commented Jul 26, 2018

It seems like the issue is getXLSX function. utils.isBrowserify is true when importing the package from TypeScript file like import * as alasql from 'alasql';, so it falls into the first condition and never assigns the XLSX. BTW the Window.XLSX exists at that moment. I have no idea why the first condition is empty. You must be knowing the reason better.

var getXLSX = function() {
	var XLSX = null;
	/* If require() shuold be supported else take from global scope */
	if (utils.isNode || utils.isBrowserify || utils.isMeteorServer) {
		/*not-for-browser/*
		XLSX = require('xlsx') || null;
		//*/
	} else {
		XLSX = utils.global.XLSX || null;
	}

	if (null === XLSX) {
		throw new Error('Please include the xlsx.js library');
	}

	return XLSX;
};

So if the function would be like this it would do the same thing for both conditions. (Since the first condition is empty anyway) and it fixes the TypeScript issue.

var getXLSX = function() {
	var XLSX = (utils.global && utils.global.XLSX) ? utils.global.XLSX : null;
	
	if (null === XLSX) {
		throw new Error('Please include the xlsx.js library');
	}
	return XLSX;
};

Would it be OK to change the function like this?

@mathiasrw
Copy link
Member

Thank you so much for your time to look into this.

The /*not-for-browser/* is used to have code that compiles both to a node version and for a browser version. Now, the problem is that typescript is handeling the default - the node version. But actually it should use the browser version. What part of the code is default would not be a large change. Ill look into it next weekend.

@mathiasrw mathiasrw self-assigned this Aug 6, 2018
@eluleci
Copy link
Author

eluleci commented Aug 6, 2018

Awesome. Thanks.

@mathiasrw mathiasrw reopened this Aug 6, 2018
@mathiasrw
Copy link
Member

It was a bit more cryptic than expected.

I added a new function: alasql.setXLSX(...) so you can load XLSX manually and parse it into alasql instead of it trying to load XLSX.

Please try this and let me know if it fixed this.

  • Make sure you are using the latest code from this repo by replacing "alasql": "^0.4.5" with "alaswl": "github:agershun/alasql" in package.json
  • Do a npm install xlsx
  • Include XLSX with a import { XLSX } from 'xlsx'
  • Before using alasql do a alasql.setXLSX(XLSX);
  • See if it works.

@eluleci
Copy link
Author

eluleci commented Aug 14, 2018

I tried it and I got error while calling alasql.setXLSX(XLSX); function because the setXLSX function doesn't exist in alasql.js.

Also I have to import the alasql like const alasql = require('alaswl'); instead of import * as alasql from 'alaswl';. Otherwise the compilation fails with error ... alasql.d.ts is not a module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants