adodo0829/blog

ES Module 模块加载规范

Opened this issue · 0 comments

ES Module 模块加载规范

规范

export: 规定模块对外接口

默认导出:export default Person(当导入时可指定模块任意名称,无需知晓内部真实名称)
单独导出:export const name = "huhua"
按需导出:export { age, name, sex }(推荐)
改名导出:export { name as newName }

import:导入模块内部功能

默认导入:import Person from "person"
整体导入:import * as Person from "person" // Module对象
按需导入:import { age, name, sex } from "person"
改名导入:import { name as newName } from "person"
自执导入:import "person"
复合导入:import Person, { name } from "person"

复合模式

export命令和import命令结合在一起写成一行,变量实质没有被导入当前模块,相当于对外转发接口,导致当前模块无法直接使用其导入变量

默认导入导出:export { default } from "person"
整体导入导出:export * from "person"
按需导入导出:export { age, name, sex } from "person"
改名导入导出:export { name as newName } from "person"
具名改默认导入导出:export { name as default } from "person"
默认改具名导入导出:export { default as name } from "person"
// 示例, 将布局组件模块拎出来
export { default as AppMain } from './AppMain.vue'
export { default as Navbar } from './Navbar/index.vue'
export { default as NavTitle } from './NavTitle/NavTitle.vue'
export { default as Sidebar } from './Sidebar/index.vue'

// 其他文件下引入
import { AppMain, Navbar, Sidebar, NavTitle } from './components'

模块加载

传统加载:通过<script>进行同步或异步加载脚本
  同步加载:<script src="index.js"></script>
  Defer异步加载:<script src="index.js" defer></script>(顺序加载,渲染完再执行)
  Async异步加载:<script src="index.js" async></script>(乱序加载,下载完就执行)

模块加载:<script type="module" src="index.js"></script>(默认是Defer异步加载)
  • CommonJS和ES Module的区别
CommonJS输出值的拷贝,ES Module输出值的引用
  CommonJS一旦输出一个值,模块内部的变化就影响不到这个值
  ES Module是动态引用且不会缓存值,模块里的变量绑定其所在的模块,
  等到脚本真正执行时,再根据这个只读引用到被加载的那个模块里去取值


CommonJS是运行时加载,ES Module是编译时加载
  CommonJS加载模块是对象(即module.exports),该对象只有在脚本运行完才会生成
  ES Module加载模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成

运行时加载
  定义:整体加载模块生成一个对象,再从对象上获取需要的属性和方法进行加载(全部加载)
  影响:只有运行时才能得到这个对象,导致无法在编译时做静态优化
编译时加载
  定义:直接从模块中获取需要的属性和方法进行加载(按需加载)
  影响:在编译时就完成模块加载,效率比其他方案高,但无法引用模块本身(本身不是对象),可拓展JS高级语法(宏和类型校验)