使用许多HTML模板文件构建大型Meteor应用程序的最佳实践是什么?

时间:2012-04-12 11:50:14

标签: meteor

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

13 个答案:

答案 0 :(得分: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

了解详情:Unofficial Meteor FAQ

答案 1 :(得分:36)

我同意yagooar,但不是:

client/application.js

使用:

client/main.js

main。*文件最后加载。这有助于确保您没有任何加载订单问题。有关详细信息,请参阅Meteor文档http://docs.meteor.com/#structuringyourapp

答案 2 :(得分: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

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

答案 3 :(得分:15)

把它们拼凑起来!来自文档:

> 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.

答案 4 :(得分:14)

对于每个使用Google搜索此主题的人:

em命令行工具(由铁路由器背后的人EventedMind)在装配新的Meteor应用程序时非常有用。它将创建一个漂亮的文件/文件夹结构。如果您已经在使用应用程序并希望重新组织它,只需使用em设置一个新项目,您就可以将其用作灵感。

请参阅:https://github.com/EventedMind/em

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

答案 5 :(得分:11)

我认为来自Discover Meteor Book的文件结构非常好并且是一个可靠的开始。

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

答案 6 :(得分:9)

创建包

当然并非所有内容都符合这种方法,但在大型应用程序中,您将拥有许多可以隔离的功能。 任何可分离和可重用的东西都适合包,其余的都在通常的目录结构中,如其他答案所述。即使您不创建包以避免开销,以模块化方式构造代码也是一个好主意(参见these suggestions

Meteor允许对如何加载文件(加载顺序,其中:client / server / both)以及程序包导出的内容进行细粒度控制。

我特别觉得在相关文件之间共享逻辑的简单方法非常方便。比如说,你想做一些util函数并在不同的文件中使用。你只需将它设为“全局”(没有var),Meteor会将它包装在包的名称空间中,因此它不会污染全局命名空间

Here是官方文件

答案 7 :(得分: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-pattern

答案 8 :(得分: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

答案 9 :(得分: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

答案 10 :(得分: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
     ...

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

我认为以您熟悉的方式构建应用程序是最好的。

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

我希望它有所帮助

答案 11 :(得分:3)

Evented Mind上有一个名为Setting Up Meteor Projects的新课程,解决了这个问题,但也讨论了项目配置和设置开发环境。

来自课堂上的Application Structure视频:Meteor对于如何构建应用程序没有非常强烈的意见,但这里有一些规则:

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

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获得

答案 12 :(得分: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)是一个用于轻松开发复杂UI元素的系统,需要在Meteor应用程序周围重复使用。您可以在CoffeeScript,vanilla 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)我认为已经提到过,你可以使用包进行扩展。这需要一种良好的抽象思维方式。它似乎适用于望远镜:https://github.com/TelescopeJS/Telescope

5)meteor-template-extension - 提供了各种方法来复制模板助手,事件处理程序和模板之间的钩子,允许代码重用;一个缺点是开发人员必须经常一次又一次地处理所有复制,这随着代码库的增长而变得有问题;而且,没有明确定义的API社区就无法构建和共享组件

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

2号和3号也需要一些使用,但随着时间的推移你会获得开发速度。第四个允许您构建和测试组件以使代码更稳定。第三个类型具有Typescript的完全类型安全性的优势,当你在一个文档很差的团队中开发时,这是一个巨大的优势。但是,我目前正在将第二个移植到TypeScript,因为我觉得使用它非常舒服,而且当我不使用Gulp时,我不需要调整编译器包以使其与Meteor一起使用。

仍然很难找到与Meteor合作的正确方法。你需要自己解决这个问题,否则你最终得到一个安排得很好的文件夹结构,但你不知道一切都在哪里。快乐的编码。