用许多HTML模板文件构build大型Meteor应用程序的最佳实践是什么?
在所有的例子(排行榜,文字游戏等),他们有一个单一的HTML模板文件。 是否有一些大型的开源Meteor项目,我们可以使用许多不同的HTML模板文件作为最佳实践示例? 将一个大型应用程序需要的所有内容全部放在一个模板文件中似乎并不实际。
把它们一起整理! 从文档:
> 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.
就像在非官方的meteor常见问题解答中,我想这非常解释了如何构build一个大型应用程序:
我应该把我的文件放在哪里?
meteor中的示例应用程序非常简单,并没有提供太多的见解。 以下是我目前正在考虑的最佳方式:(非常欢迎任何build议/改进!)
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)
对于更大的应用程序,可以将分散的function分解成使用相同模式组织的子目录。 这里的想法是,最终function模块可以被分解成单独的智能包,并且理想地共享。
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的devise使您可以以任何您想要的方式构build您的应用程序。 所以如果你不喜欢你的结构,你可以把一个文件移动到一个新的目录中,甚至把一个文件分成几块,meteor几乎都是一样的。 请注意主要文档页面中指定的客户端,服务器和公共目录的特殊处理: http : //docs.meteor.com/ 。
把所有东西一起放在一个HTML填充中肯定不会成为最佳实践。
这里有一个可能的结构的例子:在我的一个应用程序,一个论坛,我按模块或“页面types”(家庭,论坛,主题,评论),把每个.css,.html和.js文件页面types放在一个目录中。 我也有一个“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
你也可以按function组织
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
我希望能够出现一些更具体的最佳实践结构和命名约定。
对于每个使用Googlesearch这个主题的人来说:
em
命令行工具(由EventedMind,铁路路由器背后的人)在安装新的Meteor App时非常有用。 它会创build一个不错的文件/文件夹结构。 如果您已经在应用程序上工作并想要重新组织它,只需使用em
创build一个新项目,然后就可以使用它来获得灵感。
请参阅: https : //github.com/EventedMind/em
在这里: https : //stackoverflow.com/questions/17509551/what-is-the-best-way-to-organize-templates-in-meteor-js
我认为发现meteor书的文件结构是一个很好的开始。
/app: /client main.html main.js /server /public /lib /collections
- / server目录中的代码只能在服务器上运行。
- / client目录中的代码只能在客户端上运行。
- 其他的一切都在客户端和服务器上运行。
- 在/ lib之前的文件加载之前。
- 任何主要的。*文件被加载后的一切。
- 你的静态资产(字体,图片等)进入/ public目录。
创build包
当然,并不是所有的东西都适合这种方式,但是在大型应用程序中,你将会拥有很多可以被隔离的function。 任何可分离和可重用的东西都可以放在软件包中,其余的放在通常的目录结构中,就像其他答案中提到的一样。 即使你不打包来避免开销,以模块化的方式构build代码是一个好主意(请参阅这些build议 )
meteor允许对如何加载文件(加载顺序,其中:客户端/服务器/两者)以及软件包导出的方式进行精细控制。
我特别发现非常方便的方式来共享相关文件之间的逻辑。 比如说,你想做一些util函数,并在不同的文件中使用。 你只要把它设置成“全局的”(没有var
),Meteor就会把它包装在包的名字空间中,所以它不会污染全局的名字空间
这是官方文件
从meteorjs编码的一段时间,我很高兴有一些空闲时间致力于build设一个相当复杂的在线游戏。 应用程序结构一直是我最关心的问题之一,看起来好几个非常优秀的程序员都支持构build应用程序的仅包方法,它允许您松散地耦合function不同的包。 这种方法还有其他的好处,并且可以在这里find2个很好的解释方法的文章:
http://www.matb33.me/2013/09/05/meteor-project-structure.html http://www.manuel-schoebel.com/blog/meteorjs-package-only-app-structure-with-mediator -模式
我们有一个很大的项目(可能是迄今为止任何人都已经build成的最大的Meteor项目之一,因为它在1.5年的全职开发中)。 我们在每个视图中使用相同的一组文件名。 这是非常一致的,并帮助我们快速导航到我们正在寻找的东西:
- events.js
- helpers.js
- templates.html
- routes.js
- styles.less
- 等等
在一个项目中看起来像这样:
├──合并请求 │├──events.js │├──helpers.js │├──routers.js │└──templates.html ├──顾客欺骗 │└──routers.js ├──仪表板 │├──events.js │├──helpers.js │├──onDestroyed.js │├──onRendered.js │├──routers.js │└──templates.html ├──电子邮件validation │├──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 ││├──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编辑器。 当search和组织我们的代码并且高效地工作时,我们发现它非常有帮助。
很高兴分享要求的细节。
我正在遵循已经包括铁路由器和模型(Collection2)的mattdeom样板格式。 见下文 :
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
使用iron-cli脚手架CLI。 是否让事情变得非常简单
https://github.com/iron-meteor/iron-cli
一旦安装。 使用iron create my-app
来创build一个新的项目。 它会为您创build以下结构。 你也可以在现有的项目上使用它。 在项目目录中使用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
有很多不同的方法来构build你的应用程序。 例如,如果你有一个路由器和不同的页面模板,并且每个页面的内部模板有很多页面部分等等,我会根据更高>更低级别的语义来构造它。
例如:
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 ...
当然,你可以把你的新闻模板放在公共文件夹中,因为你可以在不同的页面上使用你的新闻模板。
我认为这是你用最舒服的方式构build你的应用的最好方式。
我在这里写了一个小应用程序: http : //gold.meteor.com它是如此之小,我只使用一个HTML文件,只有一个template.js文件.. 🙂
我希望它有一点帮助
在Evented Mind上有一个新的课程叫做Setting Meteor Projects来解决这个问题,同时也讨论了项目configuration和build立你的开发环境。
从课堂上的应用程序结构video: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
我也在寻找最佳实践,通过一个devise良好的架构来增强和扩展我的应用程序。 以上提到的所有实践都适用于中小型应用程序,但是当您在一个更大的团队中工作时,这些应用程序会失败。 我尝试了几种方法:
1)我遵循这个策略: https : //github.com/aldeed/meteor-autoform来扩展和重用模板。 作者对组件和现场devise有很好的想法。 我目前正在实施它,因为社区开发了几乎涵盖所有情况的36个包,我可以在开发阶段使用TypeScript进行types安全。
<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 /读/ Blaze_Notes
2)这个看起来很有希望,但最近没有更新。 这是一个用咖啡脚本编写的软件包。 Meteor的Blaze Components( 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)我喜欢types和transpiler,告诉我什么时候会出错。 我正在使用TypeScript来处理meteor,并find以下存储库: https : //github.com/dataflows/meteor-typescript-utils它似乎创build者试图完成一个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社区不能build立和共享组件
6) stream程组件 – stream程组件在APIdevise中更接近React,而Blaze组件则保持熟悉的概念,如数据上下文和模板助手; 另一方面,Flow组件仍然使用基于模板的事件处理程序,而Blaze组件使它们成为类方法,以便通过inheritance来扩展或覆盖它们; 一般Blaze组件似乎更多的面向对象; stream组件还没有正式发布( #5和#6文本信用https://github.com/peerlibrary/meteor-blaze-components#javascript-and-es6-support )
2号和3号也需要使用一些,但是随着时间的推移,你将获得发展速度。 第四个可以让你构build和testing组件,使你的代码更稳定。 第三个版本具有TypeScript全面安全的优势,当你在一个文档不佳的团队中开发时,这是一个巨大的优势。 不过,我现在正在将Type 2移植到TypeScript,因为我感觉使用它非常舒服,而且在不使用Gulp时,我不必为编译器包使用Meteor而使用它。
目前还很难find与meteor合作的正确方法。 你需要为自己弄清楚,否则你会得到一个安排得很好的文件夹结构,但是你不知道一切在哪里。 快乐的编码。