import与export在node.js中的使用详解


Posted in Javascript onSeptember 28, 2017

简述

import与export是es6中模块化的导入与导出,node.js现阶段不支持,需要通过babel进行编译,使其变成node.js的模块化代码。(关于node.js模块,可参考其他node.js模块化的文章)

export 曝露

使用export可以曝露出方法、对象、字符串等等,如下代码

//写法1
export var foo=function(){
  console.log(1);
}
//写法2
var bar ={a:"1",b:2};
export {bar};
//写法3
var baz='hello world';
export {baz as qux};

那么,上面的代码经过babel的编译后,变成可以执行的node.js代码,如下

"use strict";
//标记这个模块是es的模块
Object.defineProperty(exports, "__esModule", {
  value: true
});
//写法1
var foo = exports.foo = function foo() {
  console.log(1);
};
//写法2
var bar = { a: "1", b: 2 };
exports.bar = bar;
//写法3

var baz = 'hello world';
exports.qux = baz;

看到上面的代码我们知道了,es6的export会被转成node.js中的exports的曝露方式。

import 导入

再来看下import的写法,我们引入上面写export的文件xx.js

第一种写法

import {foo,qux} from './xx';
console.log(qux);

foo,qux是在xx.js中我们曝露出来的属性,在xx.js中曝露出来的属性有foo、bar、qux3个,由此可知这种写法需要知道引入文件中曝露出来的属性的名称,并且可以按需要写,不需要枚举全部属性。

下面我们来看下babel编译后的代码:

'use strict';
var _ = require('./xx');
console.log(_.qux);

就是一个简单的require方法,引入xx.js,所以用这种方式我们是可以引入es6的模块也可以引入node.js模块的。

第二种写法

import * as xx from './xx';
console.log(xx.bar);

这里还是引入xx.js,这种写法会把xx.js中曝露出来的属性都赋值给xx这个变量(其实就是给module.exports起个别名),被babel编译后如下下:

'use strict';
var _ = require('./xx');
var xx = _interopRequireWildcard(_);
function _interopRequireWildcard(obj) {
  //判断是node模块还是es模块
  if (obj && obj.__esModule) {
    return obj;
  }
  else {
    var newObj = {};
    if (obj != null) {
      for (var key in obj) { 
        if (Object.prototype.hasOwnProperty.call(obj, key)) 
         newObj[key] = obj[key];
      }
    }
  //兼容旧的babel编译
    newObj.default = obj;
    console.log(newObj);
    return newObj;
  }
}
console.log(xx.bar);

看到上面的代码,有一个判断是node模块还是es模块,这种写法也是兼容es模块和node的模块的。

第三种写法

import oo from './xx'
console.log(oo.bar);

在这种写法中oo是随意的变量,乍一看可能会觉的和第二种写法一样,其实不然,来看一下编译后的代码:

'use strict';
var _ = require('./xx');
var _2 = _interopRequireDefault(_);
function _interopRequireDefault(obj) { 
 return obj && obj.__esModule ? obj : 
 { default: obj }; 
}
console.log(_2.default.bar);

在最后一行,oo.bar被编译成了_2.default.bar,多了一个default,这里的bar当然就找不到了,所以这种用法不是用来引入export的属性的,而是下面要说的export default。

export default 曝露且一次性曝露

export与export default我会在别的文章总结,这里我们只说export default的用法,下面来看代码。

var foo=123;
export default foo;

被babel编译后

"use strict";
Object.defineProperty(exports, "__esModule", {
 value: true
});
var foo = 123;
exports.default = foo;

看到最后一行foo会被赋给exports.default,这样正好对应上了import oo from './xx'这种写法里面会调用default里面的属性,所以这两种用法对应使用。既然属性的值是会赋给exports.default,那么就可以有下面的用法

export default 123;

export default {foo:123};
export default function f(){}
export default function (){}

上面的代码是分开写的,因为一个js里面只能使用一次export default,理由和使用module.exports一样,除了不能写多个,下面也是错误的写法:

export default var foo=123; //错误

export default还可以用来曝露class这里不多说了,都是曝露。

其他的一些用法

继承

这里说是模块继承,其实就是一个父模块引入子模块,然后又将子模块曝露出来的属性曝露出去:

export * from './xx';

被编译后

'use strict';
Object.defineProperty(exports, "__esModule", {
 value: true
});
var _ = require('./xx');
Object.keys(_).forEach(function (key) {
 if (key === "default" || key === "__esModule") return;
 Object.defineProperty(exports, key, {
  enumerable: true,
  get: function get() {
   return _[key];
  }
 });
});

注意下面这句

if (key === "default" || key === "__esModule") return;

default属性不向外曝露...这说明,我们的引入的xx.js这个文件里面用exports default是无效的,替代写法是

