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

在所有的例子中(排行榜,文字游戏等) ,他们有一个单一的 HTML 模板文件。是否有一些大型的开源项目与许多不同的 HTML 模板文件,我们可以使用作为一个最佳实践的例子?把一个大型应用程序需要的所有东西都放在一个模板文件中似乎不太实际。

48015 次浏览

把它们放在一起! 来自医生:

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

就像非官方的流星常见问题一样,我认为它很好地解释了如何构建一个大型应用程序:

我应该把我的文件放在哪里?

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

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

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

我同意 yagooar,但代替:

client/application.js

Use:

client/main.js

总台。* 文件最后加载。这将有助于确保您没有任何加载顺序问题。有关更多细节,请参见流星文档 http://docs.meteor.com/#structuringyourapp

流星被设计成你可以随心所欲地构建你的应用程序。所以,如果你不喜欢你的结构,你可以只是移动一个文件到一个新的目录,甚至分裂成许多片段一个文件,流星几乎都一样。只需注意在主文档页面 http://docs.meteor.com/中指定的对客户机、服务器和公共目录的特殊处理。

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

下面是一个可能的结构示例: 在我的一个应用程序中,一个讨论论坛,我通过模块或“页面类型”(主页、论坛、主题、评论)组织,放置。CSS.Html 和。将每个页面的 js 文件类型放在一个目录中。我还有一个“ base”模块,它包含公共。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

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

有很多不同的方法来构建你的应用程序。 例如,如果您有一个路由器和不同的页面模板,并且在每个页面模板内部都有许多页面部件等等,我将根据较高级 > 较低级的语义来构造它。.

例如:

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

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

我认为这是最好的你的应用程序结构,在一种方式,你是舒适的。

我在这里写了一个小应用程序: < a href = “ http://gold.mete.com”rel = “ nofollow”> http://gold.meteor.com 它非常小,我只使用一个 html 文件和一个 template.js 文件. . :)

我希望能有点帮助

我认为,从发现流星书的文件结构是真的很好,一个坚实的开始。

/app:
/client
main.html
main.js
/server
/public
/lib
/collections
  • /server 目录中的代码只在服务器上运行。
  • /client 目录中的代码只在客户机上运行。
  • 其他所有内容都在客户机和服务器上运行。
  • 在加载/lib 中的文件之前先加载其他文件。
  • 任何 main. * 文件都是在其他所有内容之后加载的。
  • 您的静态资产(字体、图像等)放在/public 目录中。

经过一段时间从流星编码,我很高兴有一些空闲时间致力于建立一个相当复杂的在线游戏。应用程序结构一直是我最关心的问题之一,而且看起来有几个非常优秀的程序员支持仅包构造应用程序的方法,这种方法允许您松散地耦合功能不同的包。这种方法还有其他优点,在这里可以找到解释这种方法的两篇非常好的文章:

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

对于每一个在谷歌上搜索这个话题的人:

em命令行工具(由 EventedMind 开发,是 Iron 路由器的开发者)在安装一个新的流星应用程序时非常有用。它将创建一个很好的文件/文件夹结构。如果你已经在开发一个应用程序并且想要重新组织它,只要用 em建立一个新的项目,你就可以用它来获得灵感。

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

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

创建包

当然,并不是所有的东西都适合这种方法,但是在大型应用程序中,你会有很多可以被隔离的功能。 任何可分离和可重用的东西都可以放在包中,其余的放在通常的目录结构中,正如其他答案中提到的那样。即使您不制作包来避免开销,以模块化的方式构造代码也是一个好主意(参见 这些建议)

Meetor 允许对如何加载文件(加载顺序,在哪里: 客户机/服务器/两者)以及包导出的内容进行细粒度控制。

我尤其发现在相关文件之间共享逻辑的简单方法非常方便。例如,您想创建一些 util 函数并在不同的文件中使用。您只需将其设置为“全局”(没有 var) ,并且 Meteor 将其包装在包的名称空间中,这样它就不会污染全局名称空间

这是官方文件

事件意识上有一个名为 建立流星项目的新类解决了这个问题,但也讨论了项目配置和设置开发环境。

来自课堂上的 申请结构视频: “流星”对于你的应用程序应该如何结构化没有很强的意见,但是这里有一些规则:

1)加载顺序-“流星”首先到达文件目录中最深的位置,然后在字母顺序中处理文件

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

我们的结构是这样的:

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

我按照亚光模板格式,其中已经包括铁路由器和模型(集合2)。见下文:

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

使用铁-氯脚手架 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

我们有一个大型项目(可能是迄今为止任何人建造的最大的流星项目之一,因为它是在全职开发了1.5年)。我们在每个视图中使用相同的文件名集。它非常一致,并帮助我们快速导航到我们正在寻找的东西:

  • 大事件
  • Helpers.js
  • Html
  • 路线: js
  • 风格,更少
  • 等等。

