Closed chmln closed 7 years ago
Thanks.
It's hard to guess what's going wrong here and where (babel? uglify? webpack?). math.js itself is built using WebPack and Uglify too. The code is regular ES5, so no babel needed. To see whether it's caused somehow by Babel you could maybe configure Babe not ignore all math.js code?
I've tried tweaking babel, disabling uglify and source maps, but I couldn't get the node module import to work in any case.
However, including the math.min.js file instead works perfectly fine.
Suspecting it is rather an issue with uglify and/or webpack than the library itself. In case I find a culprit I'll report back here for sure.
Hm, that's not really satisfactory. Great that you found a solution but I'm still curious what's causing this - others may encounter similar issues.
I stumbled upon this as well and after quite a bit of digging I think I found the root of the problem. The error is caused by typed-function when a it tries to use a signature function's name as the typed function's name.
In my case the bug was actually caused by Chrome (51.0.2693.2 dev-m) when trying to create the middle helper function inside lib/function/statistics/median.js:
var middle = typed({
'number | BigNumber | Unit': function (value) {
return value;
}
});
Because the function is anonymous and bound to an object, Chrome decided to use it's object key for the function name, which works fine when setting it as a property on the function but causes issues when typed-function tries to use it to evaluate a new function.
var factory = (new Function(refs.name, 'createError', body));
var fn = factory(refs, createError);
This problem can be avoided by explicitly naming anonymous functions but that's really nothing more then a workaround at this point, since the problem lies in another package.
typed-functions will probably need a patch to handle cases where a browser, a transpiler or a minifier use invalid function names. I guess I could make a PR and propose a fix.
In the meanwhile one solution is to run a script that adds proper names to those functions. Babel with the ES2015 preset does that, but minifying will undo the process.
Wow, you're right, Chrome 51 actually changes the name of an anonymous function to its object key.
It's indeed not safe to rely on the name
property of functions, since names can change when minifying code, or like Chrome 51 does for unnamed functions in objects. I've changed typed-function
such that it only uses the name
property of other typed-functions, not of regular JavaScript functions. That should solve the issue. I've updated in the develop branch, it would be great if you could give it a try (don't forget to run npm update
).
It worked perfectly. I made sure the published version still threw the exception first, just in case the latest Chrome (dev) update changed anything. And after switching to the develop branch everything seems to work as expected. Hopefully this also fixes any similar issues. Good job :+1:
great to hear, thanks for the quick feedback.
Hey @josdejong any update on this? Does the dev branch work? I still have the same error. Thanks.
As far as I know this issue was fixed in v3.2.0. Apparently not? How to reproduce your issue?
@josdejong can confirm working since v3.2 w/ webpack @richburdon try reinstalling? webpack config might also help investigate the issue
@chmin thanks -- reinstalling worked.
But leads to a different problem -- I have the following in my webpack.config.js (which is necessary to have JS classes that use ES6 classes transpiled to ES5 for PhantomJS testing).
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
compact: false
}
},
But this causes:
Module build failed: Error: Couldn't find preset "es2015" relative to directory "node_modules/mathjs"
babel-preset-es2015 is installed (and has been working with many libs and JS files up until this point).
Sorry if it's unrelated, but I haven't figured it out yet.
Good to hear the original issue is indeed solved.
I think this is a generic babel related thing. mathjs doesn't use babel but apparently babel tries to find configuration/presets for itself in the folder of mathjs. Maybe you can exclude mathjs from being transpiled by babel?
@richburdon its a good idea to exclude node modules from babel transpiling. You could also use the include option to only search for js files in specific directories.
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015'],
compact: false
},
exclude: /node_modules/
},
I am seeing this error again with mathjs 3.13.1 and Chrome 58.0 in TypeScript. I'm using @angular/cli
to build.
Whenever I call math.parse()
, I get a TypeError
on the snippet referenced above:
var factory = (new Function(refs.name, 'createError', body));
var fn = factory(refs, createError);
Uncaught TypeError: factory is not a function
at _typed (typed-function.js:1116)
at typed (eval at _typed (typed-function.js:1115), <anonymous>:15:16)
at Object.factory (matrix.js:36)
at load (core.js:106)
at Object.factory (subtract.js:8)
at load (core.js:106)
at Object.factory (Unit.js:9)
at load (core.js:103)
at Object.factory (SymbolNode.js:12)
at load (core.js:103)
I'm getting math.js into TypeScript with import * as math from 'mathjs';
Thanks for reporting
what is the easiest way to reproduce this issue? Is it something related to just TypeScript? (running math.js in Chrome 58 still works as far as I can see)
I'll try to set up a demo repository tomorrow. I'm not exactly sure where this is happening, but it does seem related to either the TypeScript transpilation or angular>=2.
I'm migrating an angular 1 app with webpack to an angular 4 app with webpack.
In the previous app, math.js
worked just fine.
awesome, thanks. Would be great if you could do some pinpointing already.
Just to be sure: what was is the last version of mathjs that still works then?
Both the angular 1 and angular 4 apps are running on 3.13.1
Yes but I mean mathjs 3.13.1 gives this problem, but 3.13.0 not? Or is it for all (recent) versions of mathjs and has purely to do with upgrading to angular 4?
I've prepared two repositories for easier reproduction:
It turns out that in this very limited demo, mathjs actually works fine. I'm going to dig a bit deeper to see if I can find why it doesn't work in my actual application.
Thanks for the update, hope you will find the cause!
Finally figured it out! The error only occurs if you're debugging the application in the Chrome DevTools.
In the new angular
4 application, I was testing if mathjs
was working without fully implementing it, getting the error.
In the demo, I just implemented it fully without debugging.
Now, I can reproduce in both angularjs and angular (TypeScript).
I've updated both repositories. If you open:
With devtools open, you'll get to a breakpoint with a comment that includes some code to execute. Executing this code in the debugging context will result in the error similar to the one that I described above.
Thanks for working out these demos!
I've opened them in Chrome (Version 58.0.3029.110 (64-bit)), with dev tools open. Then it steps though three break points but in both cases the application runs fine and shows 2 + 2 = 4
in the end. You're running Chrome 58 too right? Is there anything else I have to do in the dev tools to get the error triggered?
Sorry if it wasn't clear - if you run the code in the comment after each of the breakpoints in the devtools console you'll get the error.
The applications indeed run fine but invoking mathjs from the debugger/console in devtools throws an error.
Ah, Thanks. I can reproduce this issue now. I've narrowed it quite a bit: it has not to do with angular, typescript or math.js, you can reproduce this issue in Chrome 58 with just one line of plain JavaScript:
http://jsbin.com/raluwu/edit?html,output
<!DOCTYPE html>
<html>
<head>
<title>math.js | issue #601</title>
</head>
<body>
<script>
// open the developer console in Chrome 58,
// and run this code until the debug point
debugger;
// when at the debug point, enter the following in the console:
//
// var f = new Function ('a', 'return a + a');
// // f should be a function but is undefined when in debug mode
//
// console.log(f(2));
// // should return 4, but throws "Uncaught TypeError: f is not a function"
// without debug point, everything runs fine
var f = new Function ('a', 'return a + a');
console.log(f(2));
</script>
</body>
</html>
This might be a bug in Chrome 58. I've asked on stackoverflow: https://stackoverflow.com/questions/44228320/new-function-returns-undefined-in-chrome-58-when-in-debug-mode
Nice, that's progress! I'll be monitoring the SO thread.
EDIT: Just checked, Firefox does not have this behaviour and works as expected.
I found an existing bug report on this issue: https://bugs.chromium.org/p/chromium/issues/detail?id=705149
I will close this issue now, it's not something I can fix.
Just hit the command:
npm install mathjs
good point @yogeshborad I suppose that this issue is resolved in math.js v4, since there new Function
isn't used anymore?
Yes, sorry for that. This issue is only resolved in math.js v4. Thanks to @josdejong for reminding and correcting to me.
Good to hear, thanks for the confirmation Yogesh.
Hello!
First off, koodos to author for a fantastic library.
I'm having trouble importing mathjs to frontend through webpack.
Whenever I import mathjs, here's what happens:
The module is imported like any other node module.
And here's my webpack config
No problems, however, using mathjs in node backend.