Commonjs和ES6模块化

commonjs模块化解决方案

commonjs导入导出需要底层解析器如webpack的支持,无法直接使用下面的格式导入导出

CommonJS的导出

语法:

module.exports={...}

CommonJs中使用module.exports导出变量及函数,也可以导出任意类型的值,看如下案例

// 导出一个对象
module.exports = {
    name: "蛙人",
    age: 24,
    sex: "male"
}

// 导出任意值
module.exports.name = "蛙人"
module.exports.sex = null
module.exports.age = undefined

直接导出

导出也可以省略module关键字,直接写exports导出也可以,看如下案例。

exports.name = "蛙人"  
exports.sex = "male"

ES6增强写法导出

var name = "小明";
var age = 22;

function sum(num1, num2) {
  return num1 + num2;
}

var flag = true;

module.exports = {
  // 这里用的是es6的增强写法,也可以写成flag:flag,sum:sum
  flag,
  sum,
  test(a, b){
    return a +b
  },
  demo(a, b){
    return a *b
  }
};

混合导出

混合导出,exportsmodule.exports可以同时使用,不会存在问题。

exports.name = "蛙人"  
module.exports.age = 24

CommonJS的导入

语法:

let {...}=require('./js的文件路径')

CommonJs中使用require语法可以导入,如果想要单个的值,可以通过解构对象来获取。

// index.js  
module.exports.name = "蛙人"  
module.exports.age = 24  
  
let data = require("./index.js")  
console.log(data) // { name: "蛙人", age: 24 }

解构对象获取导入的值

let {test, demo, flag}= require('./js的文件路径');
//等同于
let _mA= require('moduleA');
let _test =_mA.test;
let _demo =_mA.demo;
let _flag =_mA.flag;

导入值的变化

CommonJs导入的值是拷贝的,可以对该拷贝值做任意修改。

// index.js  
let num = 0;  
module.exports = {  
    num,  
    add() {  
       ++ num   
    }  
}  
  
let { num, add } = require("./index.js")  
console.log(num) // 0  
add()  
console.log(num) // 0  
num = 10  

上面example中,可以看到exports导出的值是值的拷贝,更改完++ num值没有发生变化,并且导入的num的值我们也可以进行修改

ES6导入导出

导出export

export指令用于导出变量,比如下面的代码:

//写法1:定义变量的时候直接通过export导出
export let name ='why'
export let age =.18
export let height =1.88
//写法2:定义好变量后最后通过export组合导出
let name ='why'
let age =18
let height=1.88
export {name, age, height}

上面我们主要是输出变量,也可以输出函数或者输出类

//写法1:定义函数或类的时候直接通过export导出
export function test(content){
  console. log(content);
}
export class Person{
  constructor(name, age){
    this.name =name;
    this.age= age;
  }
  run(){
    console.log(this.name+'在奔跑');
  }
}
//写法2:定义好函数和类后最后通过export组合导出
function test(content){
  console. log(content);
}
 
class Person{
  constructor (name, age){
    this.age =age;
  }
  run(){
    console.log(this.name+'在奔跑');
  }
}
export {test,Person}

某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
这个时候就可以使用export default

//info.js
export default function () {
  console.log('default function');
}

我们来到main.js中,这样使用就可以了
这里的myFunc是我自己命名的,你可以根据需要命名它对应的名字

import myFunc from './info.js'
myFunc()

另外,需要注意:
export default在同一个模块中,不允许同时存在多个

需要注意的是如果我们继续按照下面的方式在html中引入各个js文件,由于不同的文件在全局仍可能存在同名变量的情况,所以还是可能会出现命名空间污染

<script src="info.js"></script>
<script src="main.js"></script>

为此,我们需要给导入的各个js文件设置一下type属性为module

<script type="module" src="info.js"></script>
<script type="module" src="main.js"></script>

一旦将type设置成module,表示我们引入的文件都将被看作一个个单独的模块,各个模块有自己的作用域,一个模块无法直接使用另一个模块中的内容

混合导出

可以使用exportexport default同时使用并且互不影响,只需要在导入时地方注意,如果文件里有混合导入,则必须先导入默认导出的,在导入单个导入的值。

export const name = "蛙人"  
export const age = 24  
  
export default {  
    fn() {},  
    msg: "hello 蛙人"  
}

导入import

我们使用export指令导出了模块对外提供的接口,下面我们就可以通过import命令来加载对应的这个模块了

import指令用于导入模块中的内容,比如main.js的代码

import{name,age,height} from "./info.js"
console.log(name,age,height)

如果我们希望某个模块中所有的信息都导入,一个个导入显然有些麻烦:
通过*可以导入模块中所有的export变量,但是通常情况下我们需要给*起一个别名,方便后续的使用

import * as info from './info.js'
console.log(info.name,info.age,info.height.info.friends)

混合导入
混合导入,则该文件内用到混合导入,import语句必须先是默认导出,后面再是单个导出,顺序一定要正确否则报错。

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import msg, { name, age } from './index.js'
console.log(msg) // { msg: "蛙人" }

上面example中,如果导入的名称不想跟原本地名称一样,则可以起别名。

// index,js
export const name = "蛙人"
export const age = 24
export default {
    msg: "蛙人"
}

import { default as all,  name, age } from './index.js'
console.log(all) // { msg: "蛙人" }

导入值的变化
export导出的值是值的引用,并且内部有映射关系,这是export关键字的作用。而且导入的值,不能进行修改也就是只读状态。

// index.js
export let num = 0;
export function add() {
    ++ num
}

import { num, add } from "./index.js"
console.log(num) // 0
add()
console.log(num) // 1
num = 10 // 抛出错误

CommonJs和Es Module的区别

CommonJs

  • CommonJs可以动态加载语句,代码发生在运行时
  • CommonJs混合导出,还是一种语法,只不过不用声明前面对象而已,当我导出引用对象时之前的导出就被覆盖了
  • CommonJs导出值是拷贝,可以修改导出的值,这在代码出错时,不好排查引起变量污染

Es Module

  • Es Module是静态的,不可以动态加载语句,只能声明在该文件的最顶部,代码发生在编译时
  • Es Module混合导出,单个导出,默认导出,完全互不影响
  • Es Module导出是引用值之前都存在映射关系,并且值都是可读的,不能修改
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值