Meteor Mantra 介绍(二)- 前端架构详解

Meteor Mantra 系列文章:

Meteor Mantra 介绍(一)- 基本概念
Meteor Mantra 介绍(二)- 前端架构详解
Meteor Mantra 介绍(三)- 后端架构解释
Meteor Mantra 介绍(四)- 博客例子前端代码解读
Meteor Mantra 介绍(五)- 博客例子后端代码解读
Meteor Mantra 介绍(六)- 使用 mantra-cli 命令行生成源码


Mantra logo

注意,Meteor 1.3 后 Meteor 可以使用 .js 支持 jsx 语法,就是 js 函数里也可以有 HTML tag 了。所以建议就算是 JSX 也使用 .js 做文件后缀

上一篇 Meteor Mantra 介绍 主要是讲了 Mantra 的特点和主要构成,比较抽象,这一次是说说它的具体文件结构,希望可以帮助大家理解 Mantra 的更多细节,以及如何应用。

还有上一篇漏了一个 Routing & Component Mounting 模块。在 Mantra 里,Router 的作用是把组件组装到 UI,组件可以是 container 容器或者 UI 组件。换句话说,Router 就是把我们写的一个个页面组件组合到一起,然后根据用户在浏览器里输入的路径和参数从服务器端获取数据,并调用显示不同的组件。

有两个 Router 开源库可以选用, flow-routerreact-router 。我用 flow-router。

import React from 'react';
import {FlowRouter} from 'meteor/kadira:flow-router';
import {mount} from 'react-mounter';

import MainLayout from '/client/modules/core/components/main_layout.jsx';
import PostList from '/client/modules/core/containers/postlist';

export default function (injectDeps) {
  const MainLayoutCtx = injectDeps(MainLayout);

  FlowRouter.route('/', {
    name: 'posts.list',
    action() {
      mount(MainLayoutCtx, {
        content: () => (<PostList />)
      });
    }
  });
}

从上面代码可以看到,router 的作用就像在 Unix 里把一个硬盘添加到系统里一样,把一个 PostList 的组件添加 mount 到了应用里。

需要注意的是,如果需要重定向,最好使用 action 而不是 FlowRouter 的 triggersEnter。可以在 component 或者容器的 composer 函数里调用 action。

文件结构

建议对比这个 Mantra 例子 - 一个博客系统,来更好理解 Mantra 的文件结构。

所有 Mantra 相关的代码都在一个名为 client 的文件夹里。在这个 client 文件,又有两个文件夹和一个 JavaScript 文件

  • configs
  • modules
  • main.js

具体的文件可以见下图

mantra_client.png

下面来具体分析

configs

这里其实就是 Application Context,通常里面的文件命名为 context.js。它是整个应用的配置,可以被所有模块使用。

Application Context 是应用的核心,但不应该定义在任何模块里。所有其他模块都可以读 Application Context 但是不能写,不能修改。

modules

Mantra 使用的是模块化结构(这里的模块不是 ES2015 的模块,而是指结构上的模块,形式上就是一组 ES2015 exports 构成的一个文件夹,完成一个具体的功能)。除了 Application Context,所有的组件都是模块,然后使用 imports 调用。

这个文件夹至少得有一个名为 core 的文件夹。core module 是最先加载的。通常 core 里放

  • core routes
  • 应用配置
  • 通用 lib
  • 通用 actions
  • 其他整个应用分享的代码

一般 core 里就是核心代码,例如 routes。然后再把其他功能分散到其他的模块。当然其他模块也可以有自己的 routes。

不要使用子模块,因为会加入不必要的复杂度,增加维护难度。

通常一个模块再含有以下文件夹和文件

  • actions
  • components
  • configs
  • containers
  • libs
  • routes.js
  • index.js

下面是他们的具体作用。

actions

顾名思义,这里就是这个模块所有 actions。一般它有这样的结构

  • posts.js
  • index.js
  • tests
    • posts.js

posts.js 就是一个 action,它会输出(export)一个 JavaScript 对象。这个例子前面有讲到。

index.js 的作用是集成所有 actions,然后统一输出。目的是统一命名,解决 namespace 冲突的问题。

components

UI 组件所在处。文件通常有

  • main_layout.js
  • post.js
  • style.css
  • tests
    • main_layout.js
    • post.js

jsx 文件就是 React 代码。每个 jsx 文件应该有一个 default export,并且是一个 React 类。

containers

应该都是 .js 文件,每个文件是一个容器,输出一个 default 的 React Container 类。

configs

这里是模块级的配置。每个 js 文件输出一个缺省函数,这个函数的第一个参数通常就是 Application Context。

这里通常是 Meteor 的 method stubs 代码,目的是获得 optimistic updates 特性。如果不清楚这个概念可以看看相关资料。官方文档 https://guide.meteor.com/ui-ux.html#optimistic-ui 。简单来说就是在服务器确认、保存用户产生的信息前在客户端显示这些信息,让用户获得更好的体验。

libs

工具函数等辅助代码。可以是 .js 也可以是 .jsx 文件。

routes.jsx

见本文开头介绍。只是注意那个 injectDeps 参数。它的作用是在加载这个模块时注入依赖。

index.js

模块的定义文件

import methodStubs from './configs/method_stubs';
import actions from './actions';
import routes from './routes.jsx';

export default {
  routes,
  actions,
  load(context) {
    methodStubs(context);
  }
};

从上面的例子代码可以看到,它的作用是加载 routes、定义 actions 和初始化、配置上下文。如果不需要这三个功能,那么就用不着这个 index.js,不用定义文件。

main.js

Mantra app 的唯一入口。它初始化 application context,加载各个模块

import {createApp} from 'mantra-core';
import initContext from './configs/context';

// modules
import coreModule from './modules/core';
import commentsModule from './modules/comments';

// init context
const context = initContext();

// create app
const app = createApp(context);
app.loadModule(coreModule);
app.loadModule(commentsModule);
app.init();

注意这里使用到了 mantra-core 这个库来初始化 context 和加载模块。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容