-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Javascript前端模块化 #7
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
1. 什么是模块化
模块化是将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并组合在一起。块(文件)的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信。
在没有模块化之前,前端将不同的功能封装到不同的全局函数中,如下:
那么带来的问题就是:
为了解决这个问题,出现了namespace模式,如下:
但是以上方法仍然存在问题: 数据不安全。例如,可以直接修改里面的data
为了解决这个问题,出现了IIFE(Immediately-invoked function expression 立即执行函数表达式)模式,如下:
由于module中的data没有暴露,所以是不可修改的,代码myModule.data只会在window.myModule这个对象上新增一个data的属性。
但是以上方法仍然存在一个问题,如果module模块需要依赖其他模块怎么办? 需要对IIFE进行增强,如下:
以上就是前端的模块化
2. 什么是模块化规范
IIFE增强版的模块化实际上已经实现了前端的模块化,它带来的好处包括
但是IIFE增强版的模块化带来了新的问题,比如:
为了解决这两个问题,出现了模块化规范,比如 CommonJS, AMD, ES6, CMD规范。
3. 模块化规范--CommonJS
基本语法:
CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。例:
上面代码通过module.exports输出变量x和函数addX。
require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。
CommonJS模块的加载机制是,输入的是被输出的值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。这点与ES6模块化有重大差异(下文会介绍)
3. 模块化规范-- AMD
CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。
基本语法:
AMD规范的典型实现是RequireJS,它是一个工具库,主要用于客户端的模块管理。通过define方法,将代码定义为模块;通过require方法,实现代码的模块加载。
4. 模块化规范-- CMD
CMD规范专门用于浏览器端,模块的加载是异步的,模块使用时才会加载执行。CMD规范整合了CommonJS和AMD规范的特点。在 Sea.js 中,所有 JavaScript 模块都遵循 CMD模块定义规范。
基本语法:
5. 模块化规范-- ES6
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系、输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
基本语法:
export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
如上例所示,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。
模块默认输出, 其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。
ES6 模块与 CommonJS 模块的差异
它们有两个重大差异:
第二个差异是因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
ps: RequireJs 和 Sea.js 的实现其输出也是一个值的拷贝
6.总结
参考自:
1. 前端模块化详解(完整版)
2. Module 的语法
3. Module 的加载实现
4.【前端工程化系列】简谈前端模块化开发与开发规范
5. 前端模块化开发 - haoxl - 博客园
6. 详解JavaScript模块化开发 - trigkit4 - SegmentFault 思否
7. 前端模块化:CommonJS,AMD,CMD,ES6 - 掘金
8. 浅谈前端模块化- 腾讯Web前端IMWeb 团队社区| blog | 团队博客
9. 前端工程之模块化- FEX
10. 前端模块化** - 谦行 - 博客园
11 前端模块化和组件化理解- Counting Stars - SegmentFault 思否
12. js模块化历程
The text was updated successfully, but these errors were encountered: