最近总碰到类似于

var a = require('./expample.js).default

这样的代码,感觉很奇葩,总结一波。

为什么会出现这个问题?

import 是静态编译的,而 require 可以动态加载,也就是说你可以通过判断条件来决定什么时候去 require ,而 import 则不行,所以有时候我们会面临需要通过require 去导入一个es6模块(比如react-hot-loader官方demo :P)

当然,这只是场景之一。

前置知识

  1. ES6 Module常用语法。譬如export导出模块接口 | import 倒入模块| export default语法糖
  2. Node.js模块常用。譬如module.exports | require
  3. ES6模块与commonjs模块的区别(静态编译与动态加载 | 值得引用与值的拷贝)

如果上述前置知识您有所不了解的话,建议拜读一下阮一峰老师的《ECMAScript 6 入门》一书中的两个章节:

  1. Module 的语法
  2. Module 的加载实现

如果您已经具备了上述知识,我们来讨论一下

  1. export default为什么是语法糖
  2. require一个ES6 Module

export default为什么是语法糖

default关键字 说白了,就是别名(as)的语法糖

以下代码应当是非常常见的:

导出接口

// a.js
function a(){}
export {a}

导入模块

// b.js
import {a} from './a'

花括号就是解构赋值的语法,我们可以理解为export导出了一个对象,对象里存在a这个函数,就像下面这样

{
a:function(){}
}

于是就有了后面的通过结构赋值取出a,所以变量名必须一致。

ECMAScript 6 入门:从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。
为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

default可以理解为这一语法的语法糖

导出接口

// d.js
export default function() {} // 等效于:
function a() {};
export {a as default};

导入模块

import a from './d';

// 等效于,或者说就是下面这种写法的简写,是同一个意思
import {default as a} from './d';

这个语法糖的好处就是import的时候,可以省去花括号{}。

简单的说,如果import的时候,你发现某个变量没有花括号括起来(没有*号),那么你在脑海中应该把它还原成有花括号的as语法。

本质上依旧是结构赋值呀,只不过我们写的更为简便,假装花括号消失了罢了。

如何require一个ES6 Module

stackoverflow上有一个针对本文题目比较好的回答,原文如下:

Finally, the require and require.default... when dealing with ES6 imports (export default MyComponent), the exported module is of the format {"default" : MyComponent}. The import statement correctly handles this assignment for you, however, you have to do the require("./mycomponent").default conversion yourself. The HMR interface code cannot use import as it doesn't work inline. If you want to avoid that, use module.exports instead of export default.

我来翻译下原文

最后,require和require.default...当在node中处理ES6 模块(export default mycomponent)导入的时候,导出的模块格式为

{
"default": mycomponent
}

import
语句正确地为你处理了这个问题,然而你必须自己执行 require("./mycomponent").default. HMR(热更新模块)不在 inline 模式工作的情况下,接口代码不能使用 import ,如果你想避免,使用module.exports而不是export default;

上文提到过,export 关键字是导出一个对象,对象内存在一个属性(我们要暴露的),export default 则是 export 语法糖,import 一个export default 暴露出来的模块包含了解构赋值的步骤,所以在node中使用require去请求一个export default的模块需要我们通过.语法去取出对象中的属性(因为require木有解构赋值),清晰明了。

换个说法,如果 require 的 commonjs规范的模块,即:
导出:

// a.js
module.exports = {
a:'helloworld'
}

导入:

// b.js
var m = require('./a.js');
console.log(m.a); // helloworld

这样就显得非常清晰,我们 module.exports 的是啥,require 的就是啥。

但export default包装了一层语法糖,让我们看得不甚清晰:

const a = 'helloworld';
export default a;

其实导出的是

{
"default": a
}

而并非 a 这个变量,这就是我为什么之前要强调语法糖了,如果你将 export default 还原为:

const a = 'helloworld';
export {a as default}

是不是就能清楚一点了呢。

我们的疑问也就迎刃而解了。

注:以上所有代码都是在webpack开发环境(babel)中运行(保证ES6模块语法可以被识别)。

参考:Node中没搞明白require和import,你会被坑的很惨

require('./expample.js).default详解的更多相关文章

  1. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...

  2. OpenWrt之feeds.conf.default详解

    目录 OpenWrt之feeds.conf.default详解 文件内容 命令解释 src-svn与src-gitsvn src-git与src-git-full src-cpy与src-link 其 ...

  3. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

  4. dva.js 用法详解:列表展示

    本教程案例github:https://github.com/axel10/dva_demo-Counter-and-list/tree/master 这次主要通过在线获取用户数据并且渲染成列表这个案 ...

  5. Vue.js项目详解

    还是以Blog项目来讲解,最近我本人利用闲暇时间,以博客作为参考学习一些新的技术并尝试之前没有尝试过的思路来玩玩. 技术看似枯燥,但是带有一个目的来学,你会发现还是蛮有趣的. 主要实践的就是前后端分离 ...

  6. JS 面向对象详解

    面向对象详解1 OO1.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  7. 开胃小菜——impress.js代码详解

    README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看i ...

  8. jquery图片切换插件jquery.cycle.js参数详解

    转自:国人的力量 blog.163.com/xz551@126/blog/static/821257972012101541835491/ 自从使用了jquery.cycle.js,我觉得再也不用自己 ...

  9. 值得收藏的js原型详解

    从虚无到Object 起初,地是空虚混沌,渊面黑暗:这时候一切还是null 神说,要有原型,于是就有了prototype 原型从凭空产生,于是需要一个指向于null的特征,人们把这种特征叫做隐式原型, ...

随机推荐

  1. java----字符串的大写字母右移

    import java.util.Scanner; /** * Created by Admin on 2017/3/27. */ public class test02 { public stati ...

  2. [20170604]12c Top Frequency histogram补充.txt

    [20170604]12c Top Frequency histogram补充.txt 1.环境:SCOTT@test01p> @ ver1PORT_STRING                 ...

  3. eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二)

    eclipse使用CXF3.1.*创建webservice服务端客户端以及客户端手机APP(二) 接上篇博客,本篇博客主要包含两个内容: 4.使用Android studio创建webservice客 ...

  4. Ubuntu 普通用户无法启动Google chrome

    删除 /home/你的用户名/.config/google-chrome文件,再打开就好了 root@ecos:cd /home/ecos/.config root@ecos:~/.config# r ...

  5. 深入理解Zuul之源码解析

    转载:http://blog.csdn.net/forezp/article/details/76211680 Zuul 架构图 在zuul中, 整个请求的过程是这样的,首先将请求给zuulservl ...

  6. centos7下安装docker(26如何配置Health Check)

    Docker只能从容器启动进程的返回代码判断其状态,而对于容器内部应用的运行状况基本没有了解 执行docker run命令时,通常根据dockerfile中的CMD或ENTRYPOINT启动一个进程, ...

  7. centos7下安装docker(17.2docker监控---weave scope)

    weave scope的最大的特点是会自动生成一张docker 容器地图,让我们能够直观的理解,监控和控制地图 先来感受一下(盗图) 1.安装 执行如下脚本安装运行weave scope  curl ...

  8. 转://linux下hugepages理解

    就Linux应用程序而言,使用的都是虚拟地址,当应用程序读写一个指定的虚拟地址时,内存管理单元会自动进行虚拟地址到物理地址的转换.一个虚拟地址可以映射到多个物理地址,但当前映射到哪一个物理地址取决于当 ...

  9. (二 -3-3) 天猫精灵接入Home Assistant-自动发现Mqtt设备-自动生成配置信息

    http://www.hassmart.com/products/switches/#tab=config switch: - platform: mqtt name: keting state_to ...

  10. 解决Nginx+Tomcat下客户端https请求跳转成http的问题

    Nginx上开启https,  后端使用Tomcat,  两者间走http协议, 但发现如果tomcat应用存在跳转时, 则客户端浏览器会出现400 Bad Request的错误, 通过抓包发现原因是 ...