Module 模块化

本文详细介绍了JavaScript中的模块化,包括AMD、CommonJS、UMD规范,以及ES6的模块化特性,如静态化、严格模式、作用域、解析、延迟加载和路径兼容。此外,还讨论了导入和导出的不同方式,如具名导入、默认导出、动态导入等,以及Webpack的模块编译。
摘要由CSDN通过智能技术生成

Module 模块化

1. 模块起步

1-1 模块化规范

  • AMD —— 异步模块定义规范,最初由 require.js 库实现,用于浏览器的模块系统
  • CommonJS —— 为 Node.js 服务器创建的模块系统
  • UMD —— 通用模块定义规范,作为通用的模块系统
  • CMD —— 阿里 SeaJS,用于浏览器的模块系统
  • ES6 Module —— JavaScript 模块浏览器和服务器通用的模块系统
规范 描述
CommonJS 是服务器模块的规范,加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作
AMD 规范加载模块是异步的,并允许函数回调,不必等到所有模块都加载完成,后续操作可以正常执行,只要模块作为依赖时,就会加载并初始化
CMD CMD 规范和 AMD 类似通用模块定义,模块作为依赖且被引用时才会初始化,否则只会加载
UMD 通用模块定义,UMDAMDCommonJS 的结合,实现跨平台的解决方案,先判断是否支持 Node.js 的模块(exports)是否存在,存在则使用 Node.js 模块模式。再判断是否支持 AMDdefine 是否存在),存在则使用 AMD 方式加载模块

1-2 什么是模块?

ES ModuleES6 中提出的一个新的模块加载方式,完全可以取代 commonJsAMD 两种模块加载方式,成为服务端和浏览器端模块加载的解决方案

ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量,所以在资源加载速度和静态分析方面效率更高

  • export —— 从当前模块外部访问的变量和函数
  • import —— 允许从其他模块导入功能

通过使用 <script type="module"> 特性告诉浏览器,脚本应该被当作模块 module 来对待

<!-- 添加type="module"让浏览器以模块解析脚本 -->
<script type="module">
  // import 从其它模块引入功能
  import {
      module } from './module.js'
  console.log(module)
</script>
// module.js
let module = 'ES Modules'
// export 从当前模块导出变量与方法
export {
    module }

1-3 模块严格模式

在模块下始终在严格模式下运行,始终使用 use strict

  • 变量必须声明后再使用
  • 函数的参数不能有同名属性,否则报错
  • 全局 this 执行 undefined
<script>
  // 不在模块下允许 this指向window
  console.log(this); // window
</script>
<script type="module">
  console.log(this); // defined
</script>

1-4 模块作用域

每个模块都有自己的作用域,一个模块中的作用域变量和函数在其他脚本中是不可访问的

对于模块,我们使用导入/导出而不是依赖全局变量

<script src="./normal.js"></script>

<!-- 模块A -->
<script type="module">
  let module = 'module js'
</script>

<!-- 模块B -->
<script type="module">
  // 对于模块只能使用导入导出 不能依赖全局变量
  console.log(module)
  //Uncaught ReferenceError module is not defined
</script>

<script>
  // 不在模块下可访问外部组用于
  console.log(normal)
  console.log(module); 
  //Uncaught ReferenceError module is not defined
</script>
// normal.js
let normal = 'normal js'

1-5 模块解析

模块代码仅在第一次导入时被解析,当导出的对象或者其它类型数据时被修改了,后面再导入时获取的是修改后的新值

import.meta 对象包含关于当前模块的 url 信息,在浏览器环境中,它包含当前脚本的 URL,或者如果它是在 HTML 中的话,则包含当前页面的 URL

<script type="module">
  // import.meta获取当前脚本url
  console.log(import.meta.url)
    
  // 模块代码仅在第一次导入时被解析
  // a模块导入module立即执行改变name属性 b模块引入module里的name是被更改的
  import {
     } from './module-a.js'
  import {
     } from './module-b.js'
</script>
// module.js
// 模块代码只会在第一次导入时解析
export let obj = {
   
  name: 'jsx'
}
// module-a.js
import {
    obj } from './module.js'
obj.name = 'ljj'
// module-b.js
import {
    obj } from './module.js'
console.log(obj.name)

1-6 模块延迟

模块脚本是延迟加载的,与 defer 特性一样

  • 外部模块脚本 <script type="module" src="..."> 不会阻塞 HTML 的处理,它们会与其他资源并行加载
  • 模块脚本会等到 HTML 文档完全准备就绪,然后才会运行
  • 保持脚本的相对顺序:在文档中排在前面的脚本先执行
<!-- 普通脚本不会延时加载不会等待文档加载会阻塞文档加载 -->
<!-- 1. defer -->
<!-- 2. 脚本放置元素后 -->
<!-- defer async只能用于外部引入的脚本延时加载 -->
<script src="./normal.js"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值