SyntaxError after update to Meteor 1.8


#1

Hi folks,
I started this week to upgrade my web-app from 1.7.0.5 to 1.8 and now I have big trouble with a “SyntaxError”.
What I did before:

meteor update --release=1.8
meteor npm install @babel/runtime@latest --save

Checked: @babel/runtime is now included with 7.1.2.

Then I cleaned up and installed:

find . -name "node_modules" -type d -exec rm -rvf '{}' +
rm -rfv .meteor/local
meteor npm prune && meteor npm i && meteor run
meteor reset

At first start, the SyntaxError (you will read below) occurred and I thought about to divide ‘n’ conquer the problem:
Just to have a tiny test of all meteor and 3rd party stuff, I commented all of my proprietary modules, started the web-app and it now error, setup/environment/meteor-dependencies seems good. Ok, then commenting one after another meteor-package in, the SyntaxError rises up again.

When I now start my app, I get the following log-messages in the console:

I20181017-17:56:14.362(2)? info:    Initialized logger:
I20181017-17:56:14.363(2)?         <here is some winston-logging bla bla from a Meteor.isServer instruction in the core-app; so some parts seem to be running>
I20181017-17:56:14.363(2)?     
W20181017-17:56:14.460(2)? (STDERR) /home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/packages/myproject_myproject-activity.js:617
W20181017-17:56:14.460(2)? (STDERR) import {MyCollections} from "meteor/myproject:myproject-shared";
W20181017-17:56:14.461(2)? (STDERR) ^^^^^^
W20181017-17:56:14.461(2)? (STDERR) 
W20181017-17:56:14.461(2)? (STDERR) SyntaxError: Unexpected token import
W20181017-17:56:14.461(2)? (STDERR)     at createScript (vm.js:80:10)
W20181017-17:56:14.461(2)? (STDERR)     at Object.runInThisContext (vm.js:139:10)
W20181017-17:56:14.461(2)? (STDERR)     at /home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/boot.js:393:30
W20181017-17:56:14.461(2)? (STDERR)     at Array.forEach (<anonymous>)
W20181017-17:56:14.461(2)? (STDERR)     at /home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/boot.js:220:19
W20181017-17:56:14.461(2)? (STDERR)     at /home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/boot.js:471:5
W20181017-17:56:14.462(2)? (STDERR)     at Function.run (/home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/profile.js:510:12)
W20181017-17:56:14.462(2)? (STDERR)     at /home/myuser/workspaces/meteor/myproject/myproject-core/.meteor/local/build/programs/server/boot.js:470:11
=> Exited with code: 1
=> Your application is crashing. Waiting for file change.

In this project the most stuff is in ~40 packages and the main-app is almost empty. Here are the npm-dependencies of the package.json of the core-app:

"dependencies": {
  "@babel/runtime": "^7.1.2",
  "bcrypt": "^3.0.1",
  "simpl-schema": "^1.5.3",
  "winston": "^2.4.4",
  <spared out some client-libs>
},
"devDependencies": {
  "chai": "4.1.2"
},

Here I already excluded all of my ~20 eslint-packages, which grabbed old versions on babel and so I only see the current and non-beta version of babel in package-lock.json

I double checked the correctness of all packages:

  • api.versionsFrom(“1.8”); // yes, all packages use this
  • “ecmascript” // yes, without version, all packages use this

myproject-shared has all my mongo-collections (in MyCollections). The package.js has these parts:

Npm.depends({
    moment: "2.22.2",
});
Package.onUse((api) => {
    api.versionsFrom("1.8");
    api.use([
        "clinical:winston-browser-logging@0.2.3",
        "ecmascript",
        "erasaur:meteor-lodash@4.0.0",
        "infinitedg:winston@0.7.3",
        "iron:router@1.1.2",
    ]);
    api.mainModule("myproject-shared.js", ["client", "server"]);
});

myproject-activity is also a very tiny package. In the above error it shows that it imports MyCollections (what is correct).

Package.onUse((api) => {
    api.versionsFrom("1.8");
    api.use([
        "ecmascript",
        "erasaur:meteor-lodash@4.0.0",
        "myproject:myproject-basic-schema@0.0.1",
        "myproject:myproject-shared@0.0.1",
        "myproject:myproject-user@0.0.1",
        "myproject:tabular@2.2.3",
    ], ["client", "server"]);
    api.use([
        "blaze-html-templates", // meta-package with blaze, spacebars, templating, ...
        "myproject:myproject-styles@0.0.1",
        "iron:router@1.1.2",
        "jquery",
        "less",
        "reactive-var",
    ], 'client');
    api.mainModule('client.js', 'client');
    api.mainModule('server.js', 'server');
});

