Search code examples
node.jsamcharts

Node.js & amcharts4 - Import error 'Unexpected token export' using TypeSript or ES6


I just downloaded your amCharts4 version into my node.js app via npm to test it. Wenn installed I find the files chore.js and charts.js in MyNodejsApp/node_modules/@amcharts/amcharts4 :

MyNodejsApp
_node_modules
 |_@amcharts
  |_amcharts4
   |_charts.js
   |_core.js
  |_amcharts4-geodata
_public
 |_css
  |_styles.css
 |_js
  |_main.js
_routes
  |_index.js
_views
 |_partials
  |_scripts.ejs
 |_dashboard.ejs
 |_index.ejs     
app.js  

In my routes/index.js I'm integrate the necessary files:

const { am4core } = require("@amcharts/amcharts4/core");
const { am4charts } = require("@amcharts/amcharts4/charts");

/home/MyNodejsApp/node_modules/@amcharts/amcharts4/core.js:8
export { System, system } from "./.internal/core/System";
^^^^^^

SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/MyNodejsApp/routes/index.js:12:21)
[nodemon] app crashed - waiting for file changes before starting... 

What am I missing?

https://www.amcharts.com/docs/v4/getting-started/basics/

Edit: Import gives me also an error

import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";

/home/MyNodejsApp/routes/index.js:12
import * as am4core from "@amcharts/amcharts4/core";
^^^^^^

SyntaxError: Unexpected token import

I'm using node.js v8.12.0


Solution

  • I do not know if there is a way to get amCharts v4 to work for node.js. It is designed for browsers, not node.js.

    In our documentation for using ES6 for the web we mention that bundlers are a hard requirement:

    It is currently impossible to load npm packages directly in the browser. You must use a bundler like Webpack or Rollup. (check our Using Webpack article)

    webpack

    (In case you're interested, I've provided some explanations below for why a bundler is needed.)

    If you follow our guide, you should be able to get your code working for the browser no problem via npm install, or afterwards to build again via npm run prepare. (In package.json you may need to set "webpack-cli" to the latest, e.g. "webpack-cli": "^3.1.2".)

    However, that won't work for node.js, as globals in browsers like window and document do not exist in the node environment.

    The need for a bundler

    1. We use ES6 imports (esm) but in a way only bundlers could interpret.
    2. Even if you tried using <script type="module" src="/js/main.js"></script> and imported from there, it would eventually error out because we're using module specifiers that only bundlers would understand. E.g. paths to files without extensions ("./js/main" instead of "./js/main.js"), or names of a package within node_modules ("@amcharts/amcharts4/core" instead of "./node_modules/@amcharts/amcharts/core.js"), i.e. none are valid URLs that can be fetched.
    3. Speaking of bundlers, even if you used unpkg.com, it would also error out once it encounters our few dynamic imports as it does not support dynamic imports.
    4. Node 8.5.0+ has experimental support for esm. You can read more about that here. But this will not work because it also requires first and foremost, .mjs (otherwise called Michael Jackon Script) extensions! Even if it didn't, or if you renamed all amCharts .js files to .mjs, you would still have to have valid module specifiers. Say you renamed all the things so they were valid, including other npm package dependences, and renamed files to .mjs, it would then defeat the point of having used npm to download and manage the versioning of the amcharts package.

    So yeah, regardless of the environment, a bundler would have to be used.

    In the end I'm afraid it still can't be used in node.js, however. Say once you have a bundler putting all that together for you and it works great in a browser... to run things in node.js you would still need to simulate a browser. There's a library called jsdom which can do that for the most part. There are even several npm packages that provide jsdom in node global scope so variables like window and document are readily available anywhere, any time.

    Unfortunately you will hit a snag when it comes to working with SVGs. amCharts v4 works with SVGs via JavaScript, so support for SVG-related APIs is absolutely necessary. The implementation of SVGSVGElement is virtually non-existent in jsdom (or better yet it's still a WIP).

    We would really need to know more of what you're looking to do, if by node.js app you really mean that, or if this is meant to be browser-facing afterall. If you need amCharts to work in node.js, it may not be for you at this time. Let us know, and we'll do what we can to help.