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 相关文章推荐
JavaScript 继承详解(四)
Jul 13 Javascript
jquery的Theme和Theme Switcher使用小结
Sep 08 Javascript
解析Javascript中大括号“{}”的多义性
Dec 02 Javascript
纯JS实现根据CSS的class选择DOM
Mar 22 Javascript
jquery分析文本里url或邮件地址为真实链接的方法
Jun 20 Javascript
JS+CSS实现仿雅虎另类滑动门切换效果
Oct 13 Javascript
基于jQuery1.9版本如何判断浏览器版本类型
Jan 12 Javascript
JS简单实现浮动窗口效果示例
Sep 07 Javascript
bootstrap手风琴折叠示例代码分享
May 22 Javascript
关于javascript sort()排序你可能忽略的一点理解
Jul 18 Javascript
JS实现读取xml内容并输出到div中的方法示例
Apr 19 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
Apr 21 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
php全局变量和类配合使用深刻理解
2013/06/05 PHP
php include和require的区别深入解析
2013/06/17 PHP
php判断是否为ajax请求的方法
2016/11/29 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
ext jquery 简单比较
2010/04/07 Javascript
js 浏览器事件介绍
2012/03/30 Javascript
jquery 操作DOM案例代码分享
2012/04/05 Javascript
jQuery.extend()的实现方式详解及实例
2013/06/29 Javascript
js一般方法改写成面向对象方法的无限级折叠菜单示例代码
2013/07/04 Javascript
Java框架SSH结合Easyui控件实现省市县三级联动示例解析
2016/06/12 Javascript
jQuery插件扩展extend的简单实现原理
2016/06/24 Javascript
jQuery绑定自定义事件的魔法升级版
2016/06/30 Javascript
vue.js入门教程之计算属性
2016/09/01 Javascript
微信小程序中单位rpx和rem的使用
2016/12/06 Javascript
Vue 创建组件的两种方法小结(必看)
2018/02/23 Javascript
JavaScript实现的文本框placeholder提示文字功能示例
2018/07/25 Javascript
Angular4 Select选择改变事件的方法
2018/10/09 Javascript
react脚手架如何配置less和ant按需加载的方法步骤
2018/11/28 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
bootstrap datepicker的基本使用教程
2019/07/09 Javascript
使用React-Router实现前端路由鉴权的示例代码
2020/07/26 Javascript
[31:29]完美世界DOTA2联赛PWL S3 INK ICE vs Magma 第一场 12.20
2020/12/23 DOTA
简单的通用表达式求10乘阶示例
2014/03/03 Python
老生常谈Python startswith()函数与endswith函数
2017/09/08 Python
使用pandas对矢量化数据进行替换处理的方法
2018/04/11 Python
Python子类继承父类构造函数详解
2019/02/19 Python
详解python实现交叉验证法与留出法
2019/07/11 Python
python中的TCP(传输控制协议)用法实例分析
2019/11/15 Python
解决Python 函数声明先后顺序出现的问题
2020/09/02 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
单身旅行者的单身假期:Just You
2018/04/08 全球购物
LORAC官网:美国彩妆品牌
2019/08/27 全球购物
结构工程研究生求职信
2013/10/13 职场文书
最新大学毕业求职简历的自我评价
2013/10/18 职场文书
2014年客服工作总结与计划
2014/12/09 职场文书