ES Module -JavaScript的模块化
一.静态加载
1.ES Module运行环境
在node中运行
1.将文件扩展名改为.mjs
//other.mjs export const name = "Cristiano" export const sport = "football" //index.mjs import { name, sport } from "./other.mjs" console.log(name, sport); //Cristiano football 复制代码
2.在package.json中配置type为"module"
//package.json { "type": "module" } //other.js export const name = "Cristiano" export const sport = "football" //index.js import { name, sport } from "./other.js" console.log(name, sport); //Cristiano football 复制代码
在浏览器中运行
在html的script标签中加上type="module"
<script src="./index.js" type="module"></script> 复制代码
不能通过本地加载html文件,可以通过VSCode下载插件Live Server打开
2.export
一个模块就是一个独立的文件,export可以导出变量、函数、类,有几种不同的导出方式:
方式一: 导出声明语句
//other.js export const name = "Cristiano" export function getGoldenGlobeAward() { console.log("CR7"); } export class Sports { constructor() { this.name = "football" } } 复制代码
方式二: 将标识符一起导出
//other.js const name = "Cristiano" function getGoldenGlobeAward() { console.log("CR7"); } class Sports { constructor() { this.name = "football" } } export { name, getGoldenGlobeAward, Sports } 复制代码
方式三: 使用(as
)关键字重命名
//other.js export const name = "Cristiano" export function getGoldenGlobeAward() { return "CR7" } export class Sports { constructor() { this.name = "football" } } export { name as crName, getGoldenGlobeAward as getFootballer, Sports as BallGame } 复制代码
注意: export关键字不能出现在函数或者块级作用域中,否则无法静态加载
//other.js let flag = true if (flag) { export const name = "CR7" //SyntaxError: Unexpected token 'export' } 复制代码
//other.js function foo() { export const name = "CR7" //SyntaxError: Unexpected token 'export' } foo() 复制代码
3.import
方式一:大括号里面的变量名,必须与被导入模块(other.js)对外接口的名称相同
//index.js import { name, getGoldenGlobeAward, Sports } from "./other.js" 复制代码
方式二: 使用(as
)关键字重命名
//index.js import { name as crName, getGoldenGlobeAward as getFootballer, Sports as BallGame } from "./other.js" 复制代码
方式三: 使用(*
)整体导入
//index.js import * as wholeIdentifier from "./other.js" console.log(wholeIdentifier.name) //Cristiano console.log(wholeIdentifier.getGoldenGlobeAward()) //CR7 复制代码
import
代码在编译阶段执行的,在代码运行之前,所以有提升作用
console.log(wholeIdentifier.getGoldenGlobeAward()); import * as wholeIdentifier from "./other.js" //CR7 复制代码
4.export和import结合用法
先输入后输出同一个模块,这样可以将所有接口放到一个文件中,方便阅读和管理
//other.js export { add, sub } from './math.js' //接口改名 export { timeFormat as dateFormat, priceFormat as moneyFormat } from './format.js' 复制代码
//other.js //整体导出 export * from './math.js' //整体改名导出 export * as whatever from './format.js' 复制代码
注意:other.js
模块中并没有导入add, sub,只是对外转发,所以当前模块不能使用这些接口
//统一管理 import { add, sub, dateFormat, moneyFormat} from 'other.js' 复制代码
5.export default(一个模块中只能有一个
)
import命令后面不使用大括号
,export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令
export default后面不需要具体函数或变量名,export default本质上就是输出一个叫做default的变量或方法
,导入时可以取任意名字
//other.js export default function () { console.log("CR7"); } 复制代码
//index.js import getName from "./other.js" //不使用{}大括号,getName可以随便取名 console.log(getName()); //CR7 复制代码
//other.js export default "CR7" //此时接口就是default 复制代码
二.动态加载(import()函数
)
import
和export
命令只能在模块的顶层,不能在代码块之中(比如,在if
代码块之中,或在函数之中) import()函数
支持动态加载模块,返回一个Promise对象
,可用于以下几种情形:
1.按需加载模块
//other.js const name = 'CR7' const age = 37 const country = "Portugal" export{name,age,country} //index.js function beWiminner() { import("./other.js").then(({name,age,country}) => { console.log(name); console.log(age); console.log(country); }) } beWiminner() //beWinner函数执行才会加载模块,可以通过解构拿到输出接口 复制代码
2.条件加载
if (condition) { import('moduleA').then(...); } else { import('moduleB').then(...); } //根据不同条件加载模块 复制代码
3.获取动态路径
import(foo()) .then(...); //根据函数foo返回的路径加载模块
作者:threefour
链接:https://juejin.cn/post/7028159090643697701