如何在有许多HTML模板文件的大型Meteor应用程序中进行最佳结构化实践?

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

Meteor是新的东西,我还没有找到任何相关的最佳实践。我也期望有一些关于这方面的指导。 - newlife
10
你是否阅读了手册中 应用程序结构 部分的内容?其中有关于扫描和连接HTML文件的一些解释。 - zwippie
1
Meteor官方指南建议使用非常酷的文件结构。请查看此处: https://guide.meteor.com/structure.html#javascript-structure - Waqas
14个回答

275

就像在非官方的Meteor FAQ中所述,我认为它基本上解释了如何构建一个大型应用程序:

Where should I put my files?

The example apps in meteor are very simple, and don’t provide much insight. Here’s my current thinking on the best way to do it: (any suggestions/improvements are very welcome!)

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)

For larger applications, discrete functionality can be broken up into sub-directories which are themselves organized using the same pattern. The idea here is that eventually module of functionality could be factored out into a separate smart package, and ideally, shared around.

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 常见问题解答


12
在我看来,这比被接受的答案更好。我现在会尝试一下。 - hakan
17
从0.6.0版本开始,您最好避免混乱并完全使用智能包来运行您的应用程序。我在这篇博客文章中详细讲解了一些细节:http://www.matb33.me/2013/09/05/meteor-project-structure.html - matb33
1
有人知道在哪里放置 mobile-config.js 文件吗? - Dude
1
谢谢你的回答和提供非官方常见问题解答链接(我是 Meteor 的新手),"common code from someone else" 是什么意思?谢谢! - Cohars
3
关于 Meteor 1.3,我认为它已经过时了,主要是因为 ES6 模块引入的原因。请参阅 Meteor 指南中关于应用程序结构的文章:https://guide.meteor.com/structure.html。 - Samuel
显示剩余5条评论

36

我同意yagooar的观点,但是不是用:

client/application.js

而是用:

client/main.js

main.*文件会最后被加载。这将有助于确保您没有任何加载顺序问题。有关更多详细信息,请参见Meteor文档http://docs.meteor.com/#structuringyourapp


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
我喜欢这个答案。我一直都是用第一种方法。 - mc9
相关的事物应该靠近彼此。我的答案与你的相似,但是颠倒过来了。 - ChatGPT
1.3 弃用了 zapped lib,采用 imports。https://guide.meteor.com/structure.html#example-app-structure - Jeremy Iglehart
我认为给多个文件都命名为“topic”这样的特征名称没有意义。如果你想要将特征名称更改为“category”,那么你就必须更改多个文件名。只需将它们组织在一个名为“topic”的单个文件夹下,并以通用的方式进行命名:events.js、views.html、styles.css、routes.js等等。请查看我的答案获取更多信息。 - ChatGPT

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的客户端代码。这对于许多网站来说是不可接受的。我们将尝试在主屏幕加载后分批次进行加载,但我现在持怀疑态度。我认为需要一个功能来分解内容。 - Dave Sanders
36
这个回答是谷歌搜索排名第一,但它很可能过时了。像我这样的其他未来访问者,请往下看! - Kloar
截至1.1.0.2版本,他们演示的简单待办事项应用在浏览器缓存被清除并进行硬刷新时会传输1.7MB的文件。这对于许多使用情况来说是不可接受的。:/一旦资产被缓存,情况就会得到很大改善,但在第一次加载时,情况相当严峻。 - Jason Kim
想法:使用webpack,为各种东西制作捆绑包,在需要时进行延迟加载。 - trusktr
Asana需要一些时间来加载。Asana是一个非常出色、反应迅速的应用程序,用户在2014年创建了1.75亿个任务。加载更快的应用程序并不总是更好。应用程序在您的手机上启动也需要一点时间。人们会习惯的。 - ChatGPT
显示剩余4条评论

14

对于所有在谷歌上搜索这个主题的人:

em命令行工具(由EventedMind开发,是Iron Router背后的团队)在设置新的Meteor App时非常有帮助。它将创建一个漂亮的文件夹结构。如果你已经在一个应用程序上工作并且想要重新组织它,只需使用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(同一作者)。请查看:https://github.com/iron-meteor/iron-cli - j0e
是的,“em”已经更名为iron-cli,是同一个工具。 - Mikael Lirbank

11

我认为《探索 Meteor》这本书的文件结构非常好,是一个很好的起点。

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

10

创建包

当然,不是所有的东西都适用于这种方法,但在大型应用程序中,您将拥有许多可被隔离出来并可重复使用的功能。任何可分离和可复用的东西都适合放在包中,其余的则按照其他回答中提到的常规目录结构进行处理。即使您不制作包以避免开销,以模块化方式组织代码也是一个好主意(请参见这些建议)。

Meteor允许对文件加载进行细粒度控制(加载顺序、位置:客户端/服务器/两者等)以及包导出的内容。

我尤其发现在相关文件之间共享逻辑非常方便。例如,您想要创建一些实用函数并在不同的文件中使用。您只需在全局范围内(不加var)定义它,Meteor将把它包装在包的命名空间中,因此它不会污染全局命名空间。

这里是官方文档。


6

经过一段时间的meteorjs编码之后,我很高兴有些空闲时间来致力于构建一个相当复杂的在线游戏。应用程序结构是我的首要关注点之一,看起来有几位非常优秀的程序员倡导了仅使用包来构建应用程序的方法,这使您能够松散地耦合功能上不同的包。该方法还有其他优点,并且可以在这里找到两篇解释该方法的非常好的文章:

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


6
我们有一个大型项目(可能是迄今为止建立的最大Meteor项目之一,因为它全职开发了1.5年)。我们在每个视图中使用相同的文件名集。这非常一致,并帮助我们快速导航到我们正在寻找的内容:
- events.js - helpers.js - templates.html - routes.js - styles.less - 等等
在项目中看起来像这样:
├── 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
相关的模板只需存储在同一个文件中。此处折叠了view/order/checkout/templates.html的内容:
<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进行开发,这是一个非常强大和灵活的Meteor开发编辑器。我们发现在搜索和组织代码以及高效地工作时,它非常有帮助。 Webstorm view 如需详细信息,请随时联系我们。

3
如果您认为这个答案有所改进,请考虑添加一条评论。 - ChatGPT
我们喜欢Meteor并且所有新的开发工作都在它上面进行。不幸的是,我对LoopBack或Happi不够熟悉,无法发表任何意见。 - ChatGPT
1
LoopBack 关注于端到端的 REST API,使其听起来像传统的 Web 开发框架(如 RoR)。RoR 已经正确实现了 REST API,但我们认为 Meteor 正确实现了实时功能。 - ChatGPT
谢谢您的反馈。您也为功能组织了服务器端吗? - Liko
市场上有很多样板可以使用。大多数用户更喜欢按照自己的方式进行。也有人做了艰苦的工作:https://medium.com/things-i-did-and-learned-today/in-search-of-a-meteor-boilerplate-6f01fe5abfd1#.36yaa0wjq - Shivam Bajpai
显示剩余2条评论

5

使用 iron-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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接