ES6-模块化介绍

模块化定义

模块化是指将一个大的程序文件,拆分成许多小的文件,一个小文件就是一个模块。
然后各模块即可以相互引入,

模块的好处

没有模块化系统带来的影响

  • 引入方式
    没有模块化之前js代码的引入方式是通过<script src="">标签来引入到同一个html文件中。

    <script src="lib.js"></script> <!-- 第三方库 -->
    <script src="utils.js"></script>
    <script src="app.js"></script>
    

    并且两个js之前是不恒互相引入的

  • 命名空间的问题:
    当我们引入多个js文件,不同的js文件可能会有相同的变量名字,那么后引入的就会覆盖先引入的。即所有的js文件都是再全局空间进行定义的,每个js文件没有自己私有的命名空间。

  • 依赖关系
    如果按两个js文件之间有依赖关系,必须保证引入的顺序。如果文件A依赖于文件B,那么在引入时,就需要先引入文件B,再引入文件A。如果文件之间的依赖关系很复杂,这样的引入顺序就非常难以维护。
    eg:没有模块化的文件引入
    a.js:

    function a (){
       console.log("我是a中的函数")
    }
    

    b.js:

    b = 100
    a()
    

    text.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <script type='text/javascript' src='./a.js'></script>
        <script type='text/javascript' src='b.js'></script>
        <script type='text/javascript'>
        </script>
    </body>
    </html>
    

    浏览器输出:

    我是a中的函数
    

    如果先引入b.js再引入a.js,就会报错 a未定义
    使用模块化之后,就可以在b.js文件中引入a.js文件,避免了依赖引入的问题,同时可以确保依赖加载的顺序是先加载a.js,再加载b.js

模块化的优点

  • 防止命名冲突,每个模块都有自己的命名空间
  • 代码复用,每个模块可以被其他多个模块引用
  • 高维护性,修改一个模块其他引用该模块的地方都改变
  • 确保引入顺序的正确性,使用模块化之后一般都是在自己的中引入所依赖的模块,所以避免了依赖顺序的引入问题

模块化规范及对应的产品

模块化规范产品
CommonJSNodeJS、Browserify(前端打包工具)
AMDrequireJS
CMDseaJS

ES6模块化的语法

模块功能主要由两个命令构成:export和 import

  • export命令用于规定模块的对外接口
  • import命令用于输入其他模块提供的功能(导入功能)

eg:
m1.js:

// export将功能暴露出去
export let name = "孙悟空"
export function wuqi (){
   console.log('我的武器是金箍棒')
}

html:

注意script设置type="module"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模块化</title>
</head>
<body>
    <script type="module">
        // 将m1.js中所有暴露的内容全都存在变量m1中
        import * as m1 from "./m1.js"
        console.log(m1)
        
    </script>
</body>
</html>

输出:
在这里插入图片描述

ES6暴露模块export

分别暴露

在要暴露的数据前面添加export,就是上面的例子

// export将功能暴露出去
export let name = "孙悟空"
export function wuqi (){
   console.log('我的武器是金箍棒')
}

统一暴露

暴露也可以写成一行
格式:export{要暴露的变量名}
m2.js:

// export将功能暴露出去
let name = "猪八戒"
function wuqi (){
   console.log('我的武器是铁耙子')
}

export{name,wuqi}

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模块化</title>
</head>
<body>
    <script type="module">
        // 将m1.js中所有暴露的内容全都存在变量m1中
        import * as m1 from "./m1.js"
        import * as m2 from "./m2.js"
        console.log(m2)
        
    </script>
</body>
</html>

在这里插入图片描述

默认暴露

默认暴露只能暴露一个对象。
格式:

// 默认暴露
export default {
    要暴露的数据(对象格式)
}

该种方法的返回值是一个default对象,调用里面属性的时候的时候需要添加.default
eg:
m3.js

// 默认暴露
export default {
    name:"猪八戒",
    wuqi:function(){
    	console.log('我的武器是铁耙子')
	}
}

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>模块化</title>
</head>
<body>
    <script type="module">
        // 将m1.js中所有暴露的内容全都存在变量m1中
        import * as m1 from "./m1.js"
        import * as m2 from "./m2.js"
        import * as m3 from "./m3.js"
        console.log(m3)
        m3.default.wuqi()
        
    </script>
</body>
</html>

