Local repo Motoko imports with absolute file paths

As our dapp has gained in complexity (and canisters), we’ve had to create a deep directory structure.

image

and this is turning into a game of count the slashes and dots

image

is there any way we can import same-project Motoko files using absolute paths as opposed to relative? Something like golang, go.mod would be great.

Thanks!

2 Likes

The struggle is real.

2 Likes

You can do something like this:

moc --package base $(dfx cache show)/base --package shared shared -r main.mo

Then:

import DB "mo:shared/DB";
import M "mo:shared/gen/Mutator";

Oh ok, so do you do that once, or do you add it to the compiler options when you do dfx build? Does moc have a config file that it adds the packages to?

You’d need to do something like this:

I’m not aware of any config file.

or maybe you can use Vessel to set up a local package.

I think using the packtool field will mean you don’t need to change to a custom canister type.

Whether you’re using Vessel or not, it looks like you can add or edit the packtool field under build to return the directories you want to be loaded as packages.

The Vessel README gives this example:

...
"defaults": {
  "build": {
    "packtool": "vessel sources"
  }
}
...

You may or may not want to put this in defaults instead of in individual canisters depending on your setup.

ok fantastic - gonna sleep on this and see if we can find something that works for us tomorrow. Thanks again!

Based on this:

I think something like this will work:

"packtool": "echo \"--package base $(dfx cache show)/base --package shared shared\""

1 Like

If you’re already using Vessel you’d still need to use vessel sources and either add a new package to your vessel.dhall file or somehow manually add --package shared shared.

This might work:

"packtool": "vessel sources && echo \"--package shared shared\""

The Vessel README explains how to add a local package to your package set:

How do I add a local package to my package set?

Make sure your local package is a git repository, then add an entry like so to your additions in the package-set.dhall file:

let additions = [
   { name = "mypackage"
   , repo = "file:///home/path/to/mypackage"
   , version = "v1.0.0"
   , dependencies = ["base"]
   }
]

Now you can depend on this package by adding mypackage to your vessel.dhall file.

2 Likes

For visibility: removed a comment from @808mafia which was off topic and generally spammed

1 Like

Yeah the vessel solution isn’t ideal as we have a lot of generated files and tend to move things around. Committing the local repository and then pulling it on each change would fix it but is a bit unwieldy.

We’re working on a solution, will let you know what we end up doing. Would love it eventually if you could include local files with an absolute path but know its not very important in the whole scheme of things.

Something like this is probably the simplest thing to do then.