Currently I can reproduce the problem by including/excluding exactly one of all meteor-packages (named here “myproject:myproject-activity”): when I include it, I get the “SyntaxError” occures. If I exclude it, the server starts clearly.
I reduced this package, so no npm-dependencies and only meteor-packages loaded, which are already loaded as dependencies of other packages (checked in the profiling, see below).

I compared now the two starts with this package and without with that command:
METEOR_PROFILE=0 METEOR_LOG=debug MONGO_URL=mongodb://localhost:27017/myproject meteor run --settings ./settings-local.json --verbose
To compare it easily, I piped the two starts (with and without the package) into two files (removed the line endings with the x ms start duration) and got two very similar logs, showing some loading of my packages in a different order. But the order / loading of ecmascript or other ES2015 related packges is similiar.

meteor list --tree shows two completely equal trees, only difference is this additional block:

myproject:myproject-activity@0.0.1
├── blaze-html-templates@1.1.2 (top level)
├── myproject:myproject-basic-schema@0.0.1 (top level)
├── myproject:myproject-shared@0.0.1 (top level)
├── myproject:myproject-styles@0.0.1 (top level)
├── myproject:myproject-user@0.0.1 (top level)
├── ecmascript@0.12.1 (top level)
├── erasaur:meteor-lodash@4.0.0
├── iron:router@1.1.2 (top level)
└── reactive-var@1.0.11 (top level)

I also dropped my .meteor/versions file, as this helped me already many times in the past on meteor update problems, but without any luck.

Any help appreciated, currently I am stuck. Thx in advance.


#2

sorry for bumping, but I am completely out of any ideas. Please let me know, what I could try next or which information I could provide additionally.


#3

This looks to me like your package isn’t getting transpiled properly… I would check your packages to make sure they all depend on the ecmascript package, especially ‘meteor/myproject:myproject-shared’.


#4

hi copleykj and thx for your reply. As written above, I checked many times, that all packages (especially the 2 from the stacktrace) to have this properties:

  • ecmascript package
  • … on server and client block
  • apiVersions set to 1.8

And I also see the _ensurePackageLoaded(myproject:myproject-shared) and _ensurePackageLoaded(ecmascript) lines when profiling.

This was also my first guess, so I had an eye for ecmascript, es5-shim meteor-packages and the babel npm-packages. But that looks fine, also compared to freshly created meteor project with version 1.8.
I am still stuck… Any idea how to get more information, besides profiling?


#5

So, this error:

looks like it’s coming from the code which pulls in an NPM package via the Npm.depends() mechanism in some package.js file.

Perhaps go back to your testing where you add in packages one-by-one and when you get the error, check if there’s an NPM package being used.


#6

Ooh that npm package idea might make sense, since automatic compilation of node_modules was turned off.

Any native module code in there will throw


#7

hm, does it mean, we can not use anymore “require” in the code? In this project we try to re-use our npm dependencies in all packages like this:

import {checkNpmVersions} from 'meteor/tmeasday:check-npm-versions';

checkNpmVersions({
    moment: '2.22.2',
}, 'myproject:myproject-shared');
const moment = require('moment');

The idea came up from aldeed:collection2, where he also makes use of checkNpmVersions, to import his npm-module “simpl-schema”. And we use “require” for this, as this is the first recommendation at https://github.com/tmeasday/check-npm-versions .

Of course we also use many Npm.dependes instructions, but without those the application will also just crash. That would mean, I need to now create a minimal project from scratch to test those mechanisms…


#8

AFAIK require is still allowed.


#9

It means that I suspect one of the npm packages has native ES Module code, instead of ES5 compatible javascript.
Meteor used to automatically compile every package in node_modules, but since most apps now rely on more and more modules, that was taking a long time to do, and almost all modules on npm publish code that works natively on node and in the browser.
For the few packages that don’t, this change means these packages that magically worked before, now don’t.

There is a method to manually opt into compilation of individual modules if this is the cause of your problem (symbolically linking the folder into your imports directory so the build tool queues it for compilation)

Which Npm packages does myproject-shared import?
It’s worth checking if any of them use native ES modules, causing this problem


#10

Hi,
thank you all for your replies, it took some days but finally I nailed it! I wanted to provide a tiny example app with it, but currently I just realized that I didn’t have the time to do so and at least I could describe what the root-cause was.

In our meteor-package “myproject:myproject-activity” it was an illegal import, that is not recognized by the meteor-checks on startup.

In most packages we got the structure of these root-folders:

/both
/client
/server

In “/both” was a line, referencing an exported function in file in “/client”. In detail: a tabular-table definition was in “/both”, and a callback of it was calling a client-method. So this was failing in the server, and had this misleading “SyntaxError: Unexpected token import” message.

As this is something that could be checked on meteor-startup, that the imported file is not available in that environment (server-side) it would be perfect to have an appropriate error in the console.
Hopefully this could be implemented, as this is very hard to identify, with a misleading error message. Thanks everybody for reading.