模块化开发详细介绍及详细用法

vue的三个特点:

Ø Mvvm

Ø 组件化

Ø 模块化

 模块化是指文件的组织,管理,使用的方式

 代码的开发阶段:把一个大的文件,拆分成几个小文件,它们之间相互引用,依赖。

代码发布之后:把这些小文件打包成一个大文件webpack

 1.1. 为什么要用模块化开发

 

以下面代码为例:

这个index.html文件中一共引入了8js文件。

 

 这样组织至少会有两个问题:

(1)全局变量污染

(2)文件之间相互依赖的问题:Balloon.js文件必须要依赖于myjquery.js(这是我们自己写一个库),因为balloon.js中产生随机数所用的函数GetR来自于myjquery.js的。

 解决:

(1)全局变量污染的问题,我们可以通过立即执行的函数表达式来解决。

(2)我们之前组织代码的方式,就不能很方便地看出来,哪个文件依赖于哪个文件。就算我们事先知道A.js依赖于B.js(可能A.js中用了B.js中的方法),我们也没有办法在浏览器端保证:B.js会在A.js之前加载完成。

 

1.2. 模块化的发展

模块化的思想主要是从后端的程序中引入的。

 php  --  include  ”header.php”

1.2.1. 理解css中的模块化

Css   --  @import



 es6之前,它不支持在一个js中直接去引入另一个js文件。

 Ø 原始方式 --- 无模块时代

Ø 萌芽时代 --- 闭包+自执行函数、命名空间、人肉方式、配置参数

Ø CommonJS规范 --- CommonJs社区制定了Modules/1.0规范

Ø AMD规范 --- 革新派,RequireJS

Ø CMD规范 --- 中间派,seajs

Ø es6模块化 --- 终极解决方案

 1.3. 闭包+立即执行函数的方式

 它只是解决了文件之间的相互依赖关系的描述:

你一看到这个iife就可以知道,当前的这个模块(js文件)是依赖于哪些模块(js文件)的。

 

zepto就是这样做的

 

 1.4. CommonJS规范


 CommonJS规范源于Modules/1.0,在node.js中率先实现了。

核心内容有如下几点:

Ø 使用require方法引入其他模块(js文件),执行的结果即为别的模块(js文件)暴漏出来的API

Ø 模块通过变量module.exports导出APIexports只能是一个对象,暴漏的API须作为此对象的属性。

Ø 如果require函数引入的模块中也包含依赖,则依次加载这些依赖。

Ø 如果引入模块失败,那么require函数应该报一个异常。

 1.4.1. 定义模块

1.4.1.1. 格式

module.exports={

键值对

}

 1.4.2. 引入模块

Let obj = require(“模块名’)

 require函数,会返回一个对象,返回的是在模块中使用module.exports导出的对象

 1.4.2.1. 引入模块的格式

模块名的路径,有两种:

Ø 自定义模块:使用相对路径,以./../开头 模块名后可以加.js,也可以不加;你不能直接写模块名,就算是两个文件在同一个目录下,也加./

Ø 第三方模块:只需要写上模块名即可。这里的第三方模块,其实就是使用npm来安装的那些模块。

 例如,你安装了vue模块。则在node_modules下会多一个文件夹:

 

你要想使用vue模块,只需要:

 

 1.4.3. 示例

1.4.3.1. 浏览器端 不支持

现在有一个简单的需求,有三个文件如下:

Ø Index.html:它引入index.js文件


Ø Index.js:它执行一些功能,但它要入unit.js


Ø Unit.js:它就是一个库,提供一些方法

 

如果你现在去打开index.html文件,则浏览器一定会报错:

 

因为commonjs规则在浏览器端不支持。

 但,在node.js中是支持commonjs规则的,即,上面的index.js文件可以直接通过node去运行。

 1.4.3.2. nodejs中是支持的

 

 1.4.4. browserify工具,把代码编译打包一下,让浏览器也能用

 先通过npm安装。

(1)建议先在根目录,创建好package.json文件。

(2)全局安装和本地安装都可以。

npm install  browserify  -g (在任何一个小黑窗下都可以使用browserify命令)

