[Solved] Absolute path within meteor packages

We’re experimenting with package based architecture and we’d like to use absolute paths within a meteor package. Is it possible to use absolute import path within the package instead of relative paths? if so, what is the syntax?

Hello, do you want to use something like ‘/imports/ui/PeopleList’, right?

You can add this Babel plugin:

meteor npm install --save-dev babel-plugin-module-resolver

And add this to your .babelrc file (or create .babelrc file if you are not using one):

{
  "plugins": [
    [
      "module-resolver",
      {
        "root": [
          "./"
        ]
      }
    ]
  ]
}

That works for you?

Thanks @filipenevola , I’ll give this approach a try.

Specifically, this is inside a meteor package when a file needs to reference another file. In a meteor project I can do /imports/ui/PeopleList but inside a package we need something like ../../PeopleList which is not very readable if we have deep nesting.

So I’m not sure what is the root path within the package and how to use absolute paths.

I never tried that approach inside a package but I think it can work if Meteor consider .babelrc there, give me feedback on your attempt :wink:

1 Like

I’d strongly advise against using a babel plugin like babel-plugin-module-resolver.
Meteor already does absolute url imports from your project root, and babel plugins (especially ones that duplicate existing Meteor behaviour) are an endless source of bugs.

For importing from another Meteor package, you can refer to the package by name, prefixed with meteor/ like so:

import { someModule } from 'meteor/myNamespace:myPackage';

For this to work, the named export someModule must be exported by the entry point, and that entry point set by using api.mainModule in Package.js.

You also need to add the package you are importing from as a dependency.

If you want to pick out an individual module you can also import from deeper within the folder structure like so:

import { someOtherModule } from 'meteor/myNamespace:myPackage/client/modules/someOtherModule';

More info in docs:


and
https://guide.meteor.com/writing-atmosphere-packages.html

Thanks @coagmano!

I’m already able to import from a project using absolute path (alhough I didn’t know you can actually cherrypick a module), but I’m wondering if there is away to do absolute imports within the package, that is importing one file to another within the package itself.

Ahh I misunderstood.

I just checked a couple of things and here’s what I found:

  • An absolute import in a package still goes to the project root.

  • importing using the package name from inside that package works:
    import { someOtherModule } from 'meteor/myNamespace:myPackage
    (with the caveat that it can’t be done from the file that exports that module)

  • Cherry picking from the same package always works:
    import { someOtherModule } from 'meteor/myNamespace:myPackage/client/modules/someOtherModule';

It’s pretty cool that self-dependency is totally allowed without issue

2 Likes

This is working! thank you so much for looking into it :smiley:

It’s a bit long though, we’ve to add this meteor/myNamespace:myPackage to define the root, perhaps relative paths are more desirable when we’ve little nesting within the package.

2 Likes

I need that for WebStorm autocomplete to work properly because WebStorm doesn’t know the Meteor internal setups.

1 Like

I somehow can’t seem to get this to work. I have a package called lesswrong, which isn’t published on Atmosphere but is just a local package. When I use import { Comments } from 'meteor/lesswrong' within that package it says "Cannot find package “lesswrong”. Try “meteor add lesswrong”. meteor add lesswrong obviously doesn’t work, because I already added the package.

The same happens when I do import { Comments } from 'meteor/lesswrong/lib/collection'. Not fully sure what else to try, or whether this feature broke in the last few months. Or maybe my package has to be published on atmosphere and I need to have a private namespace?

It definitely doesn’t need to be published to atmosphere, I’m currently using 10+ separate local packages that aren’t on atmosphere, several of which contain self-references.

Double check the name in package.js matches the package added to the app?

Package.describe({
    name: 'lesswrong',

What happens when you run meteor add lesswrong in the parent app?

If it’s already been added it should say:
lesswrong without a version constraint has already been added.

One other note, all the packages I use have a namespace dg:package-name. Maybe try adding one?
eg. habryka:lesswrong