从ng1看ng2 关于NgModule的简易归纳

写在前面

最近开始折腾ng2,其实说是ng2,到目前为止,它已经发布了4.3版,就是这么的高产,高产似*,我连2都还木有完整的看完它竟然发布了4.的版本(鄙视脸)。

不过话说回来,之前工作不忙的时候,想看看ng2的东西,我的天,又是ts,又是observable的,吓的我硬是没有上来就直接去看它的入门文档,而是买了本typescript的入门开始看,后来书看了一半,工作又忙了,就想着可否重构历史代码加顺带学习rxjs的姿势去做需求,后来我也是这么做的,庆幸的是,这么做效果是挺好的,不仅实际开发效率高了不少,同时也入门了rxjs。

最近工作又闲了下来,就想着赶紧带着半吊子的ts和rxjs水平看看ng2的文档吧,虽然ng2在国内似乎热度不如react和vue流行,但是在全世界还是劲头还是比较强劲的,毕竟有谷歌爸爸和微软爸爸做东,强强联合。

而且我是个遵守规则的人,一向喜欢大而全的东西,ng这种框架我觉的真的是很对我的胃口。不过这ng2的文档不看不要紧,一看真的是有些蛋疼,随便看个啥,连码代码加理解,估计一下午也就能看一个简单的概念,就比如今天想归纳的NgModule这部分东西,前后大概有30几页的东西,所以我觉的如果不写点东西总结一下,必然是看了就忘,忘了再看的节奏。

ng1中的module回顾

其实熟悉ng1的话,对于这ng2中的module的理解是很有帮助的。从ng1开始,就一直再提倡一个module的概念,比如

angular.module('baz', [])
angular.module('bar', [])
angular.module('foo', ['bar', 'baz'])
       .factory('fooFactory', function(){ ... })
       .service('fooService', function(){ ... })
       .component('fooComponent1', { ... })
       .directive('fooDirective', function(){ ... })

这么的我就分别声明了foobarbaz的module,同时foo依赖于bazbar,然后就没有然后了,之后你就可以在这个这些module中做一切你想做的任何事情。通过这种module的划分,我们可以在各个维度中,抽象我们的代码,比如从业务上、从代码类别上等等。

ng2中的module简述

ng2将这种概念更推进了一步,虽然我们可以使用module的方法来改变我们编程的思维,但是代码本身并不具有module的含义,这么说可能有点难理解,举个例子,就上面的例子,对于barbaz模块,我们很难简单的从代码层面来区分它们分别的职能是什么。因此ng2改用了以Decorator的方式来使代码具有语意性,如下

@NgModule({
  imports:      [ ... ],
  declarations: [ ... ],
  providers:    [ ... ],
  exports:      [ ... ]
})
export class FooModule { }

通过NgModule这个装饰器来对一个class进行描述。如果直接和ng1对比的话,装饰器的参数对象中的几个属性分别对应ng1中的:

  • imports: 对应ng1声明中的模块依赖数组['bar', 'baz'],进行一些依赖模块的声明
  • declarations: 对应ng1中的.component('fooComponent1', { ... }).directive('fooDirective', function(){ ... }),进行一些声明式类的声明
  • providers: 对应ng1中的.service('fooService', function(){ ... }).factory('fooFactory', function(){ ... }),进行一些服务类的声明
  • exports: ng1中没有独立的exports语法,因此不做对比,在ng1中只有依赖模块中提供的服务、模块,加载模块均可使用。

ng2中module分类

ng2对不同的module提供了不同的语意性描述方式,可以通过装饰器属性来描述它们。

root-module(根模块)

所谓根模块,即一个应用的最上层的模块,即应用的入口模块,有时候也会称作app-module(这也是文档中指出的最佳实践)。这个概念在ng1中同样有,但是和上面指出的问题一样,就是没有代码层面的语意性描述,为了更好的描述它,ng2中的root-module会提供额外的装饰器属性来修饰它

@NgModule({
  ...,
  bootstrap:      [ ... ]
})
export class AppModule { }

这个bootstrap代表这个模块会在应用初始化阶段被引导和加载,一般来讲,ng2都会有一个独立的main.ts文件来引导加载根模块,这个过程对于根模块是透明的,因为它并不知道它如何被加载,有可能是在浏览器加载,有可能是在移动端加载等等,有可能使用JIT做动态加载,有可能提前编译好做静态加载,这些都是未知的,它仅仅需要表达的是,这个模块是可被引导加载的。通常情况下,一个应用只有一个root-module(这不是废话吗),但是在一些大型的应用中,可能会存在多个独立的子项目,那么就有可能存在多个root-module。

sub-module(子模块)

