最近总碰到类似于

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. perfect-scrollbar在vue中的使用

    1.下载perfect-scrollbar依赖包 npm install perfect-scrollbar 2.perfect-scrollbar特性 1)直接下载依赖包及包含css样式和js 2) ...

  2. SQL Server Browser探究

    一.官网关于SQL SERVER Browser服务的解释(谷歌翻译后稍作修改的): https://docs.microsoft.com/en-us/sql/tools/configuration- ...

  3. Linux用户抢占和内核抢占详解(概念, 实现和触发时机)--Linux进程的管理与调度(二十)

    1 非抢占式和可抢占式内核 为了简化问题,我使用嵌入式实时系统uC/OS作为例子 首先要指出的是,uC/OS只有内核态,没有用户态,这和Linux不一样 多任务系统中, 内核负责管理各个任务, 或者说 ...

  4. python中根据字符串导入模块module

    python中根据字符串导入模块module 需要导入importlib,使用其中的import_module方法 import importlib modname = 'datetime' date ...

  5. 第十四届智能车队员培训 I/O的使用 数据方向寄存器和数据寄存器的配置 MC9S12D64处理器

    I/O的使用 数据方向寄存器和数据寄存器的配置 I/O输入输出的使用: 数据方向寄存器与数据寄存器 寄存器的概念: 寄存器,是集成电路中非常重要的一种存储单元,通常由触发器组成.在集成电路设计中,寄存 ...

  6. mysql文件

    MySQL的每个数据库都对应存放在一个与数据库同名的文件夹中,MySQL数据库文件包括MySQL(server)所建数据库文件和MySQL(server)所用存储引擎创建的数据库文件. .frm文件: ...

  7. LeetCode算法题-Excel Sheet Column Title(Java实现)

    这是悦乐书的第180次更新,第182篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第39题(顺位题号是168).给定正整数,返回Excel工作表中显示的相应列标题.例如: ...

  8. Win10 开始运行不保存历史记录原因和解决方法

    Win10 开始运行命令以后,再次打开就没有任何历史记录了,常规方法是桌面-右键-个性化-开始-显示最常用的应用..可是打开是灰色的不可选. 每次打开开始都没有以前的记录..比如需要打开下regedi ...

  9. aliyun mysql

    https://segmentfault.com/q/1010000009603559?sort=created

  10. Custom partition assignment and migration kafka集群扩充迁移指定partition

    The partition reassignment tool can also be used to selectively move replicas of a partition to a sp ...