在这里插入图片描述

ES6暴露引入模块import

通用导入方式

格式:import * as 变量名 from "js文件地址"
就是上面使用的方式,该方式可以应对所有暴露方式
eg:

  import * as m1 from "./m1.js"

解构赋值形式

  • 应对分别暴露、统一暴露
    格式:import {解构赋值的变量名} from "js文件地址"
    解构赋值的变量名对应着js暴露出去的变量

    	//分别暴露
        import {name,wuqi} from "./m1.js"
        console.log(name)
        console.log(wuqi)
        // 统一暴露     
        import {name as zhubajie,wuqi as tiepazi} from "./m2.js"
        console.log(zhubajie)
        console.log(tiepazi)
            
    

    在这里插入图片描述

  • 应对默认暴露

        import {default as m3} from "./m3.js"
        console.log(m3)
    

    在这里插入图片描述

简便形式(只针对默认暴露)

简便形式只针对默认暴露:
格式:import 变量名 from 'js地址'
EG:

import m3 from './m3.js'
 console.log(m3)

在这里插入图片描述

模块化引入

之前我们模块的引入都是在script中写的,一般情况下我们习惯把所有的模块引入放到一个JS文件中,叫做入口文件,然后html再引入该文件
eg:
app.js

// 入口文件
import * as m1 from "./m1.js"
import * as m2 from "./m2.js"
import * as m3 from "./m3.js"

console.log(m1)
console.log(m2)
console.log(m3)

html引入(不要忘记type设置成module,因为main.js是一个模块化文件,所以引入的时候需要添加type=module来指明这是一个模块化文件)

<script src="./app.js" type="module"></script>

输出:
在这里插入图片描述

模块代码在项目中的使用

由于ES6语法较新,浏览器不能直接理解,所以要将ES6语法转化成较低版本的语法,共浏览器理解。我们就需要使用Babel工具来帮助我们转化。

Babel简介

babel是js的一款编译器可以将比较新的js语法转换成ES5语法。
官网:https://babel.docschina.org/

转完之后将代码进行打包,页面在进行引入就可以解决兼容性问题

Babel使用

  • 安装以下工具

    • babel-cli(babel命令行)
    • babel-preset-env(将比较新的js语法转换成ES5语法)
    • browserify(webpack)(打包工具)
      安装语句:
      npm init -yes (初始化)
      npm i babel-cli babel-preset-env browserify -D(安装)
  • 进行转换
    转换命令:
    npx babel 要转换的文件目录 -d 要生成的文件目录 --presets=babel-preset-env
    eg:

    npx babel src/js -d dist/js
    
  • 打包
    npx browserify 要打包的文件地址 -o 要生成的文件目录/要生成的文件.js
    eg:

    npx browserify dist/js/app.js -o dist/bundle.js
    

    html在引入的时候就引入打包好的文件。

ES6模块化第三方模块

以jquery为例

  • 下载juery包:npm i jquery
  • 使用juery包:
    再js文件中引入:import $ from 'jquery'; //等价于 const $ = require("jquery");
    这样再js文件中就可以使用jQuery语法编写语句了。

ES6模块和CommonJS模块的区别

  • 导入导出模块的方式不同:CommonJS使用require(导入)和module.exports/exports(导出),而ES6模块使用import(导入)和export(导出)。
  • 加载机制不同:CommonJS模块是在运行时加载,而ES6模块是在编译时就解析完成依赖关系
  • 兼容性:由于Node.js的广泛应用,CommonJS模块兼容性相对较好,但需要使用工具如WebpackBabel进行打包构建才能应用在浏览器端。ES6模块对于新版浏览器兼容性较好,旧版浏览器则需要借助Babel进行转译。
  • 引用不同:CommonJS模块导出module.exports的值实际上是一个值的拷贝,就算原对象改变,导出的值不会改变;import得到的是一个值的引用,原对象改变,导出的值也会改变。
  • 使用场景:ES6模块可以在html文件中使用<script>标签引用,但是需要添加type = module属性,这会告诉浏览器你的脚本是一个JavaScript模块,而非一个传统的全局作用域的脚本,type="module"的脚本默认采用异步加载(相当于在<script>标签上加了一个async属性)。

模块的异步加载和同步加载

参见: https://blog.csdn.net/mantou_riji/article/details/137072904

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值