Can I make a Julia package containing multiple modules that can be independently imported?

2.1k Views Asked by At

One of the projects I'm collaborating on has four different modules (Foo, Bar, Baz, and Plotting) and I've been tasked with combining them into a package. It is simple enough in Julia to make a new package:

julia> Pkg.generate("MyPackage", "MIT")

I copied my modules into the ~/.julia/v0.3/MyPackage/src/ and added include statements to MyPackage.jl. It looks something like this:

module MyPackage

include("foo.jl")
include("bar.jl")
include("baz.jl")
include("plotting.jl")

end

Each included file contains the corresponding module.

My main problem with this is Plotting takes forever to import and it's not needed very often when we're using the rest of MyPackage. I'd really like to be able to do something like using MyPackage.Foo to just get Foo (and particularly to exclude the Plotting and its slow import time). I've tried a couple different approaches for how I structure things, including having sub-modules explicitly defined inside MyPackage.jl instead of in each file individually, but no matter what I try, I always get the loading lag from Plotting.

Is it possible build a package so you can independently load modules from it? and if so, how?

Note: I'm new to Julia and newer still to building packages. Sorry if any of my semantics are wrong or anything is unclear.

2

There are 2 best solutions below

2
On BEST ANSWER

Try Requires.jl:

Requires is a Julia package that will magically make loading packages faster, maybe. It supports specifying glue code in packages which will load automatically when a another package is loaded, so that explicit dependencies (and long load times) can be avoided.

0
On

Is it possible build a package so you can independently load modules from it? and if so, how?

Following the advice of this comment has worked for me: https://discourse.julialang.org/t/multiple-modules-in-single-package/5615/7?u=nhdaly

You can change the top-level package-named Module to simply just expose the other four Modules as follows:

# <julia_home>/MyPackage/src/MyPackage.jl
module MyPackage
push!(LOAD_PATH, @__DIR__) # expose all other modules defined in this directory.
end

Then to import the other modules, say Bar, the user code would do:

# code.jl
using MyPackage; using Foo;
...

But it's worth noting that, then, Foo, Bar, Baz and Plotting are all also treated as top-level modules, so you'll want to make their names unique so they don't conflict with other Packages/Modules. (ie somethig like MyPackageFoo, not Foo.)