前端进阶(三)前端模块化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014744118/article/details/80846028

什么是模块化?

模块化开发是一种管理方式,是一种生产方式,一种解决问题的方案。他按照功能将一个软件切分成许多部分单独开发,然后再组装起来,每一个部分即为模块。当使用模块化开发的时候可以避免刚刚的问题,并且让开发的效率变高,以及方便后期的维护。

模块化主要解决:命名冲突(变量和函数命名可能相同),文件依赖(引入外部的文件数目、顺序问题)等。

一、ES5及ES5之前如何模块化?

要回答这个问题,首先先了解几个概念。

通行的JavaScript模块规范主要有三种:CommonJS、AMD和CMD。

(1)CommonJS

2009年,美国软件工程师Ryan Dahl创造了node.js项目,将javascript语言用于服务器端编程。这标志"Javascript模块化编程"正式诞生。因为老实说,在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程。NodeJS是CommonJS规范的实现,webpack 也是以CommonJS的形式来书写。

Common.js优点在于:

1.CommonJS模块规范很好地解决变量污染问题,每个模块具有独立空间,互不干扰,命名空间等方案与之相比相形见绌。

2.CommonJS规范定义模块十分简单,接口十分简洁。

3.CommonJS模块规范支持引入和导出功能,这样可以顺畅地连接各个模块,实现彼此间的依赖关系。

但是CommonJS规范不适用于浏览器环境。原因是缺少四个Node.js环境的变量:module/exports/require/global,并且是同步的(意味着在浏览器中会阻塞),CommonJS是主要为了JS在后端的表现制定的,它是不适合前端的

只要能够提供这四个变量,浏览器就能加载 CommonJS 模块。Browserify 是目前最常用的 CommonJS 格式转换的工具,虽然 Browserify 很强大,但不能在浏览器里操作。

解决思路:

一是开发一个服务器端组件,对模块代码作静态分析,将模块与它的依赖列表一起返回给浏览器端。 但需要服务器安装额外的组件,并因此要调整一系列底层架构。

二是用一套标准模板来封装模块定义,但是对于模块应该怎么定义和怎么加载,又产生的分歧,分成了两个思路:AMD和CMD。

(2)AMD 

AMD即Asynchronous Module Definition(AMD wiki中文版),中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范。由于AMD不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎RequireJS,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出。目前,主要有两个Javascript库实现了AMD规范:require.jscurl.js

本人只用过require.js,所以简单可以谈谈require.js。

它的优势主要在于异步模块化加载js文件,并且能很好的管理js文件的依赖关系。主要思想就是将页面用到的js全部异步加载。

1.实现js文件的异步加载,避免网页失去响应;

2.管理模块之间的依赖性,便于代码的编写和维护。

require.js要求,每个模块是一个单独的js文件。这样的话,如果加载多个模块,就会发出多次HTTP请求,会影响网页的加载速度。因此,require.js提供了一个优化工具,当模块部署完毕以后,可以用这个工具将多个模块合并在一个文件中,减少HTTP请求数。虽然require.js是基于AMD规范的,但是也可以加载非AMD规范的js文件。

(3)CMD

CMD 即Common Module Definition通用模块定义,CMD规范是国内发展出来的,就像AMD有个require.js,CMD有个浏览器的实现sea.js,sea.js要解决的问题和require.js一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。

阿里大神玉伯写了sea.js,就是遵循他提出的CMD规范,与AMD非常相近,核心思想就是按需加载,不会等待较长时间。腾讯阅文集团的张鑫旭大神维护的seajs文档

SeaJS与RequireJS最大的区别

豆瓣上面这个答案说的比较好:SeaJS对模块的态度是懒执行, 而RequireJS对模块的态度是预执行。

二、ES6模块化

EcmaScript6 标准增加了JavaScript语言层面的模块体系定义。

在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。

目前很少JS引擎能直接支持 ES6 标准,因此 Babel 的做法实际上是将不被支持的import翻译成目前已被支持的require。区别于Common.js,ES6中的模块不是对象,采用‘编译时加载’,效率比前者高。

待续。。。

---------------------------------------------------------------------------------------------------------------------------------

注:有部分摘自大牛原话,本人只是为了学习方便做的笔记,如有侵权,联系必删。

猜你喜欢

转载自blog.csdn.net/u014744118/article/details/80846028