所谓子模块,即一个应用从属于根模块的模块,即应用按各个维度划分形成的颗粒,比如从功能划分、代码架构划分等等,有时候也会称作feature-module(这也是文档中指出的最佳实践),ng1同样无法在代码层面进行语意性描述。

一般来讲,只要符合ng2中的module简述中的模块声明方式声明的模块,就是一个feature-module,它具有什么样的feature,完全取决于它提供什么样的声明式组件和服务。对于不同的feature,如服务、指令和组件会以其他的装饰器进行修饰和声明,这不是本篇文章的内容,我们只需要知道,一个feature-module负责声明和管理它提供的服务和声明式组件。值得一提的是,和ng1不同,ng2中的feature-module可以声明一些私有的组件和服务,这一点在ng1中时做不到的。

core-module(核心模块)

核心模块其实本质上讲,即是feature-module,只不过它提供的声明式组件和服务,是基于app本身构建的。言外之意,就是它必须是单例的,比如像登录验证这种服务,就是一种全局性的、app级别的服务,再入导航、顶部条等组件,也是app级别的组件,这些东西应该归并到core-module中,并在app-module中加载它,而坚决不要在feature-module中加载它。

share-module(共享模块)

共享模块也是feature-module,只不过它提供的声明式组件和服务,是从各个feature-module中提取出的公共组件和服务,在官方的例子中,高亮这个指令,就是一个公用的指令,并不依赖于任何独立的业务逻辑。这些东西应该归并到share-module中,并在各个feature-module中加载它,从而使得我们的代码尽可能的保持简洁。

lazy-load-module(懒加载模块)

对于SPA来讲,路由是必不可少的东西。那么对于一些未使用页面所加载的模块,我们没有必要从一开始就加载它们,很自然的,它们就成为了懒加载模块,这些模块本质上讲均是feature-module,因为core-module和share-module从职能来讲,在整个的应用生命周期,尤其初始化必不可少,因此它们很少成为懒加载模块。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Linux 的 OOM 终结者

现在是早晨6点钟。已经醒来的我正在总结到底是什么事情使得我的起床闹铃提前了这么多。故事刚开始的时候,手机铃声恰好停止。又困又烦躁的我看了下手机,看看是不是我自己...

46560
来自专栏Vamei实验室

Linux文本流

我之前已经用文本编辑器修改过文本。现在,我们要深入理解所谓的“文本”。 文本流 在计算机中,所谓的数据就是0或1的二进制序列,但严格来说,Unix以字节(byt...

28190
来自专栏数据小魔方

扒一扒rvest的前世今生!

rvest包可能是R语言中数据抓取使用频率最高的包了,它的知名度和曝光度在知乎的数据分析相关帖子和回答中都很高。 甚至很多爬虫教程和数据分析课程在讲解R语言网络...

40470
来自专栏听雨堂

【2】快速代码集的由来及概览

喜爱编程,尽管编程开发并非自己的主要工作,但多年来,也一直没有间断开发。既有工作单位的一些项目,也有纯粹自己的一些想法而做的程序(我的原创)。在使用C#开发各类...

20450
来自专栏企鹅号快讯

反编译对于黑客技术的帮助有多大

目前很多技术都被涉及了,也有很多的技术被挖掘出来,但是很多人对技术不是这么了解的,可能会吃亏,比如说目前挺火的黑客技术还有反编译技术都是属于很多了解却不是这么熟...

398110
来自专栏极客生活

从计算机体系结构到高性能编程实践(一)

上来先推荐一本书,《计算机体系结构:量化研究方法(第五版)》,英文能力比较好的建议阅读原版。

13020
来自专栏Kirito的技术分享

天池中间件大赛百万队列存储设计总结【复赛】

维持了 20 天的复赛终于告一段落了,国际惯例先说结果,复赛结果不太理想,一度从第 10 名掉到了最后的第 36 名,主要是写入的优化卡了 5 天,一直没有进展...

25030
来自专栏王清培的专栏

数据分表小结

本次拆分主要包括订单和优惠券两大块,这两块都是覆盖全集团所有分子公司所有业务线。随着公司的业务飞速发展,不管是存储的要求,还是写入、读取的性都基本上到了警戒水位...

12400
来自专栏程序员互动联盟

程序语言变形记

随着科技的发展我们生活中接触到的应用程序越来越多,它给我们的生活带来了很大的便利。移动端安卓,苹果大肆横行;pc上QQ,浏览器大行天下。我们在享受这些软件给我们...

34550
来自专栏黑泽君的专栏

Java的日期类的时间从为什么是从1970年1月1日开始?

----------------------------------------------------------------------------- I ...

1.3K20

扫码关注云+社区

领取腾讯云代金券