export {default} from './xx';

继承的写法常用于组织多个模块,经常与下面要说的引包一起用

引文件夹(引包)

很多人不理解下面这行代码

import * as o from './oo'; //oo是个文件

为什么import可以引入文件夹,注意不是什么文件夹都可以,里面至少有一个文件就是index.js或者有package.json和另外名字的js,因为文件夹里面有index.js那么这就不是一个文件夹而是node.js的包了(更多参见node.js包的文章),import会被babel编译成require,require可以去引用指定路径的包,因此,import可以去导入一个文件夹,我们可以依赖index.js将文件夹中的其他文件代码导出,例如:

import与export在node.js中的使用详解

//index.js
export * from './1';
export * from './2';

我们可以通过import oo这个文件夹得到1.js、2.js里面曝露出的属性。

总结

从看babel编译后的代码,可以看出export与exports,module.exports与export default的用法的相似,至于用什么怎么用还是看个人喜好吧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
新发现一个骗链接的方法(js读取cookies)
Jan 11 Javascript
jQuery 联动日历实现代码
May 31 Javascript
Jquery多选下拉列表插件jquery multiselect功能介绍及使用
May 24 Javascript
JS实现QQ图片一闪一闪的效果小例子
Jul 31 Javascript
javascript中全局对象的isNaN()方法使用介绍
Dec 19 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
Apr 16 Javascript
JS实现浏览器状态栏文字从右向左弹出效果代码
Oct 27 Javascript
基于JS模仿windows文件按名称排序效果
Jun 29 Javascript
使用jquery/js获取iframe父子级、同级获取元素的方法
Aug 05 Javascript
javascript简单进制转换实现方法
Nov 24 Javascript
通过实例解析vuejs如何实现调试代码
Jul 16 Javascript
解决vue单页面 回退页面 keeplive 缓存问题
Jul 22 Javascript
AngularJS 仿微信图片手势缩放的实例
Sep 28 #Javascript
AngularJS路由删除#符号解决的办法
Sep 28 #Javascript
深入理解React高阶组件
Sep 28 #Javascript
基于webpack 实用配置方法总结
Sep 28 #Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
Sep 28 #Javascript
JQuery 选择器、DOM节点操作练习实例
Sep 28 #jQuery
浅谈JavaScript find 方法不支持IE的问题
Sep 28 #Javascript
You might like
ucenter通信原理分析
2015/01/09 PHP
解决ThinkPHP关闭调试模式时报错的问题汇总
2015/04/22 PHP
php数组随机排序实现方法
2015/06/13 PHP
原生JS实现Ajax通过GET方式与PHP进行交互操作示例
2018/05/12 PHP
php微信开发之图片回复功能
2018/06/14 PHP
Laravel框架源码解析之反射的使用详解
2020/05/14 PHP
[推荐]javascript 面向对象技术基础教程
2009/03/03 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
如何解决easyui自定义标签 datagrid edit combobox 手动输入保存不上
2015/12/26 Javascript
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
jQuery图片拖动组件Dropzone用法示例
2017/01/17 Javascript
js实现消息滚动效果
2017/01/18 Javascript
JavaScript之DOM_动力节点Java学院整理
2017/07/03 Javascript
详解tween.js 中文使用指南
2018/01/05 Javascript
vue组件中的数据传递方法
2018/05/14 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
2018/09/04 jQuery
express + jwt + postMan验证实现持久化登录
2019/06/05 Javascript
原生javascript的ajax请求及后台PHP响应操作示例
2020/02/24 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
2020/04/15 Javascript
深入讲解Python函数中参数的使用及默认参数的陷阱
2016/03/13 Python
python实现多线程网页下载器
2018/04/15 Python
python实现本地批量ping多个IP的方法示例
2019/08/07 Python
基于python实现MQTT发布订阅过程原理解析
2020/07/27 Python
纯css3实现效果超级炫的checkbox复选框和radio单选框
2014/09/01 HTML / CSS
Get The Label中文官网:英国运动时尚购物平台
2017/04/19 全球购物
Myholidays美国:在线旅游网站
2019/08/16 全球购物
第一范式(1NF)、第二范式(2NF)和第三范式(3NF)之间的区别是什么?
2016/04/28 面试题
西安启天科技有限公司网络工程师面试题笔试题
2016/06/12 面试题
Prototype是怎么扩展DOM的
2014/10/01 面试题
个人租房协议书
2014/04/09 职场文书
横幅标语大全
2014/06/17 职场文书
白银帝国观后感
2015/06/17 职场文书
python基础之while循环语句的使用
2021/04/20 Python
win10如何快速切换窗口 win10切换窗口快捷键分享
2022/07/23 数码科技