JaneChelle | Blog JaneChelle | Blog

执着于理想,纯粹于当下

目录
JS模块化
/      

JS模块化

一、理解

1. 什么是模块化?

将一个复杂的程序依据一定的规则(规范)封装成几个块(文件),并进行组合在一起。块的内部数据/实现是私有的,只是向外暴露一些接口(方法)与外部其他模块通信。

2. 模块化的进化史

(1) 最早我们这么写代码:

function foo(){}
function bar(){}

缺点:Global 被污染, 很容易命名冲突

(2)简单封装 Namespace 模式

var MYAPP = {
foo: function(){}.
bar: function(){}
NYAPP. foo();

缺点:减少 Global 上的变量数目;本质是对象,一点都不安全
(3)匿名闭包: IIFE 模式

var Module = (function(){
var _private = 'safe now';
var foo = function(){
	console.log(_private);
}
return {
	foo: foo;
})()
Module.foo();
Module._private;// undefined

缺点:函数是 JavaScript 唯一的 Local scope,安全
(4)再增强一点:引入依赖

var Module = (function($) {
var _Sbody = $("body"); // we can use jouery now !
var foo = function(){
	console.log( $body); // 特权方法
       // Revelation Pattern
return {
        foo: foo
}
})(jquery)
Module. foo();

这就是模块模式,也是现代模块实现的基石

3. 为什么要模块化?

降低复杂度,提高解耦性,部署方便

4. 模块化的好处

  • 避免命名冲突
  • 更好的分离,按需加载
  • 高可维护性
  • 更高复用性

5. 模块化带来的问题

  • 请求过多
  • 依赖模糊
  • 难以维护

二、模块化规范

1. CommonJS

1.说明

每个文件都可以当做一个模块

在服务器端:模块的加载是运行时同步加载的

在浏览器端:模块需要提前编译打包处理

2.基本语法

  1. 暴露的模块:module.exports = value; exports.xxx = value
  2. 暴露的模块到底是什么?暴露 都是 exports
  3. 引入模块 require(xxx):第三方模块:xxx 为模块名;自定义模块: xx x 为模块文件路径

3.开发依赖和运行依赖

开发依赖:当前的包只在开发的环境下去使用

--save-dev,会使安装的包在 package.json 中的 devDependencies 中 工程构建(开发时、“打包”时)依赖

运行依赖:线上运行,即生产环境运行

--save,会使安装的包在 package.json 中的 dependencies 中,项目(运行时、发布到生产环境时)依赖

2. AMD(requirejs)

1. 说明

专门用于浏览器端,模块的加载是异步的

2. 基本句法

  1. 定义暴露模块
  • 定义没有依赖的模块
define(function(){
return 模块
})
  • 定义有依赖的模块
define(['module1', 'module2'], function(m1, m2){  
return模块  
})
  1. 引入使用模块
require(['module1', 'module2'], function(m1, m2){
使用m1/m2
})

3. 实现(浏览器端): Require.js

image.png

image.png

3. CMD(了解)

1. 说明

  • 专门用于浏览器端,模块的加载是异步的
  • 模块使用时才会加载执行

2. 基本语法

定义暴露模块及引入使用模块
image.png

4. ES6

1. 说明

依赖模块需要编译打包处理

2. 语法

导出模块:export
引入模块:import

3. 实现(浏览器端)

  1. 编码:
* js/src/module1.js  分别暴露
    ```
    export function foo() {
      console.log('module1 foo()');
    }
    export function bar() {
      console.log('module1 bar()');
    }
    export const DATA_ARR = [1, 3, 5, 1]
    ```

  * js/src/module2.js  统一暴露
    ```
    let data = 'module2 data'
    
    function fun1() {
      console.log('module2 fun1() ' + data);
    }
    
    function fun2() {
      console.log('module2 fun2() ' + data);
    }
    export {fun1, fun2}

   * js/src/module3.js 默认暴露

    export default {
      name: 'Tom',
      setName: function (name) {
        this.name = name
      }
    }
  
  1. 编译:
  • 使用Babel将ES6编译为ES5代码
    babel js/src -d js/build
  • 使用Browserify编译打包js
    browserify js/build/main. js -o js/dist/bundle. js
  1. 页面测试:
 <script type="text/javascript" src="js/lib/bundle.js"></script>
  1. 引入第三方模块(jQuery)

1). 下载jQuery模块:

npm install jquery@1 --save

2). 在app.js中引入并使用

    import $ from 'jquery'
    $('body').css('background', 'red')