VS Code + Meteor and help in migrating away from globals


#1

I would like to configure my VS Code to work with Meteor the best it can.

Currently I’m in the process of migrating away from globals, which means… adding a ton of import statements!

I could use all the help available from tooling, so, what works with and understands Meteor packages? Any other valuable VS Code extensions that help automate the process of adding missing imports?

:pray:


#2

The tool import-js does a pretty good job of automatically adding import statements and It understands Meteor projects.

There’s a VS Code extension and can be used from the command line

It can be a bit flaky sometimes, but it’s a good starting point


#3

Thanks, I’ll give it a try!


#4

These will make your life easier:


#5

Thanks! At some point I had whole bunch of imports / intellisense -related extensions installed and I started to have a hard time understanding which suggestions were coming from where…

…but I’ll try these too!


#6

Yeah I’ve done the same thing. Delete them all and just install these.


#7

Hey thanks, that’s actually quite cool. It could use a bit more work but I have a project I want to upgrade from Meteor “Classic” to ES6 style and I think this tool will help speed that up a lot. Out of interest, what does your .importjs.js look like ? What worked best for me was this :

module.exports = {
    namedExports: {
        "meteor/meteor": [
          'Meteor'
        ],
        'meteor/mongo': [
          'Mongo'
        ],
        "meteor/check": [
            'Match', 'check'
        ],
        "meteor/aldeed:simple-schema": [
            "SimpleSchema"
        ],
        'meteor/ddp': [
            'DDP'
        ],
        'meteor/templating': [
            'Template'
        ],
        "meteor/tmeasday:publish-counts": [
            "Counts"
        ],
        "meteor/mdg:validated-method": [
            "ValidatedMethod"
        ],
        "meteor/kadira:flow-router": [
            "FlowRouter"
        ],
        "meteor/random": [
            "Random"
        ],
        "meteor/http": [
            "HTTP"
        ],
        "meteor/oauth-encryption": [
            "OAuthEncryption"
        ],
        "meteor/accounts-base": [
            "Accounts"
        ],
        "meteor/promise": [
            "Promise"
        ],
        "meteor/ejson": [
            "EJSON"
        ],
        "meteor/edgee:slingshot": [
            "Slingshot"
        ],
        "meteor/kadira:blaze-layout": [
            "BlazeLayout"
        ],
        "meteor/spacebars": [
            "Spacebars"
        ],
        "meteor/jquery": [
            "$"
        ],
        "meteor/percolate:migrations": [
            "Migrations"
        ],
        "meteor/webapp": [
            "WebApp", "WebAppInternals"
        ],
        "meteor/reactive-dict": [
            "ReactiveDict"
        ],
        "meteor/reactive-var": [
            "ReactiveVar"
        ],
        "meteor/tracker": [
            "Tracker"
        ],
        "meteor/blaze": [
            "Blaze"
        ],
        "meteor/aldeed:autoform": [
            "AutoForm"
        ]
    },
    danglingCommas: false,
    maxLineLength: 100
}

I couldn’t see how to get it to find lodash and some other npm modules but 90% of our imports are our own code and meteor modules so this will help a lot.

