Prashanth Chandra
Prashanth Chandra

Reputation: 2692

SyntaxError when importing ES6 npm module in Meteor

  1. I created a new meteor project using meteor create
  2. I ran npm install -S spacy-nlp, which contains some ES6 code
  3. In my server/main.js, I wrote import spacy from 'spacy-nlp'
  4. Upon running meteor, it complained Error: The babel-runtime npm package could not be found in your node_modules. Please run the following command to install it: meteor npm install --save babel-runtime
  5. I installed babel-runtime
  6. Then it complains

    W20161120-16:40:30.175(8)? (STDERR) /Users/prashanthcr/code/es6-meteor-test/node_modules/spacy-nlp/src/start-io.js:3
    W20161120-16:40:30.176(8)? (STDERR) const { spawn } = require('child_process')
    W20161120-16:40:30.176(8)? (STDERR)       ^
    W20161120-16:40:30.177(8)? (STDERR)
    W20161120-16:40:30.178(8)? (STDERR) SyntaxError: Unexpected token {
    

Not sure where to go from there. Why can't I import an npm package that uses ES6?

I have Node.js 7.1.0 installed globally and I'm using Meteor 1.4.2.3.

Upvotes: 1

Views: 563

Answers (3)

thoni56
thoni56

Reputation: 3335

Meteor refuses to do anything with what's in node_modules, the thinking being that those packages should already be ready for distribution.

But more and more npm packages are not transpiling from ES6 before packaging so Meteor have been forced to look into this.

For packages that you don't need to modify the solution is easy (once you know it):

Make a symbolic link from node_modules/<package> to somewhere in your app (import maybe). No Meteor thinks that this is code in your application and does whatever is needed with it.

Upvotes: 0

MasterAM
MasterAM

Reputation: 16488

Meteor does not compile any files in node_modules to ES5. This means that the code is run unchanged. That is the reason you are getting the error at runtime and not during the build process.

Meteor v1.4.2.x uses node v4.6.2 (you can check the node version using meteor node --version).

This version of node does not normally support destructuring assignment (the const {foo} = ... syntax). This requires using the --harmony_destructuring flag. You can easily test this by running a node shell (REPL) with version 4.x vs 6.x.

Typing the following in 3 terminal sessions:

  • $ meteor node
  • $ meteor node --harmony_destructuring
  • $ node, when node is in v6+

Code:

let bar = () => ({foo: 3}); // 1
let { foo } = bar(); // 2
eval("let { foo } = bar();"); // 3
  • Statement 1 will run fine.
  • Statement 2 will not be recognized by node v4 (expect more user input) and will be evaluated as expected by node v6 and v4 with the flag.
  • Statement 3 forces node to evaluate the expression as a unit without expecting further input by the user, so it will cause node v4 to throw the error you are seeing and will be evaluated properly by node v6 and v4 w/flag.

This means that the error you are facing is a node issue and you need to either:

  • find a way to get Meteor to run node with the --harmony_destructuring flag.
  • fork the packages and change the problematic expressions.
  • fork and add a build configuration to the packages (e.g, a pre-publish step).
  • wait for Meteor to start using Node v6 (should happen soon, as it is now the stable LTS version).

Upvotes: 1

Mikkel
Mikkel

Reputation: 7777

There is a story about babel-runtime here, which all seems a little confusing to me, but I think the solution is to do

meteor npm install --save babel-runtime

https://forums.meteor.com/t/meteor-1-4-2-1-is-an-important-patch-for-1-4-2-users/31190

Upvotes: 0

Related Questions