用许多HTML模板文件构造大型Meteor应用程序的最佳实践是什么?[关闭]


165

在所有示例(排行榜,文字游戏等)中,它们只有一个HTML模板文件。是否有一些大型的开源Meteor项目带有许多不同的HTML模板文件,我们可以将其用作最佳实践示例?将大型应用程序需要的所有内容都放在一个模板文件中似乎不切实际。


流星是新事物,我还没有找到与此相关的最佳实践。我也希望对此有所了解
newlife 2012年

10
您是否已阅读手册中有关构建应用程序的部分?关于扫描和串联HTML文件有一些解释。
zwippie 2012年

1
流星官方指南建议使用非常酷的文件结构。在此处查看:guide.meteor.com/structure.html#javascript-structure
Waqas,

Answers:


16

一起把它全部包起来!从文档:

> HTML files in a Meteor application are treated quite a bit differently
> from a server-side framework. Meteor scans all the HTML files in your
> directory for three top-level elements: <head>, <body>, and
> <template>. The head and body sections are seperately concatenated
> into a single head and body, which are transmitted to the client on
> initial page load.
> 
> Template sections, on the other hand, are converted into JavaScript
> functions, available under the Template namespace. It's a really
> convenient way to ship HTML templates to the client. See the templates
> section for more.

29
不过,这是发布者的关注点。集总可以,但是您可以看到Asana会发生什么-下载超过1MB的客户端代码时,它需要加载屏幕。对于许多网站来说,这是不可接受的。我们将看看在主屏幕加载后是否可能无法进行一些加载,但我现在对此表示怀疑。我认为它需要成为一种功能,以分解一些东西。
戴夫·桑德斯

36
这个答案是google中排名第一的结果,但它已经过时了。其他像我这样的未来访客;往下看!
Kloar 2014年

从1.1.0.2版本开始,当您在不加载浏览器缓存的情况下进行硬重装时,他们演示的简单的Todo应用程序将传输1.7MB的文件。对于许多用例来说,这是不可接受的。:/一旦资产被缓存,情况会大大改善,但是在第一次加载时,这是非常残酷的。
詹森·金

想法:使用webpack,制作东西的包,在需要时懒加载它们。
trusktr

是的,Asana需要一些时间来加载。Asana还是一款出色的反应式应用程序,2014年用户创建了1.75亿个任务。加载速度更快的应用程序并不总是更好。应用程序也需要一点时间才能在手机上启动。人们会习惯的。
Max Hodges

274

就像非官方的流星常见问题一样,我认为这足以说明如何构建大型应用程序:

我应该在哪里存放文件?

流星中的示例应用程序非常简单,并且没有提供太多见解。这是我目前关于最佳方法的想法:(非常欢迎任何建议/改进!)

lib/                       # <- any common code for client/server.
lib/environment.js         # <- general configuration
lib/methods.js             # <- Meteor.method definitions
lib/external               # <- common code from someone else
## Note that js files in lib folders are loaded before other js files.

collections/               # <- definitions of collections and methods on them (could be models/)

client/lib                 # <- client specific libraries (also loaded first)
client/lib/environment.js  # <- configuration of any client side packages
client/lib/helpers         # <- any helpers (handlebars or otherwise) that are used often in view files

client/application.js      # <- subscriptions, basic Meteor.startup code.
client/index.html          # <- toplevel html
client/index.js            # <- and its JS
client/views/<page>.html   # <- the templates specific to a single page
client/views/<page>.js     # <- and the JS to hook it up
client/views/<type>/       # <- if you find you have a lot of views of the same object type
client/stylesheets/        # <- css / styl / less files

server/publications.js     # <- Meteor.publish definitions
server/lib/environment.js  # <- configuration of server side packages

public/                    # <- static files, such as images, that are served directly.

tests/                     # <- unit test files (won't be loaded on client or server)

对于较大的应用程序,可以将离散功能分解为多个子目录,这些子目录本身使用相同的模式进行组织。这里的想法是,最终可以将功能模块分解为一个单独的智能程序包,理想情况下可以共享。

feature-foo/               # <- all functionality related to feature 'foo'
feature-foo/lib/           # <- common code
feature-foo/models/        # <- model definitions
feature-foo/client/        # <- files only sent to the client
feature-foo/server/        # <- files only available on the server

了解更多:非官方流星常见问题


12
恕我直言,这比公认的答案更好。我现在将尝试。
哈坎

