5
votes

This is probably a very easy question for meteor 1.3 knowledgable people.

In the meteor application structure documentation its recommended to split an API into a few files but I didn't see any examples of how to pull them back together. I'm starting with Todo React Tutorial: Collections and I'm trying to split /api/tasks.js into tasks.js methods.js server/publications.js

I don't know what changes I need to make from the code that was in tasks.js to properly import the code moved to methods.js and server/publications.js

Thank you for your assistance!

Code: http://www.github.com/Falieson/LearningReact/blob/meteor_todos/MeteorTodos_React/imports/api/tasks/tasks.js

2

2 Answers

3
votes

This is a fairly broad and opinionated topic, so I will try to give a concise answer that relates to matters discussed in the Meteor Guide.

First, I would follow through with the tutorial to get its purpose. To me, it seems that it is not intended to teach you how to build a complex app, but rather to get the hang of React in a basic Meteor project.

There is no definitive answer to the question of project structure, as it is fairly opinionated. Some partition by function, others by feature; some like deep nesting and some prefer a more flat structure.

The main theme is that the modules' explicit import syntax makes your dependencies explicit and therefore prevent the need for guesswork or awkward filenames that loses semantics and makes finding the source of each symbol a non-trivial task.

The app structure tutorial is not complete either and mainly includes guidelines.

Let's assume something like the following simple structure, that fits pretty closely with the use-case:

.
├── client
│   └── main.js
├── imports
│   ├── api
│   │   ├── api.js
│   │   ├── api-server.js
│   │   └── module1
│   │       ├── collections.js
│   │       ├── methods.js
│   │       └── server
│   │           └── publications.js
│   ├── client
│   │   └── index.js
│   └── server
│       └── index.js
└── server
    └── main.js

Anything in the imports directory is not automatically imported. It all starts in the server/main.js and client/main.js entry points.

They, in turn, import the imports/<target>/index.js, which is where the app is bootstrapped for each target (client/server).

Since some of the api code is server-specific, you would probably want to create a server-api.js file or the like that also imports the server resources.

During the bootstrap process, the server's index.js will

import '../api/api-server';

api-server.js will:

import './api';
import './module1/server/publications';

while the client/index.js could import api.js directly.

Standard methods and publications do not export any symbol, so no need to import them individually, but only the file that they are defined in.

api.js will:

import './module1/methods';

where methods.js and publications.js will import the collections.js file, assuming they need it.

Again, this is a very broad and opinionated topic and there are several ways to structure your project.

0
votes

I'm not sure I understand what the problem is. I'm guessing it's about the import statements.

In your original tasks file you have

import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';

You need those to use functions/objects from the Meteor, Mongo and check packages.

You need look at what the code needs. In your methods.js file, you use Meteor and check, but you don't use Mongo. So you want to add

import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';

I also see that you declare your Mongo collection in your publication.js file, which is usually not appropriate. A publication should run only on the server, while your collection should be declared both on the client and the server.

So you should move this code

export const Tasks = new Mongo.Collection('tasks');

typically, it would go in the task.js file.

In this case, in the task.js, as you're declaring a collection, you're using the Mongo object and you need to

import { Mongo } from 'meteor/mongo';

And in your publication, for the moment you just need

import { Meteor } from 'meteor/meteor';

There's still a problem, as you declared the task object using export, you need to import it the same way than you import Meteor, Mongo and check, but as your own package:

import { Tasks } from './tasks';

for files in the same folder than the tasks.js file. And

import { Tasks } from '../tasks';

if it's in a subfolder.

Does this somehow answers your question? If you need more help, please be more specific and/or include some error log.