最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to properly use es6 classes in different files by importing them in Meteor? - Stack Overflow

programmeradmin0浏览0评论

I have recently discovered Meteor and I am struggling with using ES6 classes and imports in a new Meteor project. What I want to do is to have a complex structure of classes, which methods get called from Meteor events/methods/helpers. I've added Babel.js to the project by writing a command $ meteor add grigio:babel and it works properly.

Example of what I am trying to achieve:

in server/models/article.js:

class Article {
  static all() {
    //returns all articles from db
  }
}

in server/methods/articles.js:

Meteor.methods({
  allArticles: {
    Article.all();
  }
})

Having just that raises ReferenceError: Article is not defined in a methods file, which is adequate. So I have got three options: write all classes in one file, append all classes to a global object or use a good module system like Browserify. Obviously, third option is better.

But how do I use that? Babel converts export, import into Browserify by default and Meteor raises a require is not defined error on page refresh. After googling the problem I didn't find a clear solution on how to add Browserify to Meteor. Should I add a npm packages support to Meteor, add a npm package of browserify and add it manually to Meteor on every page where I import/export anything? Or should I use a completely different approach? How is this task usually handled in Meteor? Thank you!

I have recently discovered Meteor and I am struggling with using ES6 classes and imports in a new Meteor project. What I want to do is to have a complex structure of classes, which methods get called from Meteor events/methods/helpers. I've added Babel.js to the project by writing a command $ meteor add grigio:babel and it works properly.

Example of what I am trying to achieve:

in server/models/article.js:

class Article {
  static all() {
    //returns all articles from db
  }
}

in server/methods/articles.js:

Meteor.methods({
  allArticles: {
    Article.all();
  }
})

Having just that raises ReferenceError: Article is not defined in a methods file, which is adequate. So I have got three options: write all classes in one file, append all classes to a global object or use a good module system like Browserify. Obviously, third option is better.

But how do I use that? Babel converts export, import into Browserify by default and Meteor raises a require is not defined error on page refresh. After googling the problem I didn't find a clear solution on how to add Browserify to Meteor. Should I add a npm packages support to Meteor, add a npm package of browserify and add it manually to Meteor on every page where I import/export anything? Or should I use a completely different approach? How is this task usually handled in Meteor? Thank you!

Share Improve this question asked Mar 31, 2015 at 11:08 cbrwizardcbrwizard 932 silver badges9 bronze badges 1
  • Use the .es6 extension instead of .js for any files containing es6 ECMAScript 2015 code. This fixed a similar ReferenceError for me. If it works for you I'll add this comment as an answer. – Dave Roma Commented Aug 5, 2015 at 14:01
Add a comment  | 

3 Answers 3

Reset to default 13

I was reading about this earlier and found this issue on github that may help.

Essentially just assign the class to a variable that is exposed to both the client and server (lib/both/etc depends on your file structure). Like so:

Article = class Article {...}

Seems to be the best solution at the moment.

The way I do this is to collect objects together into various namespaces, for example:

// Global
Collections = {};
class Article {
  static all() {
    //returns all articles from db
  }
}

_.extend(Collections, { Article });

Then to avoid having to use Collections.Article everywhere I can use the following in the file I need to access Article in:

// Make `Article` available
let { Article } = Collections;

I am using Meteor 1.4.1.1 and the error remains, when reproducing your approach. However, there are some new ways to use es6 classes now:

1. Export your class as a constant (e.g. for use as a singleton object):

class MyModuleInternalClassName {
   //... class internals
}
export const PublicClassName = new MyModuleInternalClassName();

You can import this one via

import {PublicClassName} from 'path/to/PublicClassFileName.js';

2. Export your class directly as the module's default

export default class PublicClassName {
   //... class internals
}

and then import it (as with the above one) as the following

import {PublicClassName} from from 'path/to/PublicClassFileName.js';
let myInstance = new PublicClassName();

+++++++++++++++++++++++++++++++++

Regarding the question of OP and the error, you can try something like this:

Article.js

class InternalArticle {
  constructor(){
     //setup class
  }

  all() {
    //returns all articles from db
  }
  register(article){
     //add article to db
  }
}
export const Article = new InternalArticle();

Import and use the Singleton

import {Article} from 'path/to/Article.js';

//either register some article
Article.register(someArticle);


//or get all your articles
const allArticles = Article.all();
发布评论

评论列表(0)

  1. 暂无评论