ESLint errors with new 1.5 clean -full boilerplate

I’m a long time Meteor developer, but have always used the pre-1.3 style of code. I’m starting a new very large project and wanted to update my skillset to be post 1.3. As any prudent developer would do before starting a new project, I’m wasting my weekend on tooling instead of starting actual work. Since I have experience as a Meteor dev, and I want new users to have a great first experience, I want to pass along some issues in regards to the guide and the -full boilerplate. I’m actually not sure where a PR would go for the boilerplate, but I’m also new enough of to this that I want someone that knows the post-1.3 style better to make sure that my feedback is accurate. This is my first time to be using imports with Meteor, first time with ESLint, first time with Mocha (and I went ahead and changed to WebStorm as well, because you know, procrastination).

The experience issues I’m addressing are related to someone starting a brand new project with the -full setting with meteor create (which I assume is encouraged) and following the guide to get setup with ESLint.

The guide says to run the following for ESLint:

meteor npm install --save-dev babel-eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-meteor eslint-plugin-react eslint-plugin-jsx-a11y eslint-import-resolver-meteor eslint @meteorjs/eslint-config-meteor

but on my Mac OS X 10.12.5 that does not work to get ESLint working. What I found at https://www.npmjs.com/package/eslint-config-airbnb was that you need to peg particular versions for the dependencies to use the airbnb setup, so I found the following worked correctly with Meteor:

(
  export PKG=eslint-config-airbnb;
  npm info "$PKG@latest" peerDependencies --json | command sed 's/[\{\},]//g ; s/: /@/g' | xargs meteor npm install --save-dev "$PKG@latest" babel-eslint eslint-plugin-meteor @meteorjs/eslint-config-meteor eslint-import-resolver-meteor
)

Without doing that you just get a total mess mostly trying to use the lint. You also have to do the next step in the guide which is edit the package.json, my only comment there is that I think the goal is to append to the scripts section, not replace it. The eslint-plugin-meteor guide says to use .eslintrc, but I assume the guide is more correct on this point. The only other thing I would say is that it would be nice to not require react to be installed with the ESLint, airbnb does provide a base that does not require it but I think eslint-plugin-meteor does require it.

The next set of issues are relating to things in the boilerplate (meteor create --full) that should be fixed so that new users get a clean slate in regards to error messages when they first make a new app:

The following line needs to be moved up one line to clear an error message “Absolute imports should come before relative imports”

#imports/api/links/server/publications.tests.js
import { PublicationCollector } from 'meteor/johanbrook:publication-collector';

The following two lines should be added to the top of the file to resolve the error “‘Template’ is not defined” and “‘ReactiveVar’ is not defined”. I’m a little confused why they still work if those are errors, does Meteor only encourage us to do our imports correctly but is fuzzy enough to work regardless of if we really do them or not?

#imports/ui/components/hello/hello.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

The Template one needs to be added to imports/ui/components/info/info.js as well.

To get rid of the error “Invalid parameter name, use “templateInstance” instead” I changed this section:

#imports/ui/components/hello/hello.js
  'click button'(event, instance) {
    // increment the counter when button is clicked
    instance.counter.set(instance.counter.get() + 1);
  },

to:

  'click button'(event, templateInstance) {
    // increment the counter when button is clicked
    templateInstance.counter.set(templateInstance.counter.get() + 1);
  },

I’m not actually sure if that is an improvement or not, but the code still works and it clears the error.

Another thing that needs attention is to add the following:

/* eslint-env mocha */

to the top line of every one of the mocha tests so the linter is aware of things like describe and it and beforeEach.

There were three things that I wasn’t able to resolve, but I am curious if someone else can resolve them, or if they are false error messages that should be ignored:

imports/api/links/links.js - Prefer default export:

export const Links = new Mongo.Collection('links');

I can clear the error message by following some alternative ways to export that I found here https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md but when I do that the collection no longer works, and I’m new to exports and don’t fully understand the differences.

The next one I can’t figure out is in all the test.js files I get an error message of “Unable to resolve path to module ‘meteor/practicalmeteor:chai’” and I don’t know why. The package is installed and it does work.

Finally in imports/api/links/links.tests.js I get an error message of “Unexpected dangling _ in _getCollectionName” but this one confuses me because I don’t see a defined function called _getCollectionName anywhere in the codebase. It clearly is running correctly, because I can alter what it is looking for and it will fail in Mocha. I found one forum post where someone is looking for that type of functionality, and I found one package that has a function called that but it isn’t installed in the boilerplate.

Ultimately I think it is worth cleaning this up so that new users get a nice clean slate when they start developing an app and we give them the best boilerplate we can and they don’t get disheartened. I think it should be a standard practice to create a new boilerplate app for all of the examples and test to make sure that Mocha works, ESLint is clean, and also that ios and Android still works.

A lot of the problems you’re running into have to do with tools like eslint not being aware of the Meteor way of doing things.

For things like Meteor globals you can add { env: { meteor: true } } to your eslintrc file. This will help eslint understand that these globals exist.

But I personally prefer to just import those from the correct spot (you can find the import lines by consulting the Meteor or Blaze docs)

PS practicalmeteor:chai can probably be safely replaced with the plain chai npm and that should solve that issue. The core problem again is that eslint doesn’t know how meteor organizes packages by default. What plugin are you using to verify imports?