17
从0.6.0开始,您最好避免这种混乱,并完全使用智能软件包运行应用程序。我会在此博客文章中详细介绍:matb33.me/2013/09/05/meteor-project-structure.html
matb33 2013年

1
任何人都有线索将放置在mobile-config.js哪里?
杜德(Dude)

1
感谢您的回答以及与非官方常见问题解答的链接(我是流星世界中的新人),“由他人提供的通用代码”是什么意思?谢谢!
Cohars

3
至于流星1.3,由于ES6模块的导入,我认为这已经过时了。请参阅有关应用程序结构的流星指南文章:guide.meteor.com/structure.html
Samuel,


26

设计Meteor的目的是,您可以采用几乎任何方式构建应用程序。因此,如果您不喜欢自己的结构,则可以将文件移动到新目录,甚至将一个文件拆分为多个部分,并将其几乎全部都移到Meteor。只需注意在主文档页面中指定的对客户机,服务器和公共目录的特殊处理即可:http : //docs.meteor.com/

仅将所有内容合并到一个HTML填充中肯定不会成为最佳实践。

这是一个可能的结构的示例:在我的一个应用程序中,一个讨论论坛,我按模块或“页面类型”(首页,论坛,主题,评论)进行组织,分别为.css,.html和.js文件页面类型一起放在一个目录中。我还有一个“基本”模块,其中包含通用的.css和.js代码以及主模板,该模板使用{{renderPage}}来根据路由器来呈现其他模块之一。

my_app/
    lib/
        router.js
    client/
        base/
            base.html
            base.js
            base.css
        home/
            home.html
            home.js
            home.css
        forum/
            forum.html
            forum.js
            forum.css
        topic/
            topic.html
            topic.js
            topic.css
        comment/
            comment.html
            comment.js
            comment.css

您也可以按功能进行组织

my_app/
    lib/
        router.js
    templates/
        base.html
        home.html
        forum.html
        topic.html
        comment.html
    js/
        base.js
        home.js
        forum.js
        topic.js
        comment.js
    css/
        base.css
        home.css
        forum.css
        topic.css
        comment.css

我希望确实能出现一些更具体的最佳实践结构和命名约定。


2
这是我最喜欢的答案。关于Meteor,我最喜欢的事情之一就是您可以采用适合自己的方式来构造文件。
CaptSaltyJack 2015年

我喜欢这个答案。我一直在做第一件事。
宋卓2015年

相关的事物应该彼此靠近。我的回答就像你的一样,但倒退了。
Max Hodges


我没有用功能名称(例如“ topic”)命名多个文件的价值。现在,如果要将功能名称更改为“类别”,则必须更改多个文件名。只需将它们组织在一个名为“ topic”的文件夹下,然后通用命名即可:events.js,views.html,样式,css,routes.js等。有关更多信息,请参见我的答案。
Max Hodges

14

对于在此主题上进行谷歌搜索的每个人:

em索具新的流星应用程序时,命令行工具(通过EventedMind,后面的铁路由器的球员)是非常有帮助的。它将创建一个不错的文件/文件夹结构。如果您已经在开发应用程序,并且想要重新组织它,只需与建立一个新项目,em然后就可以将其用于启发。

参见:https : //github.com/EventedMind/em

而在这里:https : //stackoverflow.com/questions/17509551/what-is-the-best-way-to-organize-templates-in-meteor-js


4
注意:此文件已由iron-cli代替(作者相同)。参见:github.com/iron-meteor/iron-cli
j0e 2015年

是的,'em'已重命名为iron-cli,与之相同。
Mikael Lirbank

11

我认为Discover Meteor Book的文件结构确实很好,而且是一个良好的开端。

/app: 
 /client
   main.html
   main.js
 /server 
 /public
 /lib
 /collections
  • / server目录中的代码仅在服务器上运行。
  • / client目录中的代码仅在客户端上运行。
  • 其他所有内容都在客户端和服务器上运行。
  • / lib中的文件先加载。
  • 任何其他main。*文件都会被加载。
  • 您的静态资产(字体,图像等)位于/ public目录中。

10

创建包