Not too important but I also couldn’t see a way to remove the space before and after { nor change from single quotes to double, but ESLint fixes that straight after the Fix Imports has run.


#8

Mine looks like this:

const globals = require('globals');

module.exports = {
    declarationKeyword: 'import',
    environments: ['meteor', 'node'],
    excludes: ['.meteor/local/**', '.vscode/**'],
    mergableOptions: {
        globals: false,
    },
    globals: [
        ...Object.keys(globals.builtin),
        ...Object.keys(globals.node),
        'Package',
        'Npm',
    ],
    namedExports: {
        'meteor/underscore': ['_'],
        'meteor/jquery': ['$'],
    },
    useRelativePaths: false,
};

By setting the environment to Meteor, you can remove most of those namedExports and by re-writing the globals (by telling importjs not to merge globals, and providing a new set), it will start generating imports for Meteor’s globals as well


#9

Did you manage to get auto imports working with local Meteor packages?

My workspace has three different Meteor apps, and alongside them I have a meteor-packages folder. Packages are then symlinked to the app’s packages directories as needed.

I can’t get importjs (or any other tool for that matter) to acknowledge that I have a bunch of local Meteor packages in the workspace.

Edit: folder structure:

- meteor-packages/
  - my-awesome-pkg/
  - another-meteor-package/
- app1/
  - packages/
    - @link ../../meteor-packages/my-awesome-pkg/
- app2/
  - packages/
- app3/
  - packages/

#10

Thanks for sharing that. As far as I can tell, if I use just the environment [‘meteor’] and your globals & mergableOptions I get most of what I had manually defined with the slight downside of it importing underscore from meteor. It has another minor downside in that it takes 3 runs and puts moment in as

import moment from '/moment' 

which ESLint won’t fix.
Is that your experience too ?

Have you had any joy getting it to import npm modules ? Not sure why it finds moment but then never finds lodash and a host of other modules. It also prompts me to select a location with moment (as fullcalendar also imports it). Would be nice if it could pick automatically somehow.


#11

Actually, import-js seems to be doing nothing.

Typing Meteor in a JavaScript file gives me zero recommendations in VS Code.

I have installed the ImportJS-extension and import-js globally from npm :man_shrugging:


#12

import-js doesn’t add intellisense. It simply adds the Fix Imports, Import word under cursor & Goto module commands. Making it useful for refactors rather than daily use (at least for me).

Vscode should allow you to import individual ones though, after you’ve typed Meteor it should give you some options, one of which is import

Have you Javscript > Suggest: Auto Imports switched on @arggh ?


#13

I tried these too, but it just said No JS Module to import for 'Meteor' in the status bar.

However, I then had a break, enjoyed a cup of sencha tea, played with my kiddo, ate a bunch of chocolate and came back to my laptop and… now it works! :hugs:


#14

Apparently import-js gets very baffled if the file at hand has any require()s at the top.

I was just trying it out on the first file I opened by chance.


#15

Now I wish it was just smart enough to use the file-system styled imports from Meteor packages, like so:

import { MyThingie } from 'meteor/arggh:thingies/myThingie';

Also, the .importjs.js apparently must reside in the Meteor app’s root, not the workspace root, for package imports to work. So in my app structure (shown in posts above), I have to add .importjs.js file to each app individually.

Maybe I should create issues for these questions/remarks in the ImportJS repo, if it happens to be alive/active.


#16

You should be able to get that MyThingie to work if you create a namedExport entry but you’d have to do it for every one of your meteor packages.

I’m just using it as a refactor tool myself - and I’m hoping VSCode will soon extend the built in import suggestion to support an ‘import all’.


#17

Thanks for reminding me about this feature :+1:

…Do you have any tips how to ease the importing of Blaze templates included in the current template? Probably impossible? :fearful:

// Talking about these
import '../components/icon_thumbup';
import '../components/icon_close';
import '../components/text_input';
import '../components/segment';
import '../components/section_title';
...

Template.signup.onCreated(...
<template name="signup">
   <div>
     {{#section_title}}Signup{{/section_title}}
     {{> text_input type="email" }}
   </div>
   ...
</template>

#18

I know local packages without symlinks work. Never tried with a symlinked directory,


Yeah I don’t know why it does this either, but can be fixed with an importStatementFormatter in the config: (I have a complicated one I didn’t post for… reasons)

    importStatementFormatter({ importStatement }) {
        return importStatement.replace(/(import|from)\s('|")\//, '$1 $2');
    },

Which will remove the initial /, but this will cause issues for absolute imports in Meteor, so you either need to use a babel plugin or set useRelativePaths: true


import-js relies pretty heavily on caching, so sometimes it does this :cry:


The maintainer doesn’t use Meteor so any bugs there will need to be fixed by the Meteor community. It’s a pretty clean codebase with good comments, flow types and decent tests though. It’s pretty pleasant to work with


All of these reasons are why I described it as a bit flaky haha


#19

This has been an absolute gem, thank you so much for the recommendation (and your work on the lib itself!)


#20

Yeah, I had to tweak it while converting a 300 file, 50k LOC Meteor project with 18 local packages from globals to import syntax. At that scale it was worth it to contribute haha

After I’d fixed the general errors, I ran the CLI over all the files and then worked through the resulting import errors one by one