或者是

npm install  browserify  --save (只能在当前的目录下使用这个命令)

(3)运行browserify  命令去转码

格式:

Browserify 要转码的.js  -o  转码之后的.js

示例:

 

 这里的blunder.js会自动创建的。

如下:

 

4)在html中引入这个blunder.js即可。(之前引的是index.js,它不能用)

效果如下:

 

1.4.5. 应用:对前面的打气球游戏的js代码进行模块化处理

 

1.4.5.1. 把之前的立即执行的函数表达式的写法,改成commonjs的定义模块

 

改成:

 

 把

 

改成:

 

 其它的js文件的写法都类似。

 game.js

 

 1.4.5.2. browserify对game.js进行转码

html中引入转码之后的文件即可。

 commonjs主要是在服务器端使用,在浏览器端虽然可以用browserify进行转码,但,并没有体现出浏览器与服务器端的区别:

 浏览器端的代码是异步的,而服务器端是同步的。在浏览器端,提出 amd规范。

 1.5. amd 规范 require.js

Asynchronous Module Definition

"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

amd是一种规范。require.js实现了这种规范。

 1.5.1. 代表产品:require.js

 

 

1.5.2. Require.js的使用

1.定义模块

2.在主文件中引用模块

3.html中引入require.js

 

 1.5.2.1. requirejs 定义模块(不是入口文件)

define(['模块1',’'模块2'’],function(变量1,变量2){

return {

}

});

(1)这里的变量就是这个模块的别名。

(2)如果当前模块不依赖其它的模块,则不需要写第一个参数,第二个参数中的形参列表也不要。

(3)这里也是使用模块。

 示例:

 

1.5.2.2. requirejs 定义入口文件

require([“模块1”,“模块2],function(变量1,变量2){

//你的代码

});

 示例

 

Index.js需要使用unit.js这个模块

 1.5.2.3. html页面中引入requirejs并指定入口文件

 <script src="js/require.js" data-main="js/main" ></script>

 (1)data-main是指定的主入口的名字。类似于c语言中的main函数一样。

(2)可以省略.js后缀。

 

 效果如下:

 

 1.5.3. 应用 :用require.js去改写对前面的打气球游戏的js代码

 部分代码如下:

 

  

  

  

 1.6. cmd规范 sea.js

Common Module Definition”的缩写,意思就是"通用模块定义"

 cmd是一种模块化规范。

CMD推崇依赖就近,延迟执行

 sea.js是推动cmd规范的产物。

 1.6.1. 代表产品sea.js


1.6.1.1. seajs 定义模块--不需要引用其它模块

define(function(require,exports,module){

      //你的代码,函数,变量,对象

//导出模块有三种方式

exports.属性名=值。//方式一

module.exports.属性名=值。//方法二

    return 对象//方法三

   

});

 

(1)defineseajs定义的全局函数


1.6.1.2. seajs 定义模块--需要引用其它模块

define(function(require,exports,module){

      //你的代码,函数,变量,对象

Var obj = require(‘模块名’)

//导出模板有三种方式

exports.属性名=值。//方式一

module.exports.属性名=值。//方法二

    return 对象//方法三

   

});

 

1.6.1.3. 主入口

<script >

seajs.use(["模块1",“模块2],function(变量1,变量2){

});

  

1.6.1.4. html页面中引入sea.js,和入口文件

  

 1.6.2. 应用 :用sea.js去改写对前面的打气球游戏的js代码

  

  

  

  

 

 

注意一下:sea.js文件最好是和你的模块放在同一级目录下。

 

 

 

1.7. 查看jquery的代码

 

 

 

1.8. es6模块化

 

 

 

Import:导入。在自己当前的模块去使用其它模块

Export:导出。在定义模块时,决定把哪些内容暴露出去:当别的模块去引入当前模块,别人会得到什么东西。

 

1.8.1. 示例

Ø Index.html:引入index.js


Ø Index.js:要去引用unit.js


Ø Unit.js

 

 

 

现在,直接打开浏览器去访问index.html会得到一个错误:

 

 

 

由于importes6的语法。在浏览器中不支持的,但我们可以通过babel进行转码。

 