当然,并非所有方法都适合这种方法,但是在大型应用程序中,您将具有很多可以隔离的功能。软件包中任何可分离且可重复使用的软件包都适合,其余都放在通常的目录结构中,如其他答案所述。即使您不制作软件包来避免开销,以模块化方式构造代码也是一个好主意(请参阅这些建议

Meteor可以对文件的加载方式(加载顺序,其中:客户端/服务器/两者)以及软件包导出的内容进行细粒度的控制。

我特别发现在相关文件之间共享逻辑的简便方法非常方便。举例来说,您想制作一些util函数,并在其他文件中使用。您只需将其设置为“全局”(不带var),Meteor会将其包装在包的名称空间中,这样它就不会污染全局名称空间

是官方文件


6

经过meteorjs编码一段时间后,我很高兴能有一些空闲时间专门用于构建一个相当复杂的在线游戏。应用程序结构一直是我最关心的问题之一,似乎好几位优秀的程序员都拥护仅使用软件包的方法来构建应用程序,该方法使您可以松散地耦合功能不同的软件包。该方法还有其他优点,可以在这里找到2篇很好的文章介绍该方法:

http://www.matb33.me/2013/09/05/meteor-project-structure.html http://www.manuel-schoebel.com/blog/meteorjs-package-only-app-structure-with-mediator -模式


6

我们有一个大型项目(可能是迄今为止进行的1.5年全日制开发的最大的流星项目之一)。我们在每个视图中使用相同的文件名集。这是非常一致的,可以帮助我们快速导航到所需的内容:

  • events.js
  • helpers.js
  • templates.html
  • routes.js
  • 无样式
  • 等等

在项目中看起来像这样:

       ├──合并要求
       │├──events.js
       │├──helpers.js
       │├──routers.js
       │└──templates.html
       ├──客户恶搞
       │└──routers.js
       ├──仪表板
       │├──events.js
       │├──helpers.js
       │├──onDestroyed.js
       │├──onRendered.js
       │├──routers.js
       │└──templates.html
       ├──email验证
       │├──events.js
       │├──helpers.js
       │├──routers.js
       │└──templates.html
       ├──载入中
       │├──styles.css
       │└──templates.html
       ├──信箱
       │├──autoform.js
       │├──合并请求确认
       ││├──events.js
       ││├──helpers.js
       ││├──onCreated.js
       ││├──onRendered.js
       ││└──templates.html
       │├──events.js
       │├──helpers.js

相关模板只是一起存储在同一文件中。显示的内容在view/order/checkout/templates.html此处折叠:

<template name="orderCheckout"></template>

<template name="paymentPanel"></template>

<template name="orderCheckoutSummary"></template>

<template name="paypalReturnOrderCheckout"></template>

当视图包含很多部分时,我们将使用子文件夹:

       ├──手推车
       │├──addItem
       ││├──autoform.js
       ││├──events.js
       ││├──helpers.js
       ││├──onRendered.js
       ││├──routers.js
       ││├──款式少
       ││└──templates.html
       │├──结帐
       ││├──autoform.js
       ││├──events.js
       ││├──helpers.js
       ││├──onRendered.js
       ││├──routers.js
       ││└──templates.html
       │└──查看
       │├──autoform.js
       │├──deleteItem
       ││├──events.js
       ││├──helpers.js
       ││└──templates.html
       │├──editItem
       ││├──autoform.js
       ││├──events.js
       ││├──helpers.js
       ││└──templates.html
       │├──events.js
       │├──helpers.js
       │├──onDestroyed.js
       │├──onRendered.js
       │├──routers.js
       │├──款式少
       │└──templates.html

我们还使用WebStorm进行开发,WebStorm是用于Meteor开发的极其强大且灵活的编辑器。我们发现它在搜索和组织代码以及提高工作效率时非常有用。 网络风暴视图

乐意根据要求分享详细信息。


3
如果您认为此答案可以改善,请考虑添加评论。
Max Hodges 2015年

很棒的帖子。问题:在流星经历了所有这一切之后,您仍然推荐它用于大型项目,例如电子商务吗?或者考虑使用可能会给您带来更多“自治权”的框架,例如LoopBack甚至Happi。
Liko 2015年

我们热爱流星,并在其中进行所有新的开发。不幸的是,我对LoopBack或Happi不够熟悉,无法发表意见。
Max Hodges

1
LoopBacks专注于端到端的其余API,使其听起来像传统的Web开发框架(如RoR)。RoR正确使用了REST API,但我们认为Meteor正确使用了实时程序。
Max Hodges 2015年

感谢您的反馈。您也为功能组织了服务器端吗?
2015年

5

使用Iron-cli脚手架CLI。确实使事情变得很容易。

https://github.com/iron-meteor/iron-cli

一旦安装。用于iron create my-app创建一个新项目。它将为您创建以下结构。您也可以在现有项目上使用它。iron migrate在项目目录中使用。

my-app/    
 .iron/    
   config.json    
 bin/    
 build/    
 config/    
   development/    
     env.sh    
     settings.json    
 app/    
   client/    
     collections/    
     lib/    
     stylesheets/    
     templates/    
     head.html    
   lib/    
     collections/    
     controllers/    
     methods.js    
     routes.js    
   packages/    
   private/    
   public/    
   server/    
     collections/    
     controllers/    
     lib/    
     methods.js    
     publish.js    
     bootstrap.js

尽管此链接可以回答问题,但最好在此处包括答案的基本部分,并提供链接以供参考。如果链接的页面发生更改,仅链接的答案可能会失效。
user2314737

@ user2314737大声疾呼,说回答者确实编辑了他的帖子。现在,它包括解决当前问题所需的基本数据。
凯尔(Kyll)

4

我遵循的是mattdeom样板格式,该格式已经包括铁路由器和模型(Collection2)。见下文 :

client/                 # Client folder
    compatibility/      # Libraries which create a global variable
    config/             # Configuration files (on the client)
    lib/                # Library files that get executed first
    startup/            # Javascript files on Meteor.startup()
    stylesheets         # LESS files
    modules/            # Meant for components, such as form and more(*)
    views/              # Contains all views(*)
        common/         # General purpose html templates
model/                  # Model files, for each Meteor.Collection(*)
private/                # Private files
public/                 # Public files
routes/                 # All routes(*)
server/                 # Server folder
    fixtures/           # Meteor.Collection fixtures defined
    lib/                # Server side library folder
    publications/       # Collection publications(*)
    startup/            # On server startup
meteor-boilerplate      # Command line tool

3

构建应用程序有很多不同的方法。例如,如果您有一个路由器和不同的页面模板,并且在每个页面模板内部有很多页面部件,依此类推,那么我将根据上级>下级的语义来构造它。

例如:

client
  views
    common
      header
        header.html
        header.js
        header.css
      footer
        footer.html
        footer.js
        footer.css
    pages
      mainPage
        mainPage.html
        mainPage.js
        mainPage.css
        articles
          articles.html
          articles.js
          articles.css
        news
          news.html
          news.js
          news.css
     ...

当然,您可以将新闻模板放在common文件夹中,因为您可以在不同页面上使用新闻模板。

我认为最好以一种舒适的方式构建应用程序。

我在这里写了一个小应用程序:http : //gold.meteor.com 它是如此之小,我只使用一个html文件和一个template.js文件.. :)

希望对您有所帮助


我没有用功能名称(如“文章”)命名多个文件的价值。现在,如果要将功能名称更改为“ posts”,则必须更改文件名。只需将它们组织在一个名为“ articles”的文件夹下,并将它们命名为“ events.js”,views.html,styles,css等。有关更多信息,请参见我的答案。
Max Hodges

3

Evented Mind上有一个名为“ 设置流星项目”的新类,可以解决这个问题,但同时也涉及项目配置和设置开发环境。

在班上的“ 应用程序结构”视频中:流星对应用程序的结构没有很强烈的看法,但以下是一些规则:

1)加载顺序-流星首先进入文件目录中最深的位置,并按字母顺序处理文件

