【问题标题】:How to properly use es6 classes in different files by importing them in Meteor?如何通过在 Meteor 中导入它们来正确使用不同文件中的 es6 类?
【发布时间】:2015-06-04 17:01:51
【问题描述】:

我最近发现了 Meteor,我正在努力在一个新的 Meteor 项目中使用 ES6 类和导入。我想要做的是拥有一个复杂的类结构,这些方法从 Meteor 事件/方法/帮助程序中调用。我已经通过编写命令$ meteor add grigio:babel 将 Babel.js 添加到项目中,并且它可以正常工作。

我想要实现的示例:

在 server/models/article.js 中:

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

在服务器/方法/articles.js 中:

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

仅在方法文件中引发ReferenceError: Article is not defined,这就足够了。所以我有三个选择:将所有类写入一个文件,将所有类附加到一个全局对象或使用像 Browserify 这样的良好模块系统。显然,第三种选择更好。

但是我该如何使用它呢? Babel 默认将exportimport 转换为Browserify,Meteor 在页面刷新时会引发require is not defined 错误。在谷歌搜索问题后,我没有找到关于如何将 Browserify 添加到 Meteor 的明确解决方案。我是否应该向 Meteor 添加一个 npm 包支持,添加一个 browserify 的 npm 包并在我导入/导出任何内容的每个页面上手动将其添加到 Meteor?还是我应该使用完全不同的方法? Meteor 通常如何处理此任务?谢谢!

【问题讨论】:

  • 对于任何包含 es6 ECMAScript 2015 代码的文件,使用 .es6 扩展名而不是 .js。这为我修复了一个类似的 ReferenceError。如果它适合您,我会添加此评论作为答案。

标签: javascript meteor module browserify ecmascript-6


【解决方案1】:

我正在使用 Meteor 1.4.1.1 并且在复制您的方法时错误仍然存​​在。但是,现在有一些使用 es6 类的新方法:

1.将您的类导出为常量(例如用作单例对象):

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

您可以通过以下方式导入此文件

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

2。将您的类直接导出为模块的默认值

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

然后将其导入(与上面一样)如下

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

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

关于OP的问题和报错,你可以试试这样的:

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 {Article} from 'path/to/Article.js';

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


//or get all your articles
const allArticles = Article.all();

【讨论】:

  • 如何导入?
  • @afkatja 我改进了我的答案。这对您的问题有帮助吗?也许您应该在 SO 上创建一个新问题。
【解决方案2】:

我这样做的方式是将对象一起收集到各种命名空间中,例如:

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

_.extend(Collections, { Article });

然后为了避免必须在任何地方使用Collections.Article,我可以在我需要访问Article的文件中使用以下内容:

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

【讨论】:

【解决方案3】:

我之前正在阅读这方面的内容,并在 github 上找到了 this issue,这可能会有所帮助。

基本上只需将类分配给客户端和服务器都公开的变量(lib/both/etc 取决于您的文件结构)。像这样:

Article = class Article {...}

似乎是目前最好的解决方案。

【讨论】:

  • 不幸的是,使用它只会将 Article 暴露给全局命名空间,这会导致命名空间污染。所以如果我走全局路径,我宁愿使用命名空间,比如website.Article = class Article {...}
  • 确实如此。仍然不是一个不合理的解决方案,可能足够长时间了
  • @corvid 模块即将推出,但不在 1.2 中。如果您稍后阅读那篇文章 - “我们正在添加对除模块之外的所有功能的支持”
猜你喜欢
  • 1970-01-01
  • 2018-05-01
  • 2018-02-23
  • 2020-12-26
  • 2021-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多