下面,就要开始去转下码。

 

1.8.1.1. babel转码

Ø 安装bable

npm install babel-cli -g

 

Ø 安装两个包

npm install babel-preset-es2015 babel-preset-stage-2 --save-dev

 

Ø 编写配置文件

.babelrc

{

"presets":["es2015","stage-2"]

}

 

运行转码命令:

 

 

 

现在我们的文件如下::

 

 

 

 

细节:

index.es5.js中,我们引入的文件应该要从unit.js改成unit.es5.js

 

 

 

index.html中,把index.js 改成 index.es5.js。结果还是报错:require不认识。

 

 

 

 

我们通过babeles6 --> es5之后:

实际是es6规范  ---> common规范



 

Es6

Es5

 

 

 

 

Es6规范

commonjs规范

 

 commonjs规范:它还是不能在浏览器工作。但它可以直接在nodejs中运行。 


为了让代码能够在浏览器中运行,我们还需要对index.es5.js文件进行browserify处理。

 


1.8.1.2. browserify处理

 

对入口文件(这个它引用其它的模块)进行处理:

 

browserify会分析index.es5.js文件,找出这个文件中依赖了哪些其它的文件,把它的依赖文件全部装到一个文件中:bundle.js

 

 

 

 

 

修改index.html文件,把bundle.js引入:

 

 

 

成功啦!!!

 

 

 

1.8.2. Export

你在定义模块时,你可以决定,当你的模板被其它模板引入时,你暴露出去的内容是什么。

 

1.8.2.1. 逐个导出

 

 

 

 

 

 

 

1.8.2.2. 批量导出

 

 

 

1.8.2.3. 别名导出

 

 

 

 

 

1.8.3. Import

格式:

Import {变量名1,变量名2.... } from “模块名”

 

1.8.3.1. 逐个导出和批理导出

对于上面unit模块,它的两种导出方式,我们都可以用如下的方式进行导入:

 

(1)导入时,你使用的变量名data,name必须要与unit模块中导出时用的名字要一致。

(2)两个变量之间先后顺序是没有的关系的(对象是属性的无序集合)

(3)上面的模块的路径的写法(”./unit”)与commonjs中的require的要求是一样的:

Ø 如果自己定义的模块,则一定要加 ./(表示当前目录) ../(上一级目录)

Ø 如果是第三方的模块,则直接写模块名。


如上代码说明,vue这个模块是默认导出的。

 

1.8.3.2. 别名导入

在导入数据时,取个别名。

 

 

 

 

1.8.4. Export default

在导出和导入我们需要保持属性名是一致,这就比较麻烦。

 

我们通过通过exprot default来把取名的工作交给引用模块:即我导出时,不取名字,你导入时,爱取什么名字就取什么名字。

 

1.8.4.1. 定义模块

 

 

1.8.4.2. 引入模块

 

 

 

1.8.4.3. Export default和批量导出可以一起用

导出模块

 

 

导入模块

 

 

 

 

1.8.5. 模块的整体加载

 

Import * as

 

 

模块还是正常地批量导出:

 

导入时

 

 

 

 

 

 

2. 模块化总结

模块化

Ø 一个js文件就是一个模块;

Ø 把很多个模块通过相互引用的方式组合在一起

Ø index.html中,只引入一个模块

 

有四种规范

Ø Commonjs:nodejs中支持的。在服务器端工作。

Ø Amd:在浏览器端工作 。代表产品是:require.js

Ø Cmd:在浏览器端工作 。代表产品是:sea.js

Ø ES6 :正宗。完全可以构建 服务器端 和浏览器 都支持的 方案。

 

 

方案名

定义模块

使用模块

主入口

 

commonjs

modules.exports={}

require()

obj  =require(./模块名’)

 

browserify转码

 

amd-seajs

defind(require,export,module)

defined(require,export,module){ require (./模块名)}

seajs.use([],functin(){

})

sea.js

 

cmd-require

define(function(){return {}

});

 

 

define(['模块'],function(变量){return {}

});

require(["game"],function(g){})

 

data-main

common.js

es6

export

import

 

babel browserify

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值