在所有示例(排行榜、文字游戏等)中,它们只有一个 HTML 模板文件。是否有一些包含许多不同 HTML 模板文件的大型开源 Meteor 项目,我们可以将其用作最佳实践示例?将大型应用程序所需的所有内容都放在一个模板文件中似乎不切实际。
14 回答
正如在非官方的流星常见问题解答中一样,我认为它几乎解释了如何构建大型应用程序:
我应该把我的文件放在哪里?
流星中的示例应用程序非常简单,并没有提供太多洞察力。这是我目前对最佳方法的想法:(非常欢迎任何建议/改进!)
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
了解更多:非官方 Meteor 常见问题解答
我同意 yagooar,但不是:
客户端/application.js
采用:
客户端/main.js
main.* 文件最后加载。这将有助于确保您没有任何加载顺序问题。有关更多详细信息,请参阅 Meteor 文档http://docs.meteor.com/#structuringyourapp。
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
我希望一些更具体的最佳实践结构和命名约定确实会出现。
把它放在一起!从文档:
> 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.
对于所有在谷歌上搜索这个主题的人:
命令行工具(由 Iron Router 背后的em
人 EventedMind 提供)在装配新的 Meteor 应用程序时非常有用。它将创建一个不错的文件/文件夹结构。如果您已经在开发一个应用程序并想要重新组织它,只需设置一个新项目,em
您就可以使用它来获得灵感。
我认为 Discover Meteor Book 的文件结构非常好,是一个良好的开端。
/app:
/client
main.html
main.js
/server
/public
/lib
/collections
- /server 目录中的代码仅在服务器上运行。
- /client 目录中的代码仅在客户端上运行。
- 其他一切都在客户端和服务器上运行。
- /lib 中的文件在其他任何内容之前加载。
- 任何 main.* 文件都会在其他所有内容之后加载。
- 您的静态资产(字体、图像等)位于 /public 目录中。
创建包
当然,并非所有东西都适合这种方法,但在大型应用程序中,您将拥有许多可以隔离的功能。任何可分离和可重用的东西都适合包,其余的都放在通常的目录结构中,如其他答案中所述。即使您不制作包以避免开销,以模块化方式构建代码也是一个好主意(请参阅这些建议)
Meteor 允许对如何加载文件(加载顺序,其中:客户端/服务器/两者)以及包导出的内容进行细粒度控制。
我特别发现在相关文件之间共享逻辑的简单方法非常方便。比如说,你想做一些 util 函数并在不同的文件中使用。您只需将其设为“全局”(没有var
),Meteor 会将其包装在包的命名空间中,因此它不会污染全局命名空间
这是官方文档
经过一段时间的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 -图案
我们有一个大型项目(可能是迄今为止最大的 Meteor 项目之一,因为它已经进行了 1.5 年的全时开发)。我们在每个视图中使用相同的文件名集。它非常一致,可以帮助我们快速导航到我们正在寻找的内容:
- 事件.js
- helpers.js
- 模板.html
- 路由.js
- 样式.less
- 等等
在项目中看起来像这样:
├── 合并请求 │ ├── events.js │ ├── helpers.js │ ├── routers.js │ └── templates.html ├── customerSpoof │ └── routers.js ├── 仪表板 │ ├── events.js │ ├── helpers.js │ ├── onDestroyed.js │ ├── onRendered.js │ ├── routers.js │ └── templates.html ├── 邮箱验证 │ ├── events.js │ ├── helpers.js │ ├── routers.js │ └── templates.html ├── 加载中 │ ├── styles.css │ └── templates.html ├── 邮箱 │ ├── autoform.js │ ├──solidationRequestConfirmation │ │ ├── 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 │ │ ├── styles.less │ │ └── 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 │ ├── styles.less │ └── templates.html
我们还使用 WebStorm 进行开发,这是一款用于 Meteor 开发的极其强大且灵活的编辑器。在搜索和组织我们的代码以及高效工作时,我们发现它非常有用。
很高兴应要求分享详细信息。
使用 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
我正在遵循 mattdeom 样板格式,其中已经包含了 Iron router & Model (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
有很多不同的方法来构建你的应用程序。例如,如果您有一个路由器和不同的页面模板,并且在每个页面模板内部您有许多页面部分等等,我将根据更高级别> 更低级别的语义来构建它。
例如:
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 文件.. :)
我希望它有点帮助
Evented Mind上有一个名为“设置 Meteor 项目”的新课程,它解决了这个问题,但也讨论了项目配置和设置开发环境。
来自课堂上的应用程序结构视频: Meteor 对应用程序的结构没有非常强烈的意见,但这里有一些规则:
1)加载顺序——Meteor先到文件目录最深处,按字母顺序处理文件
2) client 和 server 是 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 扩展了 Iron Router 附带的 RouteController。
上面提到的em
工具现在也得到了很大的更新,应该会更好,并且可以在:https ://github.com/EventedMind/em
我还在寻找最佳实践,以通过精心构思的架构来增强和扩展我的应用程序。上述所有做法都适用于中小型应用程序,但当您在更大的团队中工作时会失败。我尝试了几种方法:
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、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)流组件——流组件在 API 设计中更接近 React,而Blaze 组件保留了熟悉的概念,如数据上下文和模板助手;另一方面,流组件仍然使用基于模板的事件处理程序,而 Blaze 组件使它们成为类方法,因此更容易通过继承扩展或覆盖它们;一般来说,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 的正确方法。您需要自己弄清楚,否则您最终会得到一个排列良好的文件夹结构,但您不知道所有内容都在哪里。快乐编码。