question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't use mathjs without package bundler

See original GitHub issue

The problem

I’m trying to use mathjs inside node, using ES modules, but without a package bundler (e.g. Webpack, Rollup).

When I do:

import { evaluate } from 'mathjs';

console.log(evaluate('1+2'));

It throws:

import { evaluate } from 'mathjs';
         ^^^^^^^^
SyntaxError: The requested module 'mathjs' is expected to be of type CommonJS, which does not support named exports. CommonJS modules can be imported by importing the default export.
For example:
import pkg from 'mathjs';
const { evaluate } = pkg;

From what I can see, the module entry in package.json is only used for package bundlers. Without bundlers, node will look at the main entry, so it tries to load the CommonJS / UMD script.

Node does support mixing ES and CommonJS modules, but expects a single, default export. Changing the import to this works, because it correctly loads the CommonJS module:

import mathjs from 'mathjs';

console.log(mathjs.evaluate('1+2'));

So that’s a kind of workaround, but it does mean that it’s not using ES modules in an ES module project.

But the bigger issue is that it’s now incompatible if I choose to use to use a bundler because the bundler will use the ES module version, which has no default import. In particular, this causes my Jest tests to fail. In my test I have something like:

TypeError: Cannot read property ‘evaluate’ of undefined

I think that conditional exports may be a solution. It seems to allow you to tell node which files to use for CommonJS require and which to use for ES import.

Potential solution

I’ve not had a proper play with it, this seemed to work for me:

Change the package.json to this, to tell node to use the esm files for import statements, and es5 files for require:

{
  "main": "./main/es5",
  "module": "./main/esm",
  "exports": {
    "import": "./main/esm/index.js",
    "require": "./main/es5/index.js"
  },
  // this is required, otherwise the `exports` doesn't work
  "type": "module"
}

But because the type is now module, node will now complain when trying to use CommonJS. To sort that, you can either rename all of the CommonJS files to have the .cjs extension, or to add a package.json in the root directories containing the CommonJS files (e.g. main/es5/, lib/), with just the following:

{
  "type": "commonjs"
}

I’m not sure if doing this has any adverse affects on other parts of the library though, but I’m happy to get a PR in for those changes.

I thought it seemed similar to #1766. Not quite the same issue, but possibly the same resolution, perhaps used with Subpath Exports.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:1
  • Comments:13 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
m93acommented, Jul 1, 2021

Was this fixed by #1941, or is it still an issue?

1reaction
GreenImpcommented, Aug 11, 2020

Also, feel free to be ruthless with your review. I’m happy to change things, or scrap it, if it’s not what you’re after.

Read more comments on GitHub >

github_iconTop Results From Across the Web

This getting started describes how to install, load, and use ...
Math.js can be installed using various package managers like npm, or by just downloading the library from the website: https://mathjs.org/download.html.
Read more >
mathjs
Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic ...
Read more >
Properly including math.js library in a .js file
Why can't you just use webpack to bundle all your javascript code and include single JS file in your index.html ?
Read more >
Code-Splitting
Most React apps will have their files “bundled” using tools like Webpack, ... math.js export function add(a, b) { return a + b;...
Read more >
Cannot be displayed using "mathjs"
maybe cannot load webpack but I don't have no idea. ... at Object.i [as injectJsCode] (customVisualsHost.bundle.min.js:23)
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found