Import from /client to server

When I import code from the imports folder, it works :

import test from '/imports/test.js';

But when I add the client folder :

import test from '/imports/client/test.js';

I have this error :

Error: Cannot find module '/imports/client/test.js'

I don’t understand why.

Because everything in folder client accessible only on client side. If you need both side - use lib folder

Not strictly true. You can import anything from anywhere.

@fabienhuet : do you have a folder /imports/client/ with a test.js in it?

Any directory named client/ is not loaded on the server. Similar to wrapping your code in if (Meteor.isClient) { ... }.

Meteor gathers all your JavaScript files, excluding anything under the client, public, and private subdirectories, and loads them into a Node.js server instance. In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node.

Maybe something changed. Meteor Guide

That’s correct. I said you can import anything from anywhere.

EDIT: Except it isn’t … see below.

@none : Yes, that is for automatic inclusion, I’m importing stuff.

@robfallows : Yes, as structured in the initial question.

  • client
    – code
  • imports
    – client
    ---- test.js
  • server
    – main.js

I try to import test in main ; does not find it.

I stand corrected.

You cannot import server to client or client to server - even under imports/.

You will need to use imports/both or imports/server/ or imports/client/ or similar.

Thanks @none : you made me check!

1 Like

((((-:
I’ve tried this right now too: not working…
I mean /client/* not working

Ok :frowning:

Thanks

This behaviour is documented in the guide:

…Meteor ensures that any file in any directory named server/ will only be available on the server, and likewise for files in any directory named client/. This also precludes trying to import a file to be used on the server from any directory named client/ even if it is nested in an imports/ directory and vice versa for importing client files from server/.

1 Like

Would this apply to this question as well?

We cannot import server to client Methods/Publish functions to the client? In the old days, we everything was just “there” for the taking.

I’m trying to figure out the “right” way to import meteor methods and publish functions that reside server side only.

That particular question shows a publication (two actually). Meteor.publish can only be used on the server.

So, even if you imported that code to the client (and given the earlier discussion, above, you wouldn’t be allowed to), it wouldn’t work - there is no Meteor.publish on the client.

I wonder if you’re confusing import with “consume”, especially since it is possible to have Meteor.methods on the client?

In a nutshell, the client can consume server functionality - it can subscribe to a publication or call a method, but it may not always make sense (or be possible) to import server functionality. And as we’ve seen, the build tool does not permit code in a client/ folder to import code from a server/ folder - even if either or both are in an imports/ folder.

I reviewed that guild, and reviewed the “todos” code, I couldn’t find an example where the client import meteor methods or publish functions. Can someone help me or point me to code where I can help myself find examples please?

In the old days, I “consumed” meteor methods or publish functions without any effort. Today, I assumed (I know, that’s bad) we need to import everything – so that lead me to look for examples along these lines.

Also, I know I don’t HAVE to import anything, as Meteor still provides the “magic” as before. Yet, I’m looking to sort out my code to comply with the “new” way of JS and the industry, hence, I’m looking to import everything.

Are we saying here that we should NOT import meteor methods or publish functions, setting them outside the “new normal” way of things?

Ah - okay. So import (in Javascript) together with imports/ (the folder) allows you to control which files you want to include in your build - and where you want them to go (client, server or both). In addition, they also let you control load order, which may be important.

Back in the pre-import days, Meteor loaded everything it could see according to the conventions of folder names (client/, server/ and lib/ being the standard trifecta). If you needed to control load order, you had to follow the practise of alphabetising file names and/or building arbitrarily obscure folder trees.

So now you still have the eager loading described above, but you also have the ability to “only load what I tell you to load, where I tell you to load it”. Anything under an imports/ folder will not appear in the final app unless you import it. There is still client-only code, server-only code and code which can be on both. A running Meteor application is no different. Using import with imports/ just gives you complete control of how modules are stitched together for build.

Don’t know if that helps - I’m sure there’s a better explanation somewhere out there.

I read the docs and examples and understand what you’re written.

So, a simple question, how does a [Publish] function in [/imports/server/publishing] end up inside a Blaze OnCreated function where I can [Subscribe] to it [/imports/client/ui] in Meteor 1.5 if both are under the import directory?

Illustration:

// imports/server/publishing/test.js

Meteor.publish('publish.test', function() {
  if (this.userId) return TestCollection.find({});
  return self.ready();
});

// imports/client/ui/test.js

import { Template } from "meteor/templating";
import { ReactiveDict } from "meteor/reactive-dict";
import { Mongo } from 'meteor/mongo';
import TestCollection from '../../imports/collections/test.js';

import "./test.html";

Template.Test.onCreated(function() {
  this.state = new ReactiveDict();

  this.autorun(() => {
    const subscription = this.subscribe('publish.test');
     ...
    }
  });
});

So, it could be something like this:

In server/main.js:

import '../imports/server/publishing/test.js';
// ...

However, imports/server/ui/test.js should be imports/client/ui/test.js: these are for the client, so should not be in a server/ folder. Then in client/main.js something like:

import '../imports/client/ui/test.js';
// ...
1 Like

Corrected that, thanks for catching it.

1 Like

Wait, so you’re saying from the traditional Meteor directories OUTSIDE the /imports directory, e.g., app-name/server and app-name/client, I should import from the /imports directory THEIR, and then use them as we did in prior times?

I tried to make an Illustration, but I just don’t understand. Is there an example somewhere?

If I understand you correctly - yes. :slight_smile: