ES6-模块化export/import

记录ES6 的模块化使用以及CommonJS的对比

构建扩展性强、复用性强一直是我编码的追求点。但工作中项目比较传统,感触不深,平时有所接触,学习使用Node时使用过require;使用React使用过import;再系统学习记录为好!

export

模块导出;每个模块指的是一个文件、不管文件中指向的是变量、函数、对象,对外使用export后是一个模块对象。

导出的模块都是严格模式use strict

user.js

// export 
export const name = "admin";
export function getAge(){
	return Math.random()*100;
}

index.js

import {name,getAge}  from "./user";
console.log(name,getAge());

由于浏览器不支持,也不能直接测试,所以使用了es6-module-transpiler转换后执行的测试结果

  1. 安装:注意安装时要全局安装,使得compile-modules命令全局可用。(安装完之后关掉窗口再打开使命令生效)
    npm install -g es6-module-transpiler
    
  2. 执行转化操作,主入口文件时index.js,在创建一个副本index-copy.js用于接收转后的内容。
    compile-modules convert -o index-copy.js index.js
    
  3. 转换后的文件内容、还有个index-copy.js.map文件
    (function() {
    "use strict";
    var $$user$$name = "admin";
    function $$user$$getAge(){
        return Math.random()*100;
    }
    
        console.log($$user$$name,$$user$$getAge());
    }).call(this);
    
    //# sourceMappingURL=index-copy.js.map
    
  4. 执行index-copy.js,得到结果:
    第一组:
    在这里插入图片描述
    第二组:
    在这里插入图片描述

如果这样导入操作:
index.js

import name  from "./user";
console.log(name);

转义时报错:error: compile-modules convert -- import default at index.js:1:8 has no matching export in ./user.js
即:模块的导入时一个整体的模块的对象导入,再引用使用内部的属性、方法等。

模块整体引入

使用*可以整体引入模块,为了方便调用,给定一个别名* as ***
index.js

import * as user  from "./user";

console.log(user.name,user.getAge());

相继的转义后的内容也不一样。
index-copy.js

(function() {
    "use strict";

    var $$user$$ = {
        get name() {
            return $$user$$name;
        },

        get getAge() {
            return $$user$$getAge;
        }
    };

    var $$user$$name = "admin";
    function $$user$$getAge(){
        return Math.random()*100;
    }

    console.log($$user$$.name,$$user$$.getAge());
}).call(this);

//# sourceMappingURL=index-copy.js.map

可以看到一些结构,慢慢理解这种转义工具是怎么工作的。

使用module命令导入整体模块。搞不了,直接报错

export default

上面的例子中不管怎么导入,最后使用都必须知道这个模块中的变量名name、方法名getAge等,就很麻烦。通过export default默认导出给与别名即可,只需要知道怎么用而不用关心它叫什么。

因为是默认导出,所以这个export default命令在模块中只允许使用一次

user.js

export var name = "admin";
export function getAge(){
	return Math.random()*100;
}
var title = "user";
export default title;

当然,写法多种多样,也可以不声明,直接导出export default "user".
index.js

import title,* as user1  from "./user";

console.log(user1.name,user1.getAge(),title);

export default默认导出的是一个值,导入时title指向的就是默认输出。
* as user1则接受的时指定名称的变量、方法。

转义后的结果:

(function() {
    "use strict";

    var $$user$$ = {
        get name() {
            return $$user$$name;
        },

        get getAge() {
            return $$user$$getAge;
        },

        get default() {
            return $$user$$default;
        }
    };

    var $$user$$name = "admin";
    function $$user$$getAge(){
        return Math.random()*100;
    }
    var $$user$$title = "user";
    var $$user$$default = $$user$$title;

    console.log($$user$$.name,$$user$$.getAge(),$$user$$default);
}).call(this);

//# sourceMappingURL=index-copy.js.map

可以看到使用export default命令导出的属性是default

import

前面的导出已经用到导入,用来接收模块中导出的变量、方法。导入的是一个整体
基本的应用在上面的例子中。

import命令会提升到模块的头部执行。

导入执行:

即在其他模块中无引用操作,只做初始化数据时用。
index.js

	import "./user";
	```
	`user.js`
	```js
	export default function(){
		console.log("user model");
	};

按照这样转以后执行是不会有任何输出的,模块导入但是没有调用执行。
user.js 导出的是执行后的结果,内部的代码在其他模块中导入时执行。

	var title = "user";
	export default (function(){
		console.log("user model");
	})();
导入即导出:

将模块汇总到一个文件中在导出,比如通常我们的组件中都会有index.js文件,如果其中不做任何逻辑处理。就只负责汇总。
就像上述例子,就只是初始化执行了一下user.js;那我们要把他执行的结果在导出。
user.js : 加入了一个返回对象,有一个getTitle方法。

var title = "user";
export default (function(){
	console.log("user model");
	return {
		getTitle:()=>{
			console.log(title);
		}
	}
})();

index.js 导入获得返回值对象后在导出。

import user from "./user";
export default user;

app.js 需要第三个组件去导入并调用执行。

import user from "./index";
user.getTitle();

这次转义的是app.jscompile-modules convert -o index-copy.js app.js .
得到执行结果。
在这里插入图片描述
简写index.js ES 7提案,未得到有效测试

export user from "./user";

还有这种写法也不支持epxort * from './user.js';书写不报错,编译时报错不支持。

动态导入

import动态导入,返回的是一个Promise对象。
未测试,暂不支持

import("./user").then((module)=>{
    console.log(module.getAge());
},(err)=>{
    throw err;
}});

// await 写法
let module = await import("./user");
module.getAge();
ES6模块VSCommonJS

NodeJS中使用的就是CommonJS规范。
require() 加载模块。
module.exports导出模块。

加载实质

CommonJS输出的模块是值得拷贝;ES6输出的则是引用,会受原组件内部代码执行影响。
先看CommonJS
user.js 取得是随机数。看导入模块后的打印值变化。

var num = 0;
function getNum(){
	num = Math.random()*100;
	return num;
}
module.exports = {
	num:num,
	change:getNum
}

index.js

let user = require("./user");
console.log(user.num);
console.log(user.change());
console.log(user.num);

当然,执行Node执行需要环境。去官网安装Node

输出结果:
在这里插入图片描述
测试ES6的模块:
user.js

export var num = 0;
export function getNum(){
	num = Math.random()*100;
	return num;
}

index.js

import * as user from "./user";
// let user = require("./user");
console.log(user.num);
console.log(user.getNum());
console.log(user.num);

执行输出结果:
在这里插入图片描述

测试时犯的错误,在导出了个默认对象把num赋给对象中的属性。

export default {
	num:num,
	change:getNum
}

结果当然num还是0。赋值阶段num:num是值传递,所以不会改变。、

模块之间的循环加载

之上,由于CommonJS是值拷贝,不是引用,所以不会导致循环加载而导致卡死状态;也正因为如此,再确认自己导入的模块是已经可以获取到值得,不然值为null,再调用操作就会报错。

ES6是动态引用,它会一直执行。直到有退出条件或者报错退出。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroboyluck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值