[Meteor 1.3] Isomorphism & modules

What is the best approach when creating an isomorphic resource with modules?

Here’s what I’m currently doing:

// /imports/foo.js
import { Meteor } from 'meteor/meteor';

export let foo;

if (Meteor.isClient) {
  foo = require('./client/foo.js').foo;
} else {
  foo = require('./server/foo.js').foo;
}
// /imports/client/foo.js
export const foo = new class Foo(/* client implementation */);
// /imports/server/foo.js
export const foo = new class Foo(/* server implementation */);

Pros:

  • Appears to work. It imports the correct implementation and users of the resource just import { foo } from '/imports/foo.js' without worrying about whether they’re running on the client or server.

Cons:

  • Uses require, side-stepping build tools that look for import statements.

  • Server code on the client (i.e., { foo } = require('./server/foo.js');) and client code on the server (i.e., { foo } = require('./client/foo.js');).

What’s everyone else doing?

1 Like

Switch around your dependencies:

// imports/foo.js

/* declare shared code in shared directory */
// edit: ES6 exports are immutable, so you need to export an object
export let foo = {
  foo: new class Foo(/* placeholder */);
}
// imports/client/foo.js
import {foo} from '/imports/foo';

foo.foo = new class Foo(/* client implementation */)

The Mantra spec actually recommends keeping the client & server separate, which, while it goes against Meteor’s benefits, sometimes makes sense for situations like these.

Hi @reoh, thanks for the reply. That was another approach that I looked at but I wasn’t sure about modifing a module’s exports. What’s the best practise there?

I guess you’ll probably want to make sure it’s only defined in one place and it can’t accidentally be re-defined later on by using Object.freeze to make the export immutable after defining it:

// imports/foo.js
foo.foo = new class Foo(/* client implementation */)

Object.freeze(foo);

export {foo};
// imports/whoops.js

foo.foo = new class Bar() // TypeError

and of course document the shared export so you know exactly where it’s client/server definitions are

1 Like