2)客户端和服务器是Meteor识别的特殊文件夹

我们的结构如下所示:

both/
    collections/
        todos.js
    controllers/
        todos_controller.js
    views/
        todos.css
        todos.html
        todos.js
    app.js - includes routes
client/
    collections/
    views/
        app.js
server/
    collections/
    views/
        app.js
packages/
public/

todos_controller扩展了RouteController,它是Iron Router附带的。

em上面提到的工具现在也得到了很大的更新,应该会更好并且可以在以下网址获得:https : //github.com/EventedMind/em


/ server / views /中的视图是什么?
stefcud

我没有用功能名称(如“ todos”)命名多个文件的价值。现在,如果要将功能名称更改为“任务”,则必须更改5个文件名称。只需将它们组织在一个名为“ todos”的文件夹下,并将它们命名为“ events.js”,views.html,样式,css等即可。有关更多信息,请参见我的答案。
Max Hodges

1

我也在寻找最佳实践,以通过一个构思良好的体系结构来增强和扩展我的应用程序。上述所有做法都适用于中小型应用程序,但是当您在更大的团队中工作时会失败。我尝试了几种方法:

1)我遵循以下策略:https : //github.com/aldeed/meteor-autoform来缩放和重用模板。作者对组件和现场设计有很好的想法。我之所以正在实施它,是因为社区开发了36个几乎涵盖所有情况的软件包,并且我可以在开发阶段使用TypeScript进行类型安全。