在一个项目中看起来像这样:



       ├── consolidationRequests
       │   ├── events.js
       │   ├── helpers.js
       │   ├── routers.js
       │   └── templates.html
       ├── customerSpoof
       │   └── routers.js
       ├── dashboard
       │   ├── events.js
       │   ├── helpers.js
       │   ├── onDestroyed.js
       │   ├── onRendered.js
       │   ├── routers.js
       │   └── templates.html
       ├── emailVerification
       │   ├── events.js
       │   ├── helpers.js
       │   ├── routers.js
       │   └── templates.html
       ├── loading
       │   ├── styles.css
       │   └── templates.html
       ├── mailbox
       │   ├── autoform.js
       │   ├── consolidationRequestConfirmation
       │   │   ├── events.js
       │   │   ├── helpers.js
       │   │   ├── onCreated.js
       │   │   ├── onRendered.js
       │   │   └── templates.html
       │   ├── events.js
       │   ├── helpers.js


相关的模板只是存储在同一个文件中:

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


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


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


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

当视图由很多部分组成变得复杂时,我们使用子文件夹:

       ├── cart
       │   ├── addItem
       │   │   ├── autoform.js
       │   │   ├── events.js
       │   │   ├── helpers.js
       │   │   ├── onRendered.js
       │   │   ├── routers.js
       │   │   ├── styles.less
       │   │   └── templates.html
       │   ├── checkout
       │   │   ├── autoform.js
       │   │   ├── events.js
       │   │   ├── helpers.js
       │   │   ├── onRendered.js
       │   │   ├── routers.js
       │   │   └── templates.html
       │   └── view
       │       ├── 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
       │       ├── styles.less
       │       └── templates.html

我们还开发与 WebStorm,一个极其强大和灵活的编辑器流星开发。我们发现在搜索和组织代码并高效工作时,它非常有帮助。 Webstorm view

欢迎提供详细信息。

我也在寻找最佳实践,通过一个构思良好的架构来增强和扩展我的应用程序。上面提到的所有实践都适用于中小型应用程序,但是如果你在一个更大的团队中工作,它们就会失败。我试过几种方法:

1)我遵循这样的策略: https://github.com/aldeed/meteor-autoform扩展和重用模板。作者对构件和现场设计有很好的认识。我目前正在实现它,因为社区开发了36个包,几乎涵盖了每个案例,我可以使用 打字机在开发阶段的类型安全。

<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)这个看起来很有前途,但是最近还没有更新。这是一个包写在咖啡脚本所谓的。Blaze 组件(https://github.com/peerlibrary/meteor-blaze-components)是一个可以轻松开发复杂 UI 元素的系统,这些元素需要在你的应用程序中重复使用。您可以在 CoffeeScript、普通 JavaScript 和 ES6中使用它们。最好的事情是,组件是面向对象的。下面是他们的一个例子:

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 来处理陨石,发现了以下存储库: 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) 流星-模板-延伸——提供各种方式在模板之间复制模板助手、事件处理程序和钩子,允许代码重用; 缺点是所有的复制都必须由开发人员进行,而且这种复制往往一次又一次,随着代码库的增长,这就成了问题; 此外,如果没有一个明确定义的 API 社区,就无法构建和共享组件

6) 流动元件-流组件在 API 设计中更接近于 React,而 火焰组件保留了熟悉的概念,如数据上下文和模板助手; 另一方面,流组件仍然使用基于模板的事件处理程序,而 Blaze 组件使它们成为类方法,因此更容易通过继承来扩展或覆盖它们; 总的来说,Blaze 组件似乎更面向 OOP; 流组件还没有正式发布(文本积分 # 5和 # 6 < a href = “ https://github.com/peerlibrary/meteor-fire- 成分 # javascript-and-es6-support _”rel = “ nofollow”> https://github.com/peerlibrary/meteor-blaze-components#javascript-and-es6-support )

2号和3号也需要一些使用,但是随着时间的推移,你将获得开发速度。第四项允许您构建和测试组件,以使代码更加稳定。第三个优势是完全类型安全的 Type 脚本,当您在一个文档较差的团队中进行开发时,这是一个巨大的优势。然而,我目前正在将第二个移植到 TypeScript,因为我觉得使用它非常舒服,而且当我不使用 Gulp 的时候,我不需要调整编译器包来使它能够与 Meetor 一起工作。

现在仍然很难找到正确的方式与流星合作。你需要自己弄清楚,否则你会得到一个很好的文件夹结构,但是你不知道所有的东西都在哪里。编程愉快。