前端模块化
CommonJS中的导入与导出
方法1:exports
导出
exports.add = function (num1, num2) {
return num1 + num2;
};
exports.decrease = function (num1, num2) {
return num1 - num2;
};
导入
const { add, decrease } = require("./cal.js");
console.log(add(8, 2)); // 10
console.log(decrease(8, 2)); // 6
方法2:module.exports
导出:
module.exports = {
add: function (num1, num2) {
return num1 + num2;
},
decrease: function (num1, num2) {
return num1 - num2;
},
};
导入
用calculate保存了引入的那个对象
const calculate = require("./calculate");
console.log(calculate.add(8, 2)); // 10
console.log(calculate.decrease(8, 2)); // 6
ES6中的导入导出与继承
一个模块就是一个独立的文件,该模块内部的私有变量,外部无法获取,如果外部需要使用,就必须将模块的变量通过export导出,使用时先用import导入
ES6模块的设计思想是尽量静态化,使得在编译时就能确定模块的依赖关系,以及输入输出变量
ES6模块自动使用严格模式,不管有没有use strict;
顶层this指向undefined
一、导出
1》命名导出
2》默认导出
二、导入
1》按需导入
2》整体导入
导出
命名导出:export.js文件
命名导出在使用时必须知道导出变量或属性或方法的名字
//1 直接导出变量或者是方法
// <1.1>export 后面直接跟变量的初始化
export var num = 666
export function add(a, b) {
return a + b
}
var name = 'luca'
function getName(firstName, lastName) {
return firstName + ' ' + lastName
}
//<1.2> 这种写法等同于上面的导出,但是阅读性上更好
export { name, getName }
按需导入
利用了es6的结构赋值
import { num, add, name, getName } from './util/export.js'
console.log(num) // 666
console.log(add(8, 2)) // 10
console.log(name) // luca
console.log(getName('hello', 'world')) // hello world
整体导入
import * as allContent from './util/export.js'
console.log(allContent.num) // 666
console.log(allContent.add(8, 2)) // 10
console.log(allContent.name) // luca
console.log(allContent.getName('hello', 'world')) // hello world
整体导入得到一个对象,默认导出的内容在default属性(是一个对象)中
默认导出
上面的例子可以看出我们在导入时必须知道导出的名字,才能导入使用,为了方便上手我们有了默认导出
//2 默认导出
function decrease(a, b) {
return a - b
}
export default decrease
导入时不需要直到导出的是什么名字,就可以直接导入,我们再导入的时候自己给它起一个名字
下面的anyName代表的就是默认导出的内容,可能是一个函数、对象、字符串……
import anyName from '../util/importExport/export.js'
console.log(anyName(4, 1))
eg2:一个模块只能有一个默认导出;入宫我们需要有多个默认导出就使用对象的形式
// 默认导出
function greet() {
return 'hello'
}
const age = 20
export default { greet, age }
// 导入
import dafultExport from '../util/importExport/export.js'
console.log(dafultExport.age)
console.log(dafultExport.greet())
可以使用as进行重命名
a as b 将a重命名为b;导入和导出都一样
三、ES6模块的继承
copy.js继承export.js
1》整体导入继承
copy.js文件,继承了export.js,同时也定义了自己的东西
export * from './export.js'
export const val = '自己的东西,不是继承'
export default function test() {
console.log('我继承了export.js,但这是我自己的方法')
}
export * 不管自己有没有默认导出,都不会继承父亲默认导出的内容
我在模块中整体导入copy.js,并打印出来,发现它并没有继承export.js的默认导出,default中只有test方法
{
add: ƒ add(a, b)
default: ƒ test()
getName: ƒ getName(firstName, lastName)
name: "luca"
num: 666
val: "自己的东西,不是继承"
}
2》使用按需导入继承
copy.js文件:
export { getName, name as newName } from './export.js'
export const val = '自己的东西,不是继承'
export default function test() {
console.log('我继承了export.js,但这是我自己的方法')
}
整体导入copy.js,并打印出来
{
default: ƒ test()
getName: ƒ getName(firstName, lastName)
newName: "luca"
val: "自己的东西,不是继承"
}
CommonJS的模块化与ES6模块化的区别
1》CommonJS模块输出的是一个值的复制,而ES6输出的是值的引用
es6:当我引入打印是,结果num=67
export let num = 66
setTimeout(() => {
num++
}, 1000)
导出:
let num = 66;
module.exports = {
num,
};
setTimeout(() => {
num++;
}, 1000);
引入:
值一旦输出,,模块内部的变化就影响不到这个值
const obj = require("./cal.js");
console.log(obj.num); // 66
2》CommonJS模块是运行是加载,ES6是编译是输出接口
因为CommonJS加载的是一个对象(module.exports属性),该对象只有在脚本结束时才会生效
而ES6模块不是对象,它对外接口只是一种静态形式,在代码静态解析阶段就会生成
Node环境混合加载
Node环境中,使用import命令加载CommonJS模块,Node会自动将module.exports属性当作模块的默认输出,即等同于 export default
采用require加载ES6模块时,ES6模块的所有输出接口都会成为输入对象的属性