Multi-app/microservices architecture: from package-based to module-based project structure


#1

Hi,

I’m trying to structure a project which consists of multiple apps and requires separate builds for each. So if I was using a package based approach the structure would be similar to the following:

/root
	/web-app
		/.meteor
		PACKAGE_DIRS points to ../packages
	/mobile-app
		/.meteor
		PACKAGE_DIRS points to ../packages
	/admin-app
		/.meteor
		PACKAGE_DIRS points to ../packages
	/packages
		/package1
		/package2
		/package3

Where all the functionality resides in separate packages that can be used by several apps.

This works, but using imports/exports is much less cumbersome because writing package.js files gets really verbose and with packages you also lose the benefit of using things like meteor add and meteor update, so I would like to move away completely from packages to modules.

In a single app it’s pretty straightforward to use modules, but with a structure like this I don’t seem to be able to import from outside each app’s folder.

Basically, the desired structure is something like this:

/root
	/web-app
		/.meteor
	/mobile-app
		/.meteor
	/admin-app
		/.meteor
	/imports
		/module1
		/module2
		/module3

And for example inside web-app I would use import { name } from '../imports/module1/module1', but this doesn’t work. No matter the syntax I can’t get it to import a module that is not within the web-app folder.

In the past the recommendation was to follow a package-based structure, but the suggestion seems to be moving away from that to a modules-based structure, but this scenario doesn’t seem suited to a multi-app/microservices architecture.

Have you done something similar to this and how were you able to implement it without using packages?


#2

Can you make your imports directory a package, add the package to each app, and then you can import the modules from the package to each app? I’m not super well versed in Meteor’s new (1.3+) architecture, but I believe Meteor only now loads what is explicitly written to do so. I would assume this extends to packages too.


#3

So basically just one package with everything and in that package just use the imports/exports approach? Yes, I think that works. That’s probably a good compromise.

Either that or I’ll use a bit of a more mixed approach.

Thank you.


#4

You could try to simply symlink the imports dir into each of the meteor apps, to share the code. This way you don’t need to change anything, in each app you will be able to import the modules using absolute imports (/imports/module1), or relative paths if you like.

You will need to make sure the imports dir comes along when you deploy the apps though.


#5

I thought of that too, but symlinks bring their own problems, since our team is on Windows.


#6

Well there is your problem then! (kidding)(…kind of).

We struggled with the same issues you are describing, and for now we have avoided making a mobile app in meteor to “get around it”, and then have admin and app in one.


#7

Ahah, I know, right? :stuck_out_tongue:


#8

Has anybody tried importing from a package? It’s possible to import modules from packages, ala meteor/meteor and meteor/session and so forth. So maybe something like the following would work?

    /root
      /web-app
          /.meteor
    	  PACKAGE_DIRS points to ../packages
      /mobile-app
    	  /.meteor
    	  PACKAGE_DIRS points to ../packages
      /admin-app
          /.meteor
    	  PACKAGE_DIRS points to ../packages
      /packages
    	  /package1/module1
    	  /package2/module2
    	  /package3/module3

You’d have to run meteor add myaccount:package1 and then add the following import statement:

import { module1 } from 'package1/module1'

#9

Yes, that kind of structure works. It’s what I ended up using. Initially I was trying to move away completely from packages, but there are still some advantages to using packages.

To import from a package you have to use:

import { module1 } from 'meteor/name:package1'

Or:

import { module1 } from 'meteor/name:package1/module1'