<template name="autoForm">
  {{#unless afDestroyUpdateForm this.id}}
  {{! afDestroyUpdateForm is a workaround for sticky input attributes}}
  {{! See https://github.com/meteor/meteor/issues/2431 }}
  <form {{atts}}>
    {{> Template.contentBlock ..}}
  </form>
  {{/unless}}
</template>

下面是关于如何做一个好博客文章:http://blog.east5th.co/2015/01/13/custom-block-helpers-and-meteor-composability/还有这里:HTTP:// meteorpedia .com / read / Blaze_Notes

2)这个看起来很有希望,但是最近还没有更新。这是一个用咖啡脚本编写的包,称为。用于Meteor的Blaze组件(https://github.com/peerlibrary/meteor-blaze-components)是一个用于轻松开发需要在您的Meteor应用程序附近重用的复杂UI元素的系统。您可以在CoffeeScript,香草JavaScript和ES6中使用它们。最好的是,组件是OOP。这是他们的例子之一:

class ExampleComponent extends BlazeComponent {
  onCreated() {
    this.counter = new ReactiveVar(0);
  }

  events() {
    return [{
      'click .increment': this.onClick
    }];
  }

  onClick(event) {
    this.counter.set(this.counter.get() + 1);
  }

  customHelper() {
    if (this.counter.get() > 10) {
      return "Too many times";
    }
    else if (this.counter.get() === 10) {
      return "Just enough";
    }
    else {
      return "Click more";
    }
  }
}

ExampleComponent.register('ExampleComponent');

{{> ExampleComponent }}

3)我喜欢类型和翻译器,它们可以告诉我何时何地出现问题。我正在使用TypeScript与Meteor一起工作,并找到了以下存储库:https : //github.com/dataflows/meteor-typescript-utils似乎创建者试图完成MVC方法。

class MainTemplateContext extends MainTemplateData {
    @MeteorTemplate.event("click #heybutton")
    buttonClick(event: Meteor.Event, template: Blaze.Template): void {
        // ...
    }

    @MeteorTemplate.helper
    clicksCount(): number {
        // ...
    }
}

class MainTemplate extends MeteorTemplate.Base<MainTemplateData> {
    constructor() {
        super("MainTemplate", new MainTemplateContext());
    }

    rendered(): void {
        // ...
    }
}

MeteorTemplate.register(new MainTemplate());

<template name="MainTemplate">
    <p>
        <input type="text" placeholder="Say your name..." id="name">
        <input type="button" value="Hey!" id="heybutton">
    </p>
    <p>
        Clicks count: {{ clicksCount }}
    </p>

    <p>
        <ul>
            {{#each clicks }}
                <li> {{ name }} at <a href="{{pathFor 'SingleClick' clickId=_id}}">{{ time }}</a></li>
            {{/each}}
        </ul>
    </p>
</template>

不幸的是,这个项目没有得到维护或积极开发。

4)并且我认为已经提到过,您可以使用包进行扩展。这需要一种良好的抽象思维方式。它似乎适用于Telescope:https : //github.com/TelescopeJS/Telescope

5)meteor-template-extension –提供了多种方法来复制模板助手,事件处理程序和模板之间的挂钩,从而允许代码重用;不利之处在于,所有复制都必须一次又一次地由开发人员处理,随着代码库的增长,这成为问题。此外,如果没有明确定义的API社区,就无法构建和共享组件

6)流组件 –流组件在API设计中更接近React,而Blaze组件则保持熟悉的概念,例如数据上下文和模板帮助器;另一方面,Flow组件仍然使用基于模板的事件处理程序,而Blaze组件使它们成为类方法,因此通过继承更容易扩展或覆盖它们。通常,Blaze Components似乎更面向OOP;Flow组件尚未正式发布(#5和#6的文本鸣谢https://github.com/peerlibrary/meteor-blaze-components#javascript-and-es6-support

2号和3号也需要一些使用,但是随着时间的推移,您将获得更快的开发速度。第四步使您可以构建和测试组件以使代码更稳定。第三名具有Typescript的完全类型安全性的优点,这在您编写文档质量差的团队时是一个巨大的优势。但是,我目前正在将第二个端口移植到TypeScript,因为使用它感觉很舒服,而且在我不使用Gulp时,不必为了使它与Meteor一起工作而需要花费一周的编译器包。

仍然很难找到与Meteor合作的正确方法。您需要自己弄清楚它,否则最终会得到一个排列合理的文件夹结构,但是您不知道所有内容在哪里。快乐的编码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.