模块化


涉及?试题:

  • 为什么要使?模块化?
  • 都有哪?种?式可以实现模块化,各有什么特点?

使??个技术肯定是有原因的,那么使?模块化可以给我们带来以下好处:
· 解决命名冲突
· 提供复?性
· 提?代码可维护性

?即执?函数
在早期,使用 立即执?函数 实现模块化是常?的?段,通过函数作?域解决了命名冲突、污染全局作?域的问题。

                                      (function(globalVariable){
                                         globalVariable.test = function() {}
                                             // ... 声明各种变量、函数都不会污染全局作?域
                                      })(globalVariable)

AMD 和 CMD
鉴于?前这两种实现?式已经很少?到,所以不再对具体特性细聊,只需要了解这两者是如何使?的。

                                      // AMD
                                      define(['./a', './b'], function(a, b) {
                                           // 加载模块完毕可以使?
                                           a.do()
                                           b.do() 
                                      })

                                      // CMD
                                      define(function(require, exports, module) {
                                           // 加载模块
                                           // 可以把 require 写在函数体的任意地?实现延迟加载
                                           var a = require('./a')
                                           a.doSomething()
                                      })

CommonJS
--- CommonJS 最早是 Node 在使?,?前也仍然?泛使?,?如在 Webpack 中你就能?到它,当然?前在 Node 中的模块管理已经和 CommonJS 有?些 区别了。

                                            // a.js
                                            module.exports = { a: 1 }
                                            // or
                                            exports.a = 1

                                            // b.js
                                            var module = require('./a.js')
                                            module.a // -> log 1
                                            ar module = require('./a.js')
                                            module.a
                                            // 这?其实就是包装了?层?即执?函数,这样就不会污染全局变量了,
                                            // 重要的是 module 这?,module 是 Node 独有的?个变量
                                            module.exports = { a: 1 }
                                            // module 基本实现
                                            var module = {
                                               id: 'xxxx', // 我总得知道怎么去找到他吧
                                               exports: {} // exports 就是个空对象 
                                            }
                                            // 这个是为什么 exports 和 module.exports ?法相似的原因
                                            var exports = module.exports
                                            var load = function (module) {
                                                 // 导出的东?
                                                 var a = 1
                                                 module.exports = a
                                                 return module.exports
                                            };
                                            // 然后当我 require 的时候去找到独特的
                                            // id,然后将要使?的东???即执?函数包装下,over
  • 另外虽然 exports 和 module.exports ?法相似,但是不能对 exports 直接赋值。
  • 因为 var exports = module.exports 这句代码表明了 exports 和 module.exports 享有相同地址,通过改变对象的属性值会对两者都起效,
  • 但是如果直接对 exports 赋值就会导致两者不再指向同?个内存地址,修改并不会对 module.exports 起效。

ES Module --- ES Module 是原?实现的模块化?案,与 CommonJS 有以下?个区别

  1. CommonJS ?持动态导?,也就是 require(${path}/xx.js) ,后者?前不?持,但是 已有提案。

  2. CommonJS 是同步导?,因为?于服务端,?件都在本地,同步导?即使卡住主线程影响 也不?。?后者是异步导?,因为?于浏览器,需要下载?件,如果也采?同步导?会对渲染有很?影响。

  3. CommonJS 在导出时都是值拷?,就算导出的值变了,导?的值也不会改变,所以如果想 更新值,必须重新导??次。
    但是 ES Module 采?实时绑定的?式,导?导出的值都指向同?个内存地址,所以导?值会跟随导出值变化。

  4. ES Module 会编译成 require/exports 来执?的。

                                       // 引?模块 API
                                       import XXX from './a.js'
                                       import { XXX } from './a.js'
                                       // 导出模块 API
                                       export function a() {}
